Vue关于双向绑定和单向数据流的理解

很多接触Vue开发不久的同学会有疑问,vue既然是单向数据流为什么会有双向绑定一说?

关于Vue数据绑定首先引用官网原话:

AngularJS 使用双向绑定,Vue 在不同组件间强制使用单向数据流。这使应用中的数据流更加清晰易懂。

官网已经说的很清楚了,在Vue中使用的是单向数据流,我们由此可以确定,Vue中的所谓的双向绑定并不是真正的双向绑定。

要想理解Vue中的所谓双向绑定首先要先弄清楚其实现原理。

例子:实现如下双向绑定的效果:

要想让上面的用户名和手机号和下面的用户名和手机号保持联动,我们首先想到的就是v-model指令。

我们先创建一个局部组件PersonalInfo.vue,并引入

<personal-info v-model="username" :phone="phone" @update:phone="val=>(phone=val)"></personal-info>

由于v-model一次只能绑定一个prop,其它的prop属性如果也要实现双向绑定的效果,我们可以使用Vue自定义事件中提供的update:myPropName的方式。

PersonalInfo.vue源码如下:

        {
            template: `<div>
              用户名:<input :value="username" type="text" placeholder="用户名"     
              @input="handleUsernameChange" /><br/>
              手机号:<input :value="phone" type="number" placeholder="手机号" 
              @input="handlePhoneChange" /><br/>
            </div>`,
            name: "PersonalInfo",
            props: {
                username: String,
                phone: String,
            },
            methods: {
                handleUsernameChange(e) {
                    this.$emit("input", e.target.value);
                },
                handlePhoneChange(e) {
                    this.$emit("update:phone", e.target.value);
                }
            }
        }

下面我们试一下v-model的其它实现方式

<personal-info :username="username" @change="val=>(username=val)" :phone="phone" @update:phone="val=>(phone=val)"></personal-info>

v-model其实就是v-bind:propName加自定义事件的缩写。

此时PersonalInfo.vue需要修改为:

        {
            template: `<div>
              用户名:<input :value="username" type="text" placeholder="用户名" 
              @input="handleUsernameChange" /><br/>
              手机号:<input :value="phone" type="number" placeholder="手机号" 
              @input="handlePhoneChange" /><br/>
            </div>`,
            name: "PersonalInfo",
            model: {
                prop: 'username',
                event: 'change'
            },
            props: {
                username: String,
                phone: String,
            },
            methods: {
                handleUsernameChange(e) {
                    this.$emit("change", e.target.value);
                },
                handlePhoneChange(e) {
                    this.$emit("update:phone", e.target.value);
                }
            }
        }

当输入框输入内容时会触发对应的事件回调函数,在回调函数中会再次触发父组件传递的自定事件并传值给父组件,最后在父组件回调函数中更改了Model中定义的值。

至此我们可以发现Vue中的双向绑定效果并不是真正的双向绑定,真正的双向绑定是Model<-->View,而例子中最终其实是在父组件自定义事件中重新对prop属性赋值,所以说到底我们还是通过改变Model才导致了View的更新。

发布了54 篇原创文章 · 获赞 0 · 访问量 7692

猜你喜欢

转载自blog.csdn.net/yuyongkun4519/article/details/100101731