关于Vue2中使用computed来保存v-model中数据的一种方法

231 阅读1分钟

前置知识

  1. 一般可以在模板中直接使用,父组件传递过来的props属性,视图能够得到更新。
  2. 如果模板中的变量与v-model绑定,则因为单向数据流的原因,不能在子组件里面修改自身的props属性值。因此,可以将v-model 中的变量,绑定到data 变量上,也可以直接使用computed 来保存props属性.

使用computed属性来保存v-model中数据的实现原理

在computed 属性中,定义一个get 方法,返回一个Proxy代理对象,对props中的属性进行代理,当属性值变化的时候,emit 值到父组件,通过父组件的属性值的变化,来更新子组件,这样子就保证了单向数据流。

代码实例

vue2.x 中子组件的代码如下所示:

<template>
  <div class="props-test">
    Hello, {{ getNameStr }} 
    <el-input v-model="modelValue.text" />
    <button @click="modelValue.text =null;">更改text值</button>
    <el-select v-model="modelValue.select">
      <el-option label="AA" value="1"></el-option>
      <el-option label="BB" value="2"></el-option>
      <el-option label="CC" value="3"></el-option>
    </el-select>    
  </div>
</template>

<script>
export default {
  props: {
    nameStr: {
      type: [String, Array],
      default: 'success',
    },
    form: {
      select: '3',
      text: 'Success!',
    },
  },
  created() {
    // this.fetchName();
  },
  computed: {
    // computed 可以做解构赋值 
    getNameStr({ nameStr }) {
      return "SUCCESS, " + nameStr;
    },
    modelValue: {
      get() {
        const _self = this;
        return new Proxy(this.form, {
          set(obj, key, val) {
            console.log('obj', obj);
            _self.$emit(`update:form`, {
              ...obj,
              [key]: val
            });
            return true;
          }
        });
      },
    }
  }
}
</script>

父组件调用的例子

<TestPropsDemo :nameStr="testNameStr" :form.sync="form" />
export default {
    data() {
       form: {
        select: '1',
        text: 'Success Haha'
      },
      testNameStr: ['Success'],
    }
}