Vue 2.0学习笔记:实现组件数据的双向绑定
2018-03-05 00:00
1021 查看
通过上一节的学习,我们了解到了在Vue的组件中数据传递:
将
这样做的好处是:父组件数据改变时,不会修改存储
<div class="parent">
<h3>父组件Parent数据</h3>
<ul>
<li>
<label>姓名:</label>
<span>{{ name }}</span>
<input type="text" v-model="name" />
</li>
<li>
<label>年龄:</label>
<span>{{ age }}</span>
<input type="number" v-model="age" />
</li>
</ul>
</div>
<child :my-name="name" :my-age="age" @update:my-name="val => name = val" @update:my-age="val => age = val"></child></div><template id="child">
<div class="child">
<h3>子组件child数据</h3>
<ul>
<li>
<label>姓名</label>
<span>{{ myName }}</span>
<input type="text" v-model="childMyName" />
</li>
<li>
<label>年龄</label>
<span>{{ myAge }}</span>
<input type="number" v-model="childMyAge" />
</li>
</ul>
</div>
</template>在上面的这个示例中,我们并没有使用
el: '#app',
data () {
return {
name: 'w3cplus',
age: 7
}
},
components: {
'child': {
template: '#child',
props: ['myName', 'myAge'],
data () {
return {
childMyName: this.myName,
childMyAge: this.myAge
}
},
watch: {
childMyName: function (val) {
this.$emit('update:my-name', val)
},
childMyAge: function (val) {
this.$emit('update:my-age', val)
}
}
}
}
})最终效果如下:
上面的示例效果,不管是修改父组件的数据还是子组件的数据,都会相互影响:
因为子组件中
'child': {
template: '#child',
props: ['myName', 'myAge'],
data () {
return {
childMyName: this.myName,
childMyAge: this.myAge
}
},
...
}
}接下来在子组件中通过
watch: {
childMyName: function (val) {
this.$emit('update:my-name', val)
},
childMyAge: function (val) {
this.$emit('update:my-age', val)
}
}
...接下来要做的事情就是当组件内的
至此,实现了组件内部数据与组件外部的数据的双向绑定,组件内外数据的同步。简而言之:组件内部自已变了告诉外部,外部决定要不要变更。
什么样的
事实上,在Vue中,双向绑定的
组件需要可以由外部在运行时动态控制,而非单纯的初始化
组件父部需要读取组件内的状态来进行处理
虽然上面的示例展示了我们怎么在Vue 2.0中实现
文章涉及到图片和代码,如果展示不全给您带来不好的阅读体验,欢迎点击文章底部的 阅读全文。如果您觉得小站的内容对您的工作或学习有所帮助,欢迎关注此公众号。
W3cplus.com————————————记述前端那些事,引领web前沿
长按二维码,关注W3cplus▼
prop向下传递,事件向上传递。意思是父组件通过
prop给子组件下发数据,子组件通过事件给父组件发送消息。但Vue中,
props是单向数据绑定,虽然在Vue 1.0版本中,通过
.sync能实现双向数据绑定。但
.sync在几个版本中被移除,尽管在2.3版本重新引入
.sync修饰符,可这次引入只是作为一个编译时的语法糖存在。如果直接使用
.sync修饰符来做双向数据绑定,会报警告信息。那么我们如何在组件中实现双向数据绑定呢?这一节我们就来学习这方面的相关知识。
实现组件双向数据绑定
在上一节中最后的示例使用的是Vue 1.0版本中的.sync实现数据双向绑定。那我们先来看看抛弃
.sync修饰符来实现组件双向数据绑定的工作:通过Vue提供的机制,绕开直接修改
prop来实现组件双向数据绑定。其思路大致是这样:在数据渲染时使用
prop渲染数据
将
prop绑定到子组件自身的数据上,修改数据时修改自身数据来替代
prop
watch子组件自身数据的改变,触发事件通知父组件更改绑定到
prop的数据
这样做的好处是:父组件数据改变时,不会修改存储
prop的子组件数据,只是以子组件数据为媒介,完成对
prop的双向修改。继续拿上一节的示例来举例,只不过接下来的示例,并没有使用
.sync来实现双向数据绑定的效果。修改的代码如下:<div id="app">
<div class="parent">
<h3>父组件Parent数据</h3>
<ul>
<li>
<label>姓名:</label>
<span>{{ name }}</span>
<input type="text" v-model="name" />
</li>
<li>
<label>年龄:</label>
<span>{{ age }}</span>
<input type="number" v-model="age" />
</li>
</ul>
</div>
<child :my-name="name" :my-age="age" @update:my-name="val => name = val" @update:my-age="val => age = val"></child></div><template id="child">
<div class="child">
<h3>子组件child数据</h3>
<ul>
<li>
<label>姓名</label>
<span>{{ myName }}</span>
<input type="text" v-model="childMyName" />
</li>
<li>
<label>年龄</label>
<span>{{ myAge }}</span>
<input type="number" v-model="childMyAge" />
</li>
</ul>
</div>
</template>在上面的这个示例中,我们并没有使用
.sync修饰符,但在调用子组件的时候使用了
@update:<child :my-name="name" :my-age="age" @update:my-name="val => name = val" @update:my-age="val => age = val"></child>子组件中渲染到HTML模板的数据是用的
prop数据,但监听
input是使用的子组件自身定义的数据作为
v-model。这样一来就不会直接修改
prop。简单来说,一切
prop的改变从本质上来说都由父组件完成。JavaScript的代码如下:let parent = new Vue({
el: '#app',
data () {
return {
name: 'w3cplus',
age: 7
}
},
components: {
'child': {
template: '#child',
props: ['myName', 'myAge'],
data () {
return {
childMyName: this.myName,
childMyAge: this.myAge
}
},
watch: {
childMyName: function (val) {
this.$emit('update:my-name', val)
},
childMyAge: function (val) {
this.$emit('update:my-age', val)
}
}
}
}
})最终效果如下:
上面的示例效果,不管是修改父组件的数据还是子组件的数据,都会相互影响:
因为子组件中
props的
myName和
myAge不可写,所以在
data中创建一个副本
childMyName和
childMyAge。初始值为
props属性
myName和
myAge的值,同时在组件内所有需要调用
props的地方调用
data中的
childMyName和
childMyAge。components: {
'child': {
template: '#child',
props: ['myName', 'myAge'],
data () {
return {
childMyName: this.myName,
childMyAge: this.myAge
}
},
...
}
}接下来在子组件中通过
watch来对
props属性的
myName和
myAge进行监听。当
props修改后对应
data中的副本
childMyName和
childMyAge也要同步数据。...
watch: {
childMyName: function (val) {
this.$emit('update:my-name', val)
},
childMyAge: function (val) {
this.$emit('update:my-age', val)
}
}
...接下来要做的事情就是当组件内的
props属性发生变化时,需要向组件外(父组件)发送通知,通知组件内属性变更,然后由外层(父组件)自己来决定是否变更他的数据。接下来我们按上面的方案来改造上一节示例中的switch按钮。
至此,实现了组件内部数据与组件外部的数据的双向绑定,组件内外数据的同步。简而言之:组件内部自已变了告诉外部,外部决定要不要变更。
什么样的props
适合做双向绑定
事实上,在Vue中,双向绑定的props是不利于组件间的数据状态管理,尤其是较为复杂的业务当中,因此在实际项目中应该尽量少用双向绑定,过于复杂的数据处理,建议使用Vuex。但很多时候又避免不了使用双向绑定。那么什么场景之下使用
props来做双向绑定呢?如果在你的项目中,同时满足下面的条件时,我们就可以考虑使用
props来做双向绑定:组件内部需要修改
props
组件需要可以由外部在运行时动态控制,而非单纯的初始化
组件父部需要读取组件内的状态来进行处理
虽然上面的示例展示了我们怎么在Vue 2.0中实现
props的双向绑定,但如果项目中有更多这样的双向绑定,那么就会让你做一些重复的事情,而且代码也很冗余,事情也会变得复杂。为了改变这样的现象,可以借助Vue的
mixin来自动化处理
props的双向绑定的需求。不过在这节中,我们不会学习这方面的知识,后面我们在学习
mixin时,可地再回过头来实现这样的功能。在Vue中除了上述介绍的组件通讯之外,还有其他一些方法,在下一节中,咱们将会继续学习这方面的知识。
文章涉及到图片和代码,如果展示不全给您带来不好的阅读体验,欢迎点击文章底部的 阅读全文。如果您觉得小站的内容对您的工作或学习有所帮助,欢迎关注此公众号。
W3cplus.com————————————记述前端那些事,引领web前沿
长按二维码,关注W3cplus▼
相关文章推荐
- 【学习笔记】Vue中实现双向数据绑定的原理
- Vue2.0源码阅读笔记--双向绑定实现原理
- 【VUE】.NET实现Tree组件双向绑定数据(1)
- 【VUE】.NET实现Tree组件双向绑定数据(2)
- vue父组件和子组件通过sync实现双向数据绑定
- Vue.js第一天学习笔记(数据的双向绑定、常用指令)
- Vue 2.0学习笔记:组件数据传递
- vue2.0数据双向绑定与表单bootstrap+vue组件
- Vue2.0利用 v-model 实现组件props双向绑定的优美解决方案
- Vue.js第一天学习笔记(数据的双向绑定、常用指令)
- 【VUE】.NET实现Tree组件双向绑定数据(3)-资源分配
- Vue2.0源码阅读笔记--双向绑定实现原理
- Vue.js学习笔记: 数据绑定语法---绑定表达式
- vue实现数据双向绑定的原理
- JS学习笔记——AngularJS 1.x双向数据绑定机制
- Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
- Vue.js学习 Item4 -- 数据双向绑定
- Vue.js学习 Item4 -- 数据双向绑定
- vue.js利用defineProperty实现数据的双向绑定
- Angular2学习笔记.4、表单相关,双向数据绑定,HeroForm