vue 自定义组件双向数据绑定

!!!这边文章记录的是 vue2 的概念,vue3 对双向绑定进行了改动,不要把一下代码放到 vue3 中运行。vue3 双向绑定的改动参考 这里

作者:玄晓乌屋
最后更新时间:2019/6/25

vue 自定义组件双向绑定没有直接一步到位的方式,全都是是通过属性传值和事件传值实现的。v-model 不能直接支持组件的双向绑定。

属性&事件传值双向绑定

这种方式最复杂,也最容易理解,前提是需要深刻理解事件传值和属性传值。
新建一个组件 Com.vue

<template>
  <!-- 单项绑定props值到value -->
  <!-- 监听input事件,提交组件事件myInput并传递更新的值 -->
  <input :value="query" @input="$emit('myInput',$event.target.value)">
</template>
<script>
export default {
  // 获取props值
  props: ['query']
}
</script>

新建一个 .vue 文件引入 Com.vue 组件并调用:

<template>
  <div id="home">
    <!-- 传递query给Com组件,并设置myInput事件更新当前组件的query -->
    <Com :query="query" @myInput="val => query=val"/>
    {{query}}
  </div>
</template>

<script>
import Com from '../components/Com'
export default {
  components: { Com },
  data() {
    return {
      query: null
    }
  }
}
</script>

解释:
这种通过事件和组件传值的方式并不难,就是在父组件中传值给子组件,并设置一个事件。
子组件获取到值后先单项绑定到某个地方,上面绑到了 input 元素中,在 input 元素中通过监听 input 事件来提交组件事件 myInput 。如果学过 react ,这就是简单的状态提升。

总结:属性&事件传值双向绑定可控性很好,支持多个数据的双向绑定,但是复杂和凌乱,单个数据可以使用,但是多个数据会造成代码可读性很低,不实用。

v-model组件双向绑定

官方对v-model指令做了一些准备工作,和上述 属性&事件传值的双向绑定 相比:
v-model 默认传递一个名为 value的值和默认绑定一个名为input的事件更新这个值。
注意:使用v-model时,默认属性和事件名是固定的valueinput
如下:

<template>
  <div id="home">
    <Com v-model="query"/>
    <Com :value="query" @input="v => query=v"/>
    <!-- 上面两行等价 -->
    {{query}}
  </div>
</template>

实现:
修改 Com.vue 文件如下:

<template>
  <!-- 单项绑定value -->
  <!-- 监听input事件提交组件事件input,注意这两个input不一样了,前一个是<input/>元素的事件,后一个是组件的事件 -->
  <input :value="value" @input="$emit('input',$event.target.value)">
</template>
<script>
export default {
  // 这个值改成value
  props: ['value']
}
</script>

新建任意 .vue 文件引入 Com.vue 组件:

<template>
  <div id="home">
    <Com v-model="query"/>
    <Com :value="query" @input="v => query=v"/>
    <!-- 上面两行等价 -->
    {{query}}
  </div>
</template>

<script>
import Com from '../components/Com'
export default {
  components: { Com },
  data() {
    return {
      query: null
    }
  }
}
</script>

此时在页面上有两个input框,两边的值都绑定同一个值query
如图:
v-model组件双向绑定
总结:v-model 虽然简化了 属性&事件传值双向绑定 的模式,但是只能传一个值,并且传递固定属性 value 和固定触发事件input,只适用于传单个值的组件,比如常见的表单组件。

.sync修饰符双向绑定

.sync修饰符简化了 属性&事件传值的双向绑定 的模式,虽然比v-model的方式稍微麻烦点,但是支持多个数据在组件上双向绑定。
使用.sync修饰符修饰一个单项绑定到组件的属性,会默认绑定一个update:myPropName的事件,myPropName是绑定的属性名。
修改 Com.vue 组件如下:

<template>
  <!-- 监听input事件,提交.sync修饰符提供的update:<myPropName>事件 -->
  <input :value="value" @input="$emit('update:value',$event.target.value)">
</template>
<script>
export default {
  props: ['value']
}
</script>

新建一个 .vue 文件引入 Com.vue 并使用:

<template>
  <div id="home">
    <Com :value.sync="query"/>
    {{query}}
  </div>
</template>

<script>
import Com from '../components/Com'
export default {
  components: { Com },
  data() {
    return {
      query: null
    }
  }
}
</script>

上述方式依旧可以实现双向数据绑定。
总结:实用简单,代码可读性较好,可控性好,可以支持多个数据的双向数据绑定。

总结

以上提供3种方式,属性&事件传值双向绑定比较复杂,但是逻辑清晰,是组件双向数据绑定的核心。v-model组件双向绑定简单,适用于单个数据。.sync修饰符双向绑定可控性好,适用于多个属性双向绑定。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值