cpn就是component的缩写
注意``是ES6中的语法,类似于引号’和双引号",但功能更强大,换行时可以不用使用+连接。
//注册局部组件 const app = new Vue({ el: "#app", data: {}, components: { 'my-cpn': myComponent, } }); //注册父子组件 const childCpn= Vue.extend({ template:` <div> i am child. </div> ` }); const parentCpn = Vue.extend({ template:` <div> i am parent. <child-cpn></child-cpn> </div> `, components:{ 'child-cpn':childCpn, } });注册组件的语法糖:就是把Vue.extend()方法所需的对象参数直接替换到原来的组件构造器对象cpn处。就省略了Vue.extend()。但实际上源码中还是调用的Vue.extend()。
//提取template模板 //第一种方法 <script type="text/x-template" id="cpn"> some html contents. </script> <script> Vue.component({ 'my-cpn': '#cpn', }) </script> //第二种写法 <template id="cpn2"> some html contents. </template> <script> Vue.component({ 'my-cpn2': '#cpn2', }) </script>Vue实例可以看成是根组件,root组件。
注册组件写法的演变过程
1.最原始的3步注册组件。 2.省略Vue.extend()。 3.提取template模板。
组件的data必须是函数。 原因:因为函数每次返回的data数据是新对象,组件多次复用时,相互之间数据是没有影响的。
子组件不能直接访问父组件或者Vue实例中的数据。这就涉及到了数据的传递。 父子组件的通信方式:(注意驼峰命名) 1.通过props从父组件向子组件传递数据 ①方式一:字符串数组,数组中的字符串就是传递时的名称。 ②方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。 注意: props传递时的驼峰命名以前的版本不支持,要根据驼峰用-分割,比如myFirstChildMessage要写成my-first-child-message。据说是因为html对大小写不敏感。在高版本中,该问题可能已经解决。 <div id="app"> <cpn :my-first-child-message="message"></cpn> </div> 问题报错:vue Expected Boolean, got String with value “false” 解决:这种情况是有一些属性的值应该填写Boolean类型,但是当前的值可能是“”字符串。这种情况只需要在属性前面加上:即可。 2.通过事件从子组件向父组件发送消息 在子组件中发射自定义事件‘item-click’ this.$emit('item-click',要传递的对象) 在父组件处接受自定义事件‘item-click‘,此处的cpnClick不加()默认会传递子组件传递过来的对象。因为是自定义事件,不会像click事件那样有浏览器的$event对象。 <div id="app"> <cpn @item-click="cpnClick"></cpn> </div> 3.兄弟组件间通信 兄弟组件之间的通讯是通过父组件作为中间媒介来进行通讯的。
组件的template模板下有很多标签时,要用<div></div>标签包起来。
watch()
this.$children //获取的为全部的子组件,数组类型 this.$refs //获取的为所有包含ref属性的子组件,对象类型 this.$parent //上一级组件,对象类型 this.$root //根组件,对象类型 slot插槽:组件的插槽是为了让封装的组件功能更强大,更加具有扩展性。可以分为匿名插槽,具名插槽,作用域插槽。 <slot></slot>可以有默认值 <slot name=""></slot>具名插槽,可以替换指定插槽 作用域插槽(编译作用域的问题,在#app的div的Vue实例中无法直接使用子组件中的数据xxx) <div id="app"> <cpn> <!-- 目的是获取子组件中的数据属性,此处不要求必须是template标签,也可以是其他包裹标签。 --> <template slot-scope="slot"> <span>{{slot.xxx.join("-")}}</span> </template> </cpn> </div> <template id="cpn"> <div> <!-- xxx名字可以随意起 --> <slot :xxx="pLanguage"> <ul> <li v-for="item in pLanguage">{{item}}</li> </ul> </slot> </div> </template> v-slot的出现是为了代替原有的slot和slot-scope,简化了一些复杂的语法,可以缩写为# 一句话概括就是v-slot :后边是插槽名称,=后边是组件内部绑定作用域值的映射。 <meta name="viewport" content="width=device-width, initial-scale=1.0">