自定义组件 v-model:Vue 如何实现双向绑定

更新日期: 2022-01-20阅读: 1.2k标签: 双向绑定

v-model 是 vue 中一个常用的指令,常用于表单中的数据绑定。如下基本用法想必大家都很熟悉,data 中的 checked 属性的值就会随着多选框的状态实时变化。

<el-checkbox v-model="checked" />

但你或许听说过,Vue 组件之间是“单向数据流”,即通过 props 从父组件向子组件单向传递数据。那么,v-model 的“双向绑定”效果是如何实现的呢?

自定义组件实现 v-model

首先来看一个实际应用的例子,需求如下:在创建试卷页面 paperCreate 中,通过选择题目组件 questionSelect 查询并选择题目组成试卷,效果如下图所示。


为了方便使用,希望能在选择题目组件上使用 v-model 指令进行双向绑定:

<!-- 选择题目组件 -->
<question-select v-model="formData.questions" />

<!-- 显示已选择题目 -->
<div v-for="item in formData.questions" :key="item.id" >
    <question :question="item" />
</div>

value 属性和 input 事件

自定义支持 v-model 的组件只需要满足两个条件:

  • value 属性作为传入数据
  • 数据改变时,将新数据作为 payload,向上 emit 一个 input 事件

就是这么简单,相关代码为:

export default {
  props: {
    value: Array,	// 类型根据实际需要
  },
  methods: {
    handelChange() {
      this.$emit("input", newValue);
    },
  },
};

如果不想使用默认的 value 属性和 input 事件,也可以通过 model 对象自定义相应属性和事件:

model: {
  prop: 'checked',
  event: 'change',
},

单向数据流

需要注意的是,prop 传值是单向的,即父组件中的数据改变会反映到子组件中,但在子组件内部不能主动改变 prop 的值。具体来说就是,子组件中不能使用类似于 v-model="value" 之类试图改变 value 值的操作。

因此表格中的 checkbox,也只单向传入 value 来控制是否选中的状态,然后在选中状态改变时手动处理改变后的结果。

  • 对于表格中的一行(即一道题目),如果传入的 value 数组(即已选中的题目列表)中包含它的 id,则显示为选中状态
  • 不能直接改变原数组 value,直接构造新列表传出:
    • 如果新增了一个选项,传原列表 + 所选对象
    • 如果取消了一个选项,传原列表 - 所选对象

(PS:组件库中提供的 el-checkbox 实际上也是另一个自定义组件,可以同理分析)

<el-table :data="questionList">
  <el-table-column>
    <template slot-scope="scope">
      <el-checkbox
        :value="selectedIds.includes(scope.row.id)"
        @change="(value) => handelChange(scope.row, value)"
      />
    </template>
  </el-table-column>
  <!-- 其他属性 -->
</el-table>
props: {
  value: Array,
},
computed: {
  selectedIds() {
    return this.value.map((item) => item.id);
  },
},
methods: {
  handelChange(item, checked) {
    if (checked) {
      this.$emit("input", [...this.value, item]);
    } else {
      this.$emit(
        "input",
        this.value.filter((element) => element.id != item.id)
      );
    }
  },
},

具体写法与组件库的具体实现有关,简单说明一下此处的 element 语法

  • scope.row 为 el-table 表格当前行对应的对象
  • el-checkbox 的 change 事件的负载为复选框点击后的新值

然后就结束了,父组件使用选择题目组件时就能正常使用 v-model 了。本例中绑定的数据是完整的题目列表,原因是需要在页面中显示已选择题目的具体信息;如果只需要 id 数据(例如 select 那样的组件),则 emit 时只传 id 列表即可,写法完全一致。

双向绑定

通过上面的例子想必你已经看出来了,v-model 指令的“双向绑定”实际上是一个语法糖:它将父组件的数据通过 prop 传入子组件,再监听子组件的输入事件来更新父组件中的数据,从而实现双向绑定的效果。


来自:https://www.cnblogs.com/skuld-yi/archive/2022/01/19/15823949.html


链接: https://fly63.com/article/detial/11054

原生js实现数据双向绑定的三种方式总汇

前端的视图层和数据层有时需要实现双向绑定(two-way-binding),例如mvvm框架,数据驱动视图,视图状态机等,研究了几个目前主流的数据双向绑定框架,总结了下。目前实现数据双向绑定主要有以下三种。

Vue双向绑定的实现原理

vue.js 采用数据劫持的方式,结合发布者-订阅者模式,通过Object.defineProperty()来劫持各个属性的setter,getter以监听属性的变动,在数据变动时发布消息给订阅者,触发相应的监听回调.

vue双向数据绑定失效_解决vue添加新属性实现双向绑定

vue框架目前在前端开发使用比较广了,但是又很多同学发现vue创建对象之后添加新的属性实现不了双向绑定,下面就简单介绍如何解决vue双向绑定出现失效的问题

vue2 实现 div contenteditable=true 类似于 v-model双向数据绑定的效果

用到 contenteditable=true的 div ,而在这个 div 上是使用 v-model 是没有效果的,这里的双向数据绑定该如何实现?解决思路:一自定义指令,二使用组件。

自定义 Vue 中的 v-model 双向绑定

v-model 双向绑定实际上就是通过子组件中的 $emit 方法派发 input 事件,父组件监听 input 事件中传递的 value 值,并存储在父组件 data 中;然后父组件再通过 prop 的形式传递给子组件 value 值,再子组件中绑定 input 的 value 属性即可。

vue双向绑定原理分析

当我们学习angular或者vue的时候,其双向绑定为我们开发带来了诸多便捷,今天我们就来分析一下vue双向绑定的原理。vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter

简单实现一个vue的双向绑定

首先我们来看一些,vue的基本使用方法;然后我们根据使用方法,来设计一个类和一些基础的声明周期;获取根元素;生命周期 beforeCreate;获取初始数据;获取渲染函数

React input表单双向数据绑定仿Vue v-model实现

用过Vue的同学都知道,Vue里<input> 、 <textarea> 及 <select>等表单元素可以通过v-model指令实现双向数据绑定,也就是说,当用户通过交互改变表单的值时,表单绑定的数据也会同步响应,这一点也是Vue对开发人员非常友好的点之一。

js 超浓缩 双向绑定

绑定确实是个有趣的话题。现在我的绑定器有了不少的功能1. 附着在Object对象上,一切以对象为中心2. 与页面元素进行双向绑定

Vue - 自定义组件双向绑定

无论在任何的语言或框架中,我们都提倡代码的复用性。对于Vue来说也是如此,相同的代码逻辑会被封装成组件,除了复用之外,更重要的是统一管理提高开发效率。我真就接手过一个项目,多个页面都会用到的列表

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!