Vue—04—组件化;
一、组件化
1、介绍
2、注册组件的三个步骤
3、全局组件和局部组件
全局组件使用vue类的component方法创建;这个时候这个组件将可以在所有的vue实例下使用;
局部组件在创建某个vue实例的时候添加component属性创建,那么这个组件就只能在这个vue实例下使用;
4、父组件和子组件
说白了就是搞两个组件构造器,在某个组件构造器a里注册另外一个组件b,另外一个组件b就变成了a的子组件,然后就可以在a组件构造器中的template属性中使用了;当然b既是子组件又是局部组件;
new Vue也是一种组件,可以看作是组件树的root组件;
局部组件一定是子组件,反之不一定;
5、注册组件的语法糖形式
注册全局组件:
注册局部组件:
6、模板抽离
主要是通过type为text/x-template的script标签或者使用《template》标签来定义内容;
二、组件的data属性为什么是函数而不是对象
每一个组件实例都要有自己的状态;
所以组件里的data属性应该是函数,而不能是对象;
如果是函数,每一个组件在注册的时候,都会有一个单独的data初始状态(单独地址),不会受其他组件影响;
如果是对象,则可能大家的data的地址都是指向同一个,这个时候就会收到其他组建的影响;
三、父组件通信到子组件
1、介绍
- 你在div里用我的cpn子组件的时候,可以通过v-bind来绑定并向子组件的props属性的值传递数据;传递过去后,子组件的template属性的内容就可以使用了本组件的props的数据了,也就使用了父组件的数据;
- 子组件都有模板template属性,其实root组件也有,只不过root组件的模板在实例外面(子组件模板和父组件模板);既然外部的div标签也是root组件的一部分,那么在div标签中使用子组件是可以通过v-bind的方式向子组件传值的;
- 子组件props可以使用对象或者数组两种方式,如果使用对象,可以验证传过来的值的数据类型还可以要求是否这个属性必穿等功能,建议使用这种方式而不是数组;
2、实操
<body> <div id=app> <ccpn c-msg='aaabbcc' :c-msg-array='msgArray'></ccpn> //父组件通信到子组件,如果用到了父组件的数据比如msgArray那就要用v-bind也就是:,
如果没有用到那不需要冒号直接传也是可以的,但是都是字符串,如果你想传数字“3”那还是会被当做字符串传过去,这个时候就想传数字3,那还是要用v-bind </div> <template id=ccpn> <div> <h2>自己的数据:{{myMessage}}</h2> <h5>父组件的数据:{{cMsg}}</h5> <ul v-for='item in cMsgArray'> <li>父组件数组的数据:{{item}}</li> </ul> </div> </template> <script src=..\node_modules\vue\dist\vue.js></script> <script> const app = new Vue({ el:'#app', data:{ msg:'you are so niubai', msgArray:['haiwang','haierxiongdi'], }, components:{ 'ccpn':{ template:'#ccpn', props:{ cMsg:{ type:String, Requied:true, default(){ return ''; } }, cMsgArray:{ type:Array, requied:true, default: function(){ return []; }, } }, data(){ return { myMessage:'这个是子组件的值', } } } } }) </script>
3、驼峰标识
注意在父组件《div》标签中使用子组件标签《ccpn》时,,如果想 传值到子组件,在使用
<ccpn :c-msg='msg' :c-msg-array='msgArray'></ccpn>
时我们可以看到,cMsg驼峰标识不起作用,要使用c-msg,目前的vue版本确实这样,后期的vue版本不知道会不会支持;
四、子组件通信到父组件
<body> <!-- 父组件模板 --> <div id=app> <ccpn v-on:clickevent="resolve($event)"></ccpn> </div> <!-- 子组件模板 --> <template id=ccpn> <div> <h2>自己的数据:{{myMessage}}</h2> <h5>父组件的数据:{{cMsg}}</h5> <ul v-for='item in cMsgArray'> <button @click='sendToParent(item)'>{{item}}</button> </ul> </div> </template> <script src=..\node_modules\vue\dist\vue.js></script> <script> //父组件(root组件)实例 const app = new Vue({ el:'#app', methods:{ resolve(event){ console.log(event); console.log(`我收到了子组件的消息,内容是${event}`); } }, components:{ ccpn, }, }) //子组件实例 const ccpn = { template:'#ccpn', props:{ cMsg:{ type:String, Requied:true, default(){ return ''; } }, cMsgArray:{ type:Array, requied:true, default: function(){ return ['科技数码','美食饮料']; }, } }, data(){ return { myMessage:'这个是子组件的值', } }, methods:{ sendToParent(item){ console.log(item); this.$emit('clickevent',item); }, } } </script>
注意,父组件模板的resolve方法中会有一个默认监听事件参数——$event对象,这个event对象在子父组件通信时就是子组件实例sendToParent方法传的item值;
五、父子组件的访问
父子组件除了可以通信即发送数据外,还可以访问他们的属性;
1、父组件访问子组件
有两种方式,分别是this.$children或者this.$refs;
this.$children会放回一个数组,所以取某个子组件元素时需要用到下标比较麻烦,除非要取出所有的子组件元素,不然建议用第二个this.$refs,这个会在父组件模板中的每个<cpn>标签中加一个ref属性,比如
<cpn ref='aaa'></cpn>
这样的话就可以在父组件实例中,使用this.$refs.关键名取调用这个专门的子组件;
2、子组件访问父组件
开发时不建议使用$parent,为什么呢?因为子组件最重要的是可高复用,如果你在这个子组件中使用$parent访问某个父组件成功了,可是你这个子组件在下一个项目复用的时候,可能没有父组件了,这个时候代码中还有$parent就会报错;这样的话子组件和父组件的耦合度就太高了;
3、子组件访问root组件
使用$root访问,但是用的都很少;