<>Vue父子组件通信
*
父子组件通信和双向绑定
—如果使用v-model进行双向绑定时,当绑定在组件的props
中的数据时,虽然可以完成双向绑定,但会出现警告;因此我们在进行组件双向绑定时,不能直接绑定给子组件,一般是在绑定给组件中data函数中返回的数据;
<div id = "cpn"> <!--这里可以写成自结束标签,因为标签内部没东西,所以可以简写--> <cpn :number1 = "num1"
:number2 = "num2" @num1change = "num1change" @num2change = "num2change"/> </div>
<template> <div> <!--双向绑定,绑定在子组件中的data的数据--> <input type = "text" v-model = "
dnumber1"> <input type = "text" v-model = "dnumber2"> <!--实现将子组件中的数据实时传向父组件--> <
input type="text" :value="dnumber1" @input="numInput1"> <input type="text"
:value="dnumber2" @input="numInput2"> </div> </template> <script> const app =
new Vue({ el:"#app", data:{ num1:1, num2:2 }, methods:{
//默认情况下,从子组件传递过来的数据为字符串String类型 num1change(value){ this.num1 = parseInt(value) }
, num2change(value){ this.num2 = parseInt(value) } } components:{ cpn:{ template
:"#cpn", props:{ number1:Number, number2:Number }, data(){ return { dnumber1:
this.number1, dnumber2:this.number2 } }, methods:{ numInput1(event){
//将input中的数据赋值到dnumber1中 this.dnumber1 = event.target.value //向父组件data中传递数据,实时更改
this.$emit('num1change',this.dnumber1) //同时修改dnumber2中的数据 this.dnumber2 = this.
dnumber1*100 this.$emit('num2change',this.dnumber2) }, numInput2(event){ this.
dnumber2= event.target.value this.$emit('num2change',this,dnumber2)
//同时修改dnumber1中的数据 this.dnumber1 = this.dnumber2/100 this.$emit('num1change',
this.dnumber1) } } } } }) </script>
*
父子组件的访问方式
—有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者子组件直接访问根组件;
父组件访问子组件
—使用$children或者$refs;
子组件访问父组件
—使用$parent;
$children访问子组件
—this.$children返回的是数组类型,包含所有的子组件;但是这种方法,通过下标值访问子组件时,可能会因为子组件的数量变化而需要改变;开发中使用较少;
$refs访问子组件
—返回对象类型,默认是空对象,需要在子组件上加上ref属性,可以通过this.$refs访问子组件,然后通过this.$refs.ref属性值进行访问;
$parent访问父组件
—当父组件为根组件时候,返回Vue实例,其余返回Vue组件,在开发中不建议使用这种方式访问父组件,子组件的复用性不强,父子组件耦合度太高;
—直接访问根组件,使用$root;
*
插槽
—插槽的目的是让我们原来的设备具有更多的扩展性;
—组件的插槽也是为了让我们封装的组件更加具有扩展性,让使用者可以决定组件内部的一些内容到底展示什么;
—插槽的基本使用:
插槽可以设置默认值,并且如果有多个值,同时放入组件进行插槽内容替换时,将一起作为替换元素;
<div id="app"> <!--因此创建了插槽,在组件中可以写入不同内容--> <cpn><button>按钮</button></cpn> <cpn>
<span>嘻嘻嘻</span></cpn> </div> <template id = "cpn"> <div> <h2>我是组件</h2>
<!--添加插槽--> <!--可以给插槽默认值,当组件没有指定内容时,就显示默认值--> <slot><button>按钮</button></slot> <
div> </template> <script> const cpn = { template:"#cpn" } const app = new Vue({
el:"#app", data:{}, components:{ cpn } }) </script>
具名插槽
—一个组件下可能会有多个插槽,可能需要分别对组件内部某个部分进行扩张,我们在使用时,可以为插槽添加name属性,这样以防止在进行替换时,将所有插槽内容替换;
—需要修改哪个具体的插槽内容,需要添加slot = "插槽name属性值";
编译作用域:当在查找一个元素时,会在当前模板下进行查找,即当前父元素下为其编译作用域;(自己理解,官方理解可查看官网)
—父组件模板的所有东西都会在父级作用域内编译,子组件模板的所有东西都会在子级作用域内编译;
作用域插槽
—简单理解为父组件替换插槽的标签,但是内容是由子组件来提供的;
<div id = "app"> <!--目的是获取子组件中的pLanguages--> <cpn> <template slot-scope="slot">
<span v-for = "item" in slot.data>{{item}}</span> <span>{{slot.data.join('*')}}
</span> </template> </cpn> </div> <template id = "cpn"> <div> <!--插槽--> <slot
:data = "pLanguages"> <ul> <li v-for = "item in pLanguages">{{item}}</li> </ul>
</slot> </div> </template> <script> const app = new Vue({ el:"#app", data:{ },
components:{ cpn:{ template:"#cpn", data(){ return{ pLanguages:['Javascritp',
'C++','C#','Python'] } } } } }) </script>