shayloyuki

科技是第一生产力

 

自定义组件使用 `v-model` 进行双向数据绑定

需求

业务需要一个显示数据范围的组件,设计两个 input 输入框,中间加上分隔字符。传递给组件的数据 value 是一个数组,第一个元素是最小值,第二个元素是最大值。

页面展示

image

尝试

最开始使用了父子组件的传值:v-bindthis.$emit,但是这样的问题是:

  1. 子组件中不知何时应该将新值传给父组件

    如果是监听到子组件的销毁状态时(即这里的对话框关闭时),传递新值给父组件,那么点击 确定取消 按钮时触发的事件应该不一样:

    • 点击 确定:新值覆盖旧值,子组件中将新值传给父组件;
    • 点击 取消:旧值仍然保留,重置表单。
  2. 针对问题1,如果在父组件中监听 确定 按钮的触发,一旦点击了该按钮,就让子组件把新值传递给父组件。但是这样又导致了一个问题:由于子组件在父组件中会被循环使用,因此不知道是哪一个 label 的值发生了改变,需要把新值和对应 id进行关联,以便区分。这样会导致问题变得更复杂。

因此,v-bindthis.$emit 的方式不合适。

解决方法

为了避免上述问题,需要用到 v-model 双向数据绑定。虽然这也是一个语法糖,其本质还是用到了 v-bindthis.$emit

  1. v-bind 绑定一个 value 属性
  2. v-on 监听当前元素的 input 事件,当数据变化时,将值传递给 value 实时更新数据

注意事项

  1. v-model 默认传递的值是 value,在子组件中接收后,这里是数组。但 form 表单中绑定的数据必须是对象,因此这里要给 value 包裹上 {},才不会报错。

    参考链接: type check failed for prop “model“. Expected Object, got Array

  2. 一般来说,v-model 双向绑定中 this.$emit 都是传递单个值。这里需要传递两个值,要明确的是:@input 实时监听输入,参数 e 代表的是新值,因此可以用 this.value[index] 指代其他 input 输入框的值。

代码

image

image

参考链接

v-model 原理: Vue自定义组件实现v-model指令

posted on 2022-07-27 15:44  shayloyuki  阅读(1589)  评论(0编辑  收藏  举报

导航