当前位置: 首页 > news >正文

vue2组件之间双向数据绑定问题

最近在使用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)

转载于:https://www.cnblogs.com/summer7310/p/7756533.html

相关文章:

  • IO(字节流、字符流)
  • Linux环境安装docker
  • 康复者的福音来了,只要穿上这款机器人外骨骼便能自由转身
  • Linux系统的数据写入机制--延迟写入
  • 它改变了整个扫地机器人行业,如今被全面收购
  • Day16 Django
  • Paros proxy:网页程序漏洞评估代理
  • HTML 5 Web 存储-sessionStorage和localStorage
  • 使用Prometheus监控Cloudflare的全球网络
  • 歌词显示控件的实现下——自定义View
  • [内核驱动] miniFilter 内核层与应用程序通信
  • 关于form表单input text 未绑定回车事件跳转问题
  • Android照片墙完整版,完美结合 内存方案 LruCache 和 硬盘方案 DiskLruCache
  • CentOS 7下搭建LAMP并把MySQL单独分离
  • Elasticsearch集群如何扩容机器?
  • 「面试题」如何实现一个圣杯布局?
  • 【刷算法】求1+2+3+...+n
  • canvas绘制圆角头像
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • codis proxy处理流程
  • create-react-app项目添加less配置
  • JavaWeb(学习笔记二)
  • k8s 面向应用开发者的基础命令
  • laravel with 查询列表限制条数
  • PAT A1092
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Python爬虫--- 1.3 BS4库的解析器
  • sessionStorage和localStorage
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • 搞机器学习要哪些技能
  • 技术发展面试
  • 如何设计一个微型分布式架构?
  • 线性表及其算法(java实现)
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 终端用户监控:真实用户监控还是模拟监控?
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 树莓派用上kodexplorer也能玩成私有网盘
  • #if 1...#endif
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (06)Hive——正则表达式
  • (2)MFC+openGL单文档框架glFrame
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (C语言)逆序输出字符串
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (实战篇)如何缓存数据
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (四)Linux Shell编程——输入输出重定向
  • (推荐)叮当——中文语音对话机器人
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .describe() python_Python-Win32com-Excel
  • .NET 8.0 发布到 IIS
  • .Net Core缓存组件(MemoryCache)源码解析
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!