zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    linux内核中的subsys_initcall是干什么的?
    linux内核中的MFD子系统
    linux内核中有哪些子系统(框架)呢?
    软件架构师书籍
    求最大公约数和最小公倍数
    写一个函数判断字符串中"{"与"}","["与"]","("与")"匹配,"{"必须在"}"前面,"["必须在"]"前面,"("必须在")"前面,可以嵌套
    请用程序写出冒泡排序算法,并做相应改进使得排序效率更高
    50个必备的实用jQuery代码段+ 可以直接拿来用的15个jQuery代码片段
    js同比例缩放图片
    oracle 10g函数大全--其他函数
  • 原文地址:https://www.cnblogs.com/summer7310/p/7756533.html
Copyright © 2011-2022 走看看