理解vue中两个常用语法糖:v-model和.sync

1,144 阅读2分钟

语法糖一:v-model

v-model是vue中最常见的语法糖,我们可以用 v-model 指令在表单 input、textarea 及 select 元素上创建双向数据绑定。

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。

以input为例,如下使用v-model即可实现对input输入框的输入和修改

<el-input v-model="inputValue" placeholder></el-input>
data() {
    return {
      inputValue: "使用v-model的值",
    }
}

如果不使用v-model时,则需要

使用属性value来初始化输入框(input)的值

通过监听input事件修改输入框(input)值的改变

<el-input :value="value" @input="inputChangeHandle"></el-input>
data() {
    return {
      value: "普通的值",
    };
  },
methods: {
    inputChangeHandle(e) {
      this.value = e;
    }
}

语法糖二:.sync修饰符

sync修饰符常用于父子组件之间的传参,由于vue是单向数据流,父组件可以修改子组件数据,但子组件中的数据改变则需要通知父组件进行修改,以便追踪数据变化。sync的作用就是方便子组件通知父组件修改数据的语法糖。

需求如下,子组件默认隐藏,当点击父组件按钮时,显示子组件,且子组件可以通过组件内的按钮,点击关闭自身(类似于弹框功能)

父组件中:
<el-button type="primary" @click="visible=true">sync点击测试</el-button>
<test :visible.sync="visible"></test3>

import test from "@/views/shop/comment/test.vue";
export default {
  components: {
    test
  },
  data() {
    return {
      visible: false
    };
  },
 }
 
 
子组件:
<div style="width:50%;heigth:300px" v-if="visible">
  <p>这是子组件的内容</p>
  <el-button type="primary" @click="closeHandle">关闭</el-button>
</div>
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    closeHandle() {
      this.$emit("update:visible", false);
    }
  }
};

代码的核心是父组件中引用子组件时使用:visible.sync="visible"

子组件在点击关闭按钮是通过this.$emit("update:visible", false),通知父组件修改visible的值

但是,我们可以看到,父组件中并没有监听对应的事件处理visible, 那他是怎么实现的呢,其实.sync是 :visible="isValue 和@update:visible="isValue = $event"的语法糖,普通写法如下:

父组件:
<el-button type="primary" @click="isValue=true">普通弹框点击</el-button>
<test :visible="isValue" @update:visible="isValue = $event"></test>

import test from "@/views/shop/comment/test.vue";
export default {
  components: {
    test,
  },
  data() {
    return {
      isValue: false,
    };
  },
 }
 
 子组件:
<div style="width:50%;heigth:300px" v-if="visible">
    <p>子组件的内容</p>
    <el-button type="primary" @click="closeHandle">关闭</el-button>
</div>

export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    closeHandle() {
       this.$emit("update:visible", false);
    }
  }
};

或者如下,其实就是子组件点击关闭后通知父组件修改isValue值

父组件:
<el-button type="primary" @click="isValue=true">普通弹框点击</el-button>
<test :visible="isValue" @update="updateHandle"></test>

 methods: {
    updateHandle(value) {
      this.isValue = value;
    },
 }
 
子组件:
<el-button type="primary" @click="closeHandle">关闭</el-button>
 methods: {
    closeHandle() {
      this.$emit("update", false);
    }
  }