vue中的组件知识!!!

组件是什么?有什么作用?

这几天一直在看《vue.js实战》这本书,一直卡在组件这一章节,的确像作者说的那样,组件是vue.js的核心知识,同时也是最难的地方,从书中暂时只是了解到组件可以实现模板的复用,但是具体的用处还不是很理解。

今天终于看懂了一些知识,先记下来!!!

在vue中声明的组件,需要注册才能被使用,在vue中组件有两种注册方式,分为全局注册和局部注册。

那么,全局注册和局部注册有什么区别呢?

在全局注册的组件可以被所有的实例访问,但是局部注册的组件只能被在注册的实例中使用,所以作用域不同!

如何来实现全局注册和局部注册?

假设已有:

<div id="app">
    <my-component></my-component>
</div>

(1)全局注册:

Vue.component('my-component',{
    template:'<div>这是my-component组件</div>'
    });
var app=new Vue({
    el:'#app'
})

全局注册通过Vue.component()来实现

(2)局部注册:

var app=new Vue({
    el:'#app',
    components:{
        'my-component':{
            template:'<div>这是通过局部注册的组件</div>'
        }
    }
})

上面也可改成下列的写法:

myComponent={
    template:'<div>这是局部注册组件的另一种写法</div>'
}
var app=new Vue({
    el:'#app',
    components:{
        'my-component':myComponent
    }
})

注意局部注册的组件中是components,需要加上"s"

以上两种注册方式都会被vue渲染成下列的形式:

<div id="app">
    <div>...(组件中的内容)</div>
</div>

注意在模板中,如果不止有一个标签,那么外部需要通过一个<div></div>标签将其包裹起来!

如:

 //组件的全局声明
    Vue.component('my-component',{
        template:'<div><div>{{count}}</div><button @click="up">点击加1</button></div>',
        data:function(){
            return {
                count:0
            }
        },
        methods:{
            up:function(){
                this.count++;
            }
        }
    });

这种会被渲染为:

<div id="app">
    <div>
        <div></div>
        <button></button>
    </div>
</div>

如果写成下列的形式,则不会被渲染:

 //组件的全局声明
    Vue.component('my-component',{
        template:'<div>{{count}}</div><button @click="up">点击加1</button>',
        data:function(){
            return {
                count:0
            }
        },
        methods:{
            up:function(){
                this.count++;
            }
        }
    });

那么如何理解全局注册和局部注册的区别呢?下面来讲一下我的理解,先贴出代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <my-component></my-component>
</div>
<div id="app2">
    <my-component></my-component>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    Vue.component('my-component',{
        template:'<div>这是通过全局注册的组件</div>'
    })
    var app=new Vue({
        el:'#app'
    });
    var app=new Vue({
        el:'#app2'
    })
</script>
</body>
</html>

上面的代码中,通过全局注册的组件,在app和app2都可以使用,这里只是通过全局注册了一次!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <my-component></my-component>
</div>
<div id="app2">
    <my-component></my-component>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>

    var myComponent={
        template:'<div>这是通过局部注册的组件</div>'
    };
    var app=new Vue({
        el:'#app',
        components:{
            'my-component':myComponent
        }
    });
    var app2=new Vue({
        el:'#app2',
        components:{
            'my-component':myComponent
        }
    })
</script>
</body>
</html>

以上的局部注册中可以看出,要在app和app2中使用组件,需要通过components分别在各自的实例中进行声明!每使用一次需要声明一次!

其实到最后才开始发现在组件里的写法和vue实例的写法有些相似,在书本中作者也提到了,但是却没有一开始就发现,这个就是看书的时候不用心吧,怪不得要多读几遍才能知道!!!

所以之后可以通过对比来理解组件的知识

在这里还需要注意的是:

在组件中声明的data需要通过函数来实现,如下:

 //组件的全局声明
    Vue.component('my-component',{
        template:'<div><div>{{count}}</div><button @click="up">点击加1</button></div>',
        data:function(){
            return {
                count:0
            }
        },
        methods:{
            up:function(){
                this.count++;
            }
        }
    });

这里再加点关于父子组件通信的一些知识,关于组件通信,这部分估计还需要再写一篇博文,因为通信部分有点复杂

刚刚还在想能不能通过vue实例中的data属性来给组件中模板的{{msg}}来赋值,结果不行,但是还未弄懂是什么原因,现在好像有点眉目了,实例可以看作是里面组件的父组件,data选项不能直接操作组件的数据,只能通过props来传递,而组件中的data选项可以直接操作自己数据(可能自己的理解不是很对,如果错了,希望大家能指正以下)

下面开始举例来讲解:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <my-component></my-component>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
    var app=new Vue({
        el:'#app',
        components:{
            'my-component':{
                template:'<div>{{message}}</div>',
                data:function(){
                    return {
                        message:'这是来自组件中的数据'
                    }
                }
            }
        }
    })
</script>
</body>
</html>

这里组件可以通过自己的data选项传输数据

如果直接通过实例传递,则会出现以下情况,这里不知道有没有直接联系(如果大家知道也麻烦告知一下)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <my-component></my-component>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
    var app=new Vue({
        el:'#app',
        components:{
            'my-component':{
                template:'<div>{{message}}</div>'
            }
        },
        data:{
            message:'这是来自实例的数据'
        }
    })
</script>
</body>
</html>

那么如果要将这个msg从实例中传递过来要如何做呢?就要通过props来实现了,如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <my-component :message="msg"></my-component>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
    var app=new Vue({
        el:'#app',
        components: {
            'my-component': {
                template: '<div>{{message}}</div>',
                props: ['message']
            }
        },
        data:{
            msg:'这是来自实例的数据'
        }
    })
</script>
</body>
</html>

这里是通过动态渲染数据,通过v-bind来动态绑定props的值,可以实时根据父级的数据动态渲染。

如果只是静态渲染父级的数据的话,就可以借鉴下面的写法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <my-component warning-text="提示信息"></my-component>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
    var app=new Vue({
        el:"#app",
        components:{
            'my-component':{
                template:'<div>{{warningText}}</div>',
                props:['warningText']
            }
        }
    });
</script>
</body>
</html>

这里需要注意的是:在html中,不区分大小写,如果在props中采用驼峰命名法,则在组件中需要使用"-"来相应改变。

这里还需要注意的是:如果要直接传递数字、布尔值、数组、对象,如果不使用v-bind,传递的仅是字符串,这里举书中例子:

<div id="app">
    <my-component message="[1,2,3]"></my-component>
    <my-component :message="[1,2,3]"></my-component>
</div>

<script>
    Vue.component('my-component',{
    template:'<div>{{message.length}}</div>',
    props:['message']
    });
    var app=new Vue({
        el:'#app'
    })
</script>

第一个没有使用v-bind,所以渲染后是7(字符串的长度),第二个由于使用了v-bind,所以渲染后是3(数组的长度)

这里再加一点props的知识,props有两种值,一种是字符串数组,一种是对象,可以通过书中的数据验正例子来了解下:

对于书中数据验证的使用我还不是很清楚,这里改天遇到了再来补充!

  Vue.component('my-component',{
        props:{
            //必须是数字类型
            propA:Number,
            //必须是字符串或数字类型
            propB:[String,Number],
            //布尔值,如果没有定义,默认值是true
            propC:{
                type:Boolean,
                default:true
            },
            //数字,且必传
            propD:{
                type:Number,
                required:true
            },
            //如果是数组,默认值必须返回一个函数
            propE:{
                type:Array,
                default:function(){
                    return [];
                }
            },
            //自定义一个验证函数
            propF:{
                validator:function(value){
                    return value>10;
                }
            }
        }
    })

书中作者提到当自己的组件需要提供给别人使用的时候,推荐进行数据验证。

验证的类型有:String、Number、Boolean、Object、Array、Function或者自定义构造器

注意:通过props传递的数据是单向的,即父组件数据变化时会传递给子组件,但是反过来不行,但是在业务中会需要改变props的情况,作者举了两个常见的情况:

1)父组件传递初始值进来后,子组件将其作为初始值保存,然后在自己的作用域下随意使用和修改

2)props作为需要被转变的原始值传入

这里就不再写作者的例子了,等自己做项目遇到再另写一篇。

为什么子组件修改数据会改变父组件呢?这个是因为props是数组或对象,这两种在js中是引用类型,这里如果不知道引用类型是什么或者其特点,就自行百度吧,暂时写到这里了~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值