Vue父子组件如何双向绑定传值

前言

父子组件之间的双向绑定很是简单,可是不少人由于是从Vue 2+开始使用的,可能不知道如何双向绑定,固然最简单的双向绑定(单文件中)就是表单元素的v-model了,例如<input type="text" />它会响应表单元素的value属性,当输入框文本改变时,会将value值传给v-model所绑定的变量,若是同时设置v-modelvaluevalue属性无效。javascript

欢迎来个人Vue技术群交流:Vue887516034html

父子组件的自定义双向v-model

当若干dom封装成组件时,在父组件中使用子组件时,却没法在子组件标签上使用v-model,由于子组件标签不是表单元素,这个时候,咱们须要自定义咱们想要的v-model规则。vue

<!-- children.vue -->
<template>
    <h1>{{ msg }}</h1>
</template>
<script> export default{ model:{ prop:'msg',//这个字段,是指父组件设置 v-model 时,将变量值传给子组件的 msg event:'parent-event'//这个字段,是指父组件监听 parent-event 事件 }, props:{ msg:String //此处必须定义和model的prop相同的props,由于v-model会传值给子组件 }, mounted(){ //这里模拟异步将msg传到父组件v-model,实现双向控制 setTimeout(_=>{ let some = '3秒后出现的某个值';//子组件本身的某个值 this.$emit('parent-event',some); //将这个值经过 emit 触发parent-event,将some传递给父组件的v-model绑定的变量 },3000); } } </script>
复制代码
<!-- parent.vue -->
<template>
    <children v-model="parentMsg"></children>
</template>
<script> import children from 'path/to/children.vue'; export default{ components:{ children }, data(){ return{ parentMsg:'test' } }, watch:{ parentMsg(newV,oldV){ console.log(newV,oldV); //三秒后控制台会输出 //'3秒后出现的某个值','test' } } } </script>
复制代码

你学会组件的自定义v-model了吗 ? 若是是普通的表单元素,同理,监听表单的input或者change事件,实时将value或者checked经过$emit传递就能够了。java

父子组件的自定义多个双向值

上述例子,是实现单个prop值的双向绑定,当组件的需求须要复杂的操做,须要多个双向值,是如何实现的呢。这里须要用到之前被vue抛弃,后来又回归的.sync修饰符。dom

事实上,这个比v-model更加简单异步

<!-- children.vue -->
<template>
    <h1>{{ msg }}</h1>
</template>
<script> export default{ props:{ msg:String }, mounted(){ //这里模拟异步将msg传到父组件v-model,实现双向控制 setTimeout(_=>{ let some = '3秒后出现的某个值';//子组件本身的某个值 this.$emit('update:msg',some); //将这个值经过 emit //update为固定字段,经过冒号链接双向绑定的msg,将some传递给父组件的v-model绑定的变量 },3000); } } </script>
复制代码
<!-- parent.vue -->
<template>
    <children :msg.sync="parentMsg"></children>
    <!-- 此处只需在平时经常使用的单向传值上加上.sync修饰符 -->
</template>
<script> import children from 'path/to/children.vue'; export default{ components:{ children }, data(){ return{ parentMsg:'test' } }, watch:{ parentMsg(newV,oldV){ console.log(newV,oldV); //三秒后控制台会输出 //'3秒后出现的某个值','test' } } } </script>
复制代码

此处须要注意,虽然加上.sync便可双向绑定,可是仍是要依靠子组件$emit去触发update:prop名实现修改父组件的变量值实现双向数据流,若是直接对prop的属性直接赋值,依然会出现报错。ui

事实上,.sync修饰符是一个简写,它作了一件事情this

<template>
    <children :msg.sync="parentMsg"></children>
    <!-- 等价于 -->
    <children :msg="parentMsg" @update:msg="parentMsg = $event"></children>
    <!-- 这里的$event就是子组件$emit传递的参数 -->
</template>
复制代码

当须要把一个对象中的属性所有经过.sync传入双向数据流时,能够再简便一下写法spa

<template>
    <children :.sync="obj"></children>
</template>
<script> export default{ components:{ children }, data(){ return{ obj:{ parentMsg:'test' } } } } </script>
复制代码

当使用这种写法时,会将obj对象中的全部属性都经过独立的props传递给子组件,并监听对应的update:,此时在子组件中也要声明对应的props。双向绑定

总结

在父子组件中,使用双向数据流,在某些时候,可以起到很好效果,以及开发体验,不过必定要适量使用,双向数据流会给项目的后期维护增长负担。

tips:懂得分享才会走得更远。

欢迎来个人Vue技术群交流:Vue887516034

若是以为对你有用,就打赏一下吧。

相关文章
相关标签/搜索