vue 父子组件通信props/emit
props
1.父组件传递数据给子组件
父组件:
<parent> <child :childMsg="msg"></child>//这里必须要用 - 代替驼峰 </parent> data(){ return { msg: [1,2,3] }; }
子组件通过props来接收数据:
方式1:
props: ['childMsg']
方式2 :
props: {
childMsg: Array //这样可以指定传入的类型,如果类型不对,会警告
}
方式3:
props: {
childMsg: {
type: Array,
default: [0,0,0] //这样可以指定默认的值
}
}
2.子组件与父组件通信
若子组件想要改变数据?
这在vue中是不允许的,因为vue只允许单向数据传递,我们可以通过触发事件来通知父组件改变数据,从而达到改变子组件数据的目的.
子组件:
<template> <div @click="up"></div> </template> methods: { up() { this.$emit('up','hello'); //主动触发up方法,'hello'为向父组件传递的数据 } }
父组件:
<div> <child @up="change" :msg="msg"></child> //监听子组件触发的upup事件,然后调用change方法 </div> methods: { change(msg) { this.msg = msg; } }
sync 修饰符
在 vue@1.x 的时候曾作为双向绑定功能存在,即子组件可以修改父组件中的值。因为它违反了单向数据流的设计理念,所以在 vue@2.0 的时候被干掉了。但是在 vue@2.3.0+ 以上版本又重新引入了这个 .sync 修饰符。但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 监听器。说白了就是让我们手动进行更新父组件中的值了,从而使数据改动来源更加的明显。
.sync 语法糖简写成如下形式:
// 父组件
<template> <div> 父组件{{number}} <child v-bind:num.sync="number"></child> </div> </template> <script> import child from './Child' export default { name: 'HelloWorld', data () { return { number: 1 } }, components: { child } } </script>
// 子组件 <template> <div>子组件 <div>{{num}}</div> <div @click="increment">点击</div> </div> </template> <script> export default { data () { return { } }, mounted () { console.log(this.title) }, props: ['num'], methods: { increment: function () { this.$emit('update:num', '8888') } } } </script>
v-model 和 .sync
<!--v-model写法--> <my-component type="text" v-model="value"> <!--编译后的写法--> <my-component type="text" :value="value" @input="value = $event.target.value" > <!-- 默认针对原生组件input事件,但是如果子组件定义了针对事件 model: { prop: "value", event: "update" }, 则编译为 --> <my-component type="text" :value="value" @update="(val) => value = val" >
<!--语法糖.sync--> <my-component :value.sync="value" /> <!--编译后的写法--> <my-component :value="msg" @update:value="(val) => value = val" >
两者的功能类似,目的均是实现双向绑定。
1)v-model默认对应的是input或者textarea等组件的input事件,如果在子组件替换这个input事件,其本质和.sync修饰符一模一样。比较单一,不能有多个。
// 子组件可以用自定义事件,来替换v-model默认对应的原生input事件,只不过我们需要在子组件手动 $emit
2)一个组件可以多个属性用.sync修饰符,可以同时"双向绑定多个“prop”,而并不像v-model那样,一个组件只能有一个。
总结功能作用场景:
1.v-model针对更多的是最终操作结果,是双向绑定的结果,是value,是一种change操作。
比如:输入框的值、多选框的value值列表、树结构最终绑定的id值列表(ant design和element都是)、等等...
2..sync针对更多的是各种各样的状态,是状态的互相传递,是status,是一种update操作。
比如:组件loading状态、子菜单和树结构展开列表(状态的一种)、某个表单组件内部验证状态、等等....