vue中如何实现双向数据绑定(【Vue2从入门到精通】详解Vue数据双向绑定原理及手动实现双向绑定)
✨什么是数据双向绑定
我们先从单向绑定切入单向绑定非常简单 ,就是把Model绑定到View 。
什么是双向绑定呢?当我们用JavaScript代码更新Model时 ,View就会自动更新 ,在单向绑定的基础上 ,用户更新了View ,Model的数据也自动被更新了 ,这种情况就是双向绑定 。
✨数据双向绑定的原理
数据双向绑定的原理之前 ,我们先来了解一下什么是MVVM 。
MVVM是一种设计思想 ,它是Model-View-ViewModel的缩写 。它也是MVC的增强版 。
Model是代表数据模型 ,也可以在Model中定义数据修改和操作的业务逻辑 。 View是代表UI组件 ,它负责将数据模型转化成UI展现出来 。 ViewModel是一个同步View和Model的对象 。ViewModel的主要职责:
数据变化后更新视图 视图变化后更新数据当然 ,它还有两个主要部分组成
监听器(Observer):对所有数据的属性进行监听 解析器(Compiler):对每个元素节点的指令进行扫描跟解析,根据指令模板替换数据,以及绑定相应的更新函数✨Vue数据双向绑定原理
Vue是采用数据劫持结合发布者-订阅者模式的方式 ,通过使用ES5中的Object.defineProperty()方法来劫持各个属性的setter,getter ,在数据变动时发布消息给订阅者 ,触发相应的监听回调来渲染视图 。
Object.defineProperty()允许在对象上定义新的属性,以及修改或删除现有属性的特性 ,其中包括get 、set 、enumerable和configurable等 。
✨实现数据双向绑定的步骤
创建Vue实例时 ,在data属性中定义需要双向绑定的数据 。 在模板中使用v-model指令将输入控件绑定到数据属性上 。
在Vue内部 ,使用Object.defineProperty()方法将数据属性转换为getter/setter形式 ,从而实现数据的响应式变化。 当输入控件的值发生变化时 ,Vue会自动调用数据属性的setter方法 ,从而更新数据的值 。 当数据的值发生变化时 ,Vue会自动更新相关的DOM元素 ,从而实现数据与视图的双向绑定 。示例代码如下:
html
<div id="app"> <input v-model="message"> <p>{{ message }}</p> </div>javascript
var vm = new Vue({ el: #app, data: { message: } });在上面的代码中 ,v-model指令将输入框和message属性进行了双向绑定。当输入框的值发生变化时 ,message属性的setter方法会被调用 ,从而更新数据 。当message属性的值发生变化时 ,相关的DOM元素也会自动更新,从而实现了数据与视图的双向绑定 。
需要注意的是 ,Vue的双向绑定仅适用于一些特定的输入控件 ,如input 、textarea和select等 。对于自定义组件,需要手动实现数据的双向绑定 。
如何手动实现数据的双向绑定呢?请继续往下看 。
✨手动实现自定义组件的双向绑定的步骤
在自定义组件中 ,通过props属性接收父组件传递的数据 ,并在组件中定义一个内部变量来保存这些数据 。 在组件内部使用v-model指令将输入控件绑定到内部变量上 。 在组件内部监听输入控件的变化事件 ,并在事件处理函数中更新内部变量的值 。 在组件内部通过$emit()方法触发一个自定义事件 ,并将内部变量作为参数传递给父组件 。 在父组件中使用自定义事件的处理函数来更新父组件中的数据 。示例代码如下:
<!-- 父组件 --> <template> <div> <my-component v-model="message"></my-component> <p>{{ message }}</p> </div> </template> <script> import MyComponent from ./MyComponent.vue; export default { components: { my-component: MyComponent }, data() { return { message: } } } </script> <!-- 自定义组件 --> <template> <div> <input type="text" v-model="internalValue"> </div> <template> <script> export default { props: [value], data() { return { internalValue: } }, mounted() { this.internalValue = this.value; }, watch: { internalValue() { this.$emit(input, this.internalValue); } } } </script>在上面的代码中 ,我们定义了一个名为value的props属性来接收父组件传递的数据 ,同时定义了一个名为internalValue的内部变量来保存这些数据 。在组件挂载后 ,我们将value的值赋值给internalValue 。
在组件内部使用v-model指令将输入控件绑定到internalValue上。当输入控件的值发生变化时 ,我们使用watch来监听internalValue的变化事件 ,并在事件处理函数中使用$emit()方法触发一个名为input的自定义事件 ,并将internalValue作为参数传递给父组件 。
在父组件中 ,我们可以通过v-model指令将message属性与自定义组件的value属性进行双向绑定 。当自定义组件的input事件被触发时 ,我们可以在事件处理函数中将事件的参数作为message属性的值进行更新。
示例代码如下:
<!-- 父组件 --> <template> <div> <my-component v-model="message"></my-component> <p>{{ message }}</p> </div> </template> <script> import MyComponent from ./MyComponent.vue; export default { components: { my-component: MyComponent }, data() { return { message: } } } </script> <!-- 自定义组件 --> <template> <div> <input type="text" v-model="internalValue"> </div> </template> <script> export default { props: [value], data() { return { internalValue: } }, mounted() { this.internalValue = this.value; }, watch: { internalValue() { this.$emit(input, this.internalValue); } } } </script>在上面的代码中,我们定义了一个名为message的数据属性 ,并将它与自定义组件的value属性进行了双向绑定 。
同时 ,在自定义组件中,我们实现了数据的双向绑定 ,并通过$emit()方法触发了一个名为input的自定义事件来与父组件进行通信 。这样就实现了自定义组件的双向绑定 。
✨写在最后
✨ 原创不易 ,希望各位大佬多多支持 。 👍 点赞 ,你的认可是我创作的动力 。 ⭐️ 收藏 ,感谢你对本文的喜欢 。 ✏️ 评论 ,你的反馈是我进步的财富 。创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!