最近在使用element-ui的dialog组件二次封装成独立组件使用时,子组件需要将关闭dialog状态返回给父组件,简单的说就是要实现父子组件之间的数据双向绑定问题。

大致代码如下:

1,父组件

<template>
<button @click="openDialog">打开弹窗</button>
<dialogCompenent :show="result" :result="result" @dialogData="closeDialog"></dialogCompenent>
</template>
<script type="text/babel">
import dialogCompenent from '/dialogCompenent'
export default {
data () {
return {
result: false
}
},
components: {
dialogCompenent
},
methods: {
openDialog () {
this.result = true
},
closeDialog (data) {
this.result = data
}
}
}
</script>

2,子组件 childCompenent

<template>
<el-dialog
title="弹框组件"
:visible.sync="result"
@open="doOpen"
@close="doClose"
:show="result"
size="tiny">
<div class="content-wrapper">
具体业务代码...
</div>
</el-dialog>
</div>
</template>
<script type="text/babel">
import videoApi from '../../api/videoApi/videoApi'
export default {
name: 'dialogCompenent',
props: {
result: Boolean
},
methods: {
doOpen () {
...
},
doClose () {
this.$emit('dialogData', false)
...
}
}
}
</script>

程序在浏览器上虽然能够正常运行,但是在vue2.0却会报错:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "result" (found in component )

组件内不能修改props的值,同时修改的值也不会同步到组件外层,即调用组件方不知道组件内部当前的状态是什么

这是什么原因造成的呢?

在vue1.x版本中利用props的twoWay和.sync绑定修饰符就可以实现props的双向数据绑定。

在vue2.0中移除了组件的props的双向数据绑定功能,如果需要双向绑定需要自己来实现。

在vue2.0中组件的props的数据流动改为了只能单向流动,即只能由(父组件)通过组件的v-bind:attributes传递给(子组件),子组件只能被动接收父组件传递过来的数据,并在子组件内不能修改由父组件传递过来的props数据。

官方文档解释:

prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。

虽然废弃了props的双向绑定对于整个项目整体而言是有利且正确的,但是在某些时候我们确实需要从组件内部修改props的需求

在Vue2.0中,实现组件属性的双向绑定方式

子组件修改:

<template>
<el-dialog
title="弹框组件"
:visible.sync="openStatus"
@open="doOpen"
@close="doClose"
:show="openStatus"
size="tiny">
<div class="content-wrapper">
具体业务代码...
</div>
</el-dialog>
</div>
</template>
<script type="text/babel">
import videoApi from '../../api/videoApi/videoApi'
export default {
name: 'dialogCompenent',
props: {
result: Boolean
},
/*创建一个openStatus变量缓存result数据
*在子组件需要调用result的地方调用data对象openStatus
*/
data () {
return {
openStatus: this.result
}
},
//新增result的watch,监听变更同步到openStatus
//监听父组件对props属性result的修改,并同步到组件内的data属性
watch: {
result (val) {
this.openStatus = val
}
},
methods: {
doOpen () {
...
},
doClose () {
this.$emit('dialogData', false)//子组件对openStatus修改后向父组件发送事件通知
...
}
}
}
</script>

父组件修改:

<template>
<button @click="openDialog">打开弹窗</button>
<dialogCompenent :show="result" :result="result" @dialogData="closeDialog"></dialogCompenent>
</template>
<script type="text/babel">
import dialogCompenent from '/dialogCompenent'
export default {
data () {
return {
result: false
}
},
components: {
dialogCompenent
},
methods: {
openDialog () {
this.result = true
},
closeDialog (data) {
this.result = data//子组件触发父组件事件,进行数据变更,同步result数据
}
}
}
</script>

至此,实现了子组件内数据与父组件的数据的双向绑定,组件内外数据的同步。最后归结为一句话就是:组件内部自己变了告诉外部,外部决定要不要变。

结语

那么为什么vue1.0还有的数据双向绑定在vue2.0版本中反而抛弃了呢,通过上述案例我们也可以发现双向绑定的props代码多,不利于组件间的数据状态管理,尤其是在复杂的业务中更是如此,所以尽量不使用这种方式的双向绑定,过于复杂的数据处理使用vuex来进行数据管理。(https://vuex.vuejs.org/zh-cn/intro.html)

vue2组件之间双向数据绑定问题的更多相关文章

  1. Angular:实现组件间双向数据绑定

    学过Angular的同学都知道,输入框通过[(ngModel)]实现双向数据绑定,那么父子组件间能不能实现双向数据绑定呢?答案是肯定的. Angular中,我们常常需要通过方括号[]和圆括号()实现组 ...

  2. Vue: 一个简单的Vue2.0 v-model双向数据绑定的实现,含源代码,小白也能看懂

    首先说一下原理吧 View层(dom元素)的变动如何响应到Model层(Js变量)呢? 通过监听元素的input事件来动态的改变js变量的值,实际上不是改变的js变量的值,而是改变的js变量的gett ...

  3. vue2.* 事件结合双向数据绑定、模块化以及封装Storage实现todolist 待办事项 已经完成 和进行中持久化 06

    ceshi.vue <template> <div id="app"> <input type='text' v-model='todo' @keyd ...

  4. 组件使用v-model、$listeners、.sync(区别于v-model的双向数据绑定)

    自定义组件 自定义组件的v-model 首先我们先说一下在自定义组件中使用v-model的必要条件 在自定义的组件中要有input(这里我们先不讨论单选复选框) 在自定义组件的模板对象中要有props ...

  5. Angular自定义组件实现数据双向数据绑定

    学过Angular的同学都知道,输入框通过[(ngModel)]实现双向数据绑定,那么自定义组件能不能实现双向数据绑定呢?答案是肯定的. Angular中,我们常常需要通过方括号[]和圆括号()实现组 ...

  6. 7.vue组件(二)--双向绑定,父子组件访问

    本文主要说两件事 1. 如何实现父子组件之间的双向绑定 2. 父组件如何访问子组件的data,method, 子组件如何访问父组件的data,method等 一. 如何实现父子组件之间的双向绑定 案例 ...

  7. Vue2.0父子组件之间的双向数据绑定问题解决方案

    对于vue 1.0项目代码,如果把vue换成vue 2.0,那么之后项目代码就完全奔溃不能运行,vue 2.0在父子组件数据绑定的变化(不再支持双向绑定)颠覆了1.0的约定,很遗憾. 解决方案只有两种 ...

  8. vue3.x自定义组件双向数据绑定v-model

    vue2.x 语法 在 2.x 中,在组件上使用 v-model 相当于绑定 value prop 并触发 input 事件: <ChildComponent v-model="pag ...

  9. 如何在Vue2中实现组件props双向绑定

    Vue学习笔记-3 前言 Vue 2.x相比较Vue 1.x而言,升级变化除了实现了Virtual-Dom以外,给使用者最大不适就是移除的组件的props的双向绑定功能. 以往在Vue1.x中利用pr ...

随机推荐

  1. BZOJ4011:[HNOI2015]落忆枫音(DP,拓扑排序)

    Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题.  「相信吧.不然我们是什么,一团肉吗?要不是有灵魂……我们也 ...

  2. AtCoder Grand Contest

    一句话题解 QwQ主要是因为这篇文章写的有点长……有时候要找某一个题可能不是很好找,所以写了这个东西. 具体的题意.题解和代码可以再往下翻._(:з」∠)_ AGC 001 C:枚举中点/中边. D: ...

  3. 【转】Android单帧动画Rotate旋转

    项目有一个需求,有一个刷新按钮,上面放着一个常见的静止的刷新圆圈,如下图: 一旦用户按了刷新按钮,需要让这个刷新圆圈转动起来,让用户感觉到程序还在运行着,而不是卡死了. 有两个思路,一是将这个图按照旋 ...

  4. Url快捷方式转超链接页

    效果:(打了码  可以感受到效果) 问题: 近期发现了之前的一些网页快捷方式文件有50个  查看起来实在不方便 解决: 目前想到了两种 (书签法) (类书签法) 第一种简单快速 (当然有掌握写技巧) ...

  5. svn安装配置

    1. 安装SVN服务器: 检查是否已安装 # rpm -qa subversion 安装SVN服务器 # yum install httpd httpd-devel subversion mod_da ...

  6. 根据身份证获取地址(mysql)

    e Encoding : Date: :: */ ; -- ---------------------------- -- Table structure for `s_area_code` -- - ...

  7. CssSelector之selenium元素定位

    CssSelector是我最喜欢的元素定位方法,Selenium官网的Document里极力推荐使用CSS locator,而不是XPath来定位元素,原因是CSS locator比XPath loc ...

  8. 【题解】洛谷P1283 平板涂色(搜索+暴力)

    思路 看到n<16 整个坐标<100 肯定想到暴力啊 蒟蒻来一发最简单易懂的题解(因为不会DP哈 首先我们用map数组来存坐标图 注意前面的坐标需要加1 因为输入的是坐标 而我们需要的是格 ...

  9. Java中,如何跳出当前的多重嵌套循环

    在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环.(Java中支持带标签的break和continue语句)

  10. 前端基础-CSS如何布局以及文档流

    一. 网页布局方式 二. 标准流 三. 浮动流 四. 定位流 一. 网页布局方式 1.什么是网页布局方式 布局可以理解为排版,我们所熟知的文本编辑类工具都有自己的排版方式, 比如word,nodpad ...