美文网首页
vue props 双向数据绑定 (computed不计算对象属

vue props 双向数据绑定 (computed不计算对象属

作者: 郝小淞 | 来源:发表于2017-04-28 19:22 被阅读0次

    前言
    在vue是实际工作中碰到一个问题,就是props传递的数据在组件内无法修改,好奇一下其中的问题

    props描述

    在Vue2中组件的props的数据流动改为了只能单向流动,即只能由组件外(调用组件方)通过组件的DOM属性attribute传递props给组件内,组件内只能被动接收组件外传递过来的数据,并且在组件内,不能修改由外层传来的props数据。

    图片.png

    不能修改props是值不能直接修改props传递的对象。但有一种情况下是特例(实际不是很严谨的特例),修改props数据的对象。

    props传递的数据类型为Object

    export default {
      name:'demo',
      props:['pData'] 
    }
    

    如果pData是Number/String等类型的数据,直接修改Vue会报错,但是如果pData是Object类型的数据,虽然不能直接修改pData的指向,但是可以修改pData的属性,来间接达到数据绑定。

    这样,子组件改变pData的属性,父组件也会同步。原理是,javascript中Object对象对应的是内存地址,当对象的属性改变时,对象的内存地址是不变的。

    computed会对属性进行深度的计算,属性发生改变也会改变的。

    但是还有一种情况要特殊看待,当父组件传递的props对象在子组件要操作一个不存在的属性时,这种情况父类和子类都不会发生变更触发。
    原理:Vue会对内部数据对象进行getter/setter处理,方便自己监听变化,不存在的属性直接添加是不会转换成vue需要的对象。
    解决:将不存在的数据通过Vue.set()或者this.$set()进行转化。

    // 截取饿了吗cartcontrol组件代码
    /*
      传递过来的props中的food是某一商品的json数据
      其中不存在用户选择的数量(count数据)
      即:food.count 等于 undefined
    */
    export default{
        name:'cartcontrol',
        props:{
          food:{
            type:Object
          }
        },
        methods: {
          add() {
            //  增加一个数量
            if(this.food.count){
              this.food.count += 1
            }else{
              /*
               因为本身不存在count数据,
               如果直接修改如:this.food.count = 1会存在上述问题
               (无法显示,无法computed,无法与父类双向绑定)
               所以要先this.$set(this.food,'count',1),将属性转化getter/setter形式
               转换之后对这个属性操作都可以进行直接修改
             */
              this.$set(this.food,'count',1)
            }
          },
          remove() {
            //  减少一个数量
            if(this.food.count || this.food.count>1){
              this.food.count -= 1;
            }else{
              this.food.count = 0;
            }
          }
        },
        mounted:function () {
    
        }
      }
    

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

    使用data副本存储props

    如何处理props数据双向绑定

    链接:如何在Vue2中实现组件props双向绑定

    v-model进行双向绑定

    最近看了一些Vue2的双向绑定的方法,看到v-model来解决的方法。

    方法实际同理上一条,v-model是vue封装的一个类似语法糖的东东。实际会被解析成为

      <div v-model='something'></div>
      //转换为
      <div :val='something' @input='something= $event.target.value '></div>
    
    
    
    <template>
      <div class="modal" :value="value" v-show="visible">
          <div class="close" @click="cancel">X</div>
      </div>
    </template>
    
    <script>
    export default {
        props: {
          value: {
            type: Boolean,
            default:false
          }
        },
    
      data () {
        return {
          visible:false
        }
      },
      watch:{
          value(val) {
            console.log(val);
            this.visible = val;
          },
          visible(val) {
            this.$emit('input', val);
          }
      },
      methods:{
        cancel(){
          this.visible = false;
        }
      },
      mounted() {
        if (this.value) {
          this.visible = true;
        }
      }
    }
    </script>
    
    
    

    computed不会去计算没有被vue格式化处理的数据

    相关文章

      网友评论

          本文标题:vue props 双向数据绑定 (computed不计算对象属

          本文链接:https://www.haomeiwen.com/subject/fssazttx.html