vue3+ts系列之vue2与vue3中的v-model、.sync

134 阅读1分钟

一、vue2中的v-model

1)父组件
<template>
  <div>
    <h3>父组件</h3>
    <div>num:{{ num }}</div>
    <MySon v-model="num"></MySon>
  </div>
</template>

<script>
import MySon from "./mySon.vue";
export default {
  data() {
    return {
      num: 0,
    };
  },
  components: {
    MySon,
  },
};
</script>
2)子组件
<template>
  <div>
    <h3>子组件</h3>
    <div>num:{{ num }}</div>
    <button @click="handleAdd">点我++</button>
  </div>
</template>

<script>
export default {
  props: {
    num: {
      type: Number,
    },
  },
  // v-model 默认
  //      值:value
  //    事件:input
  // 通过 model 进行修改
  model: {
    prop: "num",
    event: "handleChange",
  },
  methods: {
    handleAdd() {
      this.$emit("handleChange", this.num + 1);
    },
  },
};
</script>

二、vue2中的.sync

1)父组件
<template>
  <div>
    <h3>父组件</h3>
    <div>num:{{ num }}</div>
    <!-- 使用 .sync 关键词进行响应式 -->
    <MySon :num.sync="num"></MySon>
  </div>
</template>

<script>
import MySon from "./mySon.vue";
export default {
  data() {
    return {
      num: 0,
    };
  },
  components: {
    MySon,
  },
};
</script>

<style scoped></style>

2)子组件
<template>
  <div>
    <h3>子组件</h3>
    <div>num:{{ num }}</div>
    <button @click="handleAdd">点我++</button>
  </div>
</template>

<script>
export default {
  props: {
    num: {
      type: Number,
    },
  },
  methods: {
    handleAdd() {
      // .sync 采用 update:xxx 进行事件触发
      this.$emit("update:num", this.num + 1);
    },
  },
};
</script>

<style scoped></style>

三、vue3中的v-model

  1. 父组件 传参 改为 modelValue
  2. 子组件 接参 改为 modelValue
  3. 子组件 触发事件 改为 update:modelValue
  4. 父组件 接收事件 改为 @update:modelValue
  5. 父组件中 可以进行简写 v-model
1)父组件
// 父组件

<template>
  <div>
    <h3>父组件</h3>
    <div>{{ num }}</div>
    <!-- <MySon :modelValue="num" @update:modelValue="num = $event" /> -->
    <!-- 简写 -->
    <MySon v-model="num"></MySon>
  </div>
</template>

<script setup lang="ts">
import MySon from "./mySon.vue";
import { ref } from "vue";

const num = ref(0);
</script>


2)子组件 mySon.vue
// 子组件 mySon.vue

<template>
  <div>
    <h3>子组件</h3>
    <div>{{ modelValue }}</div>
    <button @click="handleAdd">点我num++</button>
  </div>
</template>

<script setup lang="ts">
const props = defineProps<{
  modelValue: number;
}>();
const emits = defineEmits<{
  (e: "update:modelValue", num: number): void;
}>();
const handleAdd = () => {
  emits("update:modelValue", props.modelValue + 1);
};
</script>


四、vue3中的.sync

父组件 传参 使用 v-model:xxx="xxx"

1)父组件
<template>
  <div>
    <h3>父组件</h3>
    <div>{{ num }}</div>
    <!-- .sync -->
    <!-- <MySon v-model="num" :car="car" @handleChange="car = $event"></MySon> -->
    <!-- <MySon v-model="num" :car="car" @update:car="car = $event"></MySon> -->
    <!-- 简写 -->
    <MySon v-model="num" v-model:car="car"></MySon>
  </div>
</template>

<script setup lang="ts">
import MySon from "./mySon.vue";
import { ref } from "vue";

const num = ref(0);
const car = ref("公交车");
</script>
2)子组件
// 子组件 mySon.vue

<template>
  <div>
    <h3>子组件</h3>
    <div>{{ modelValue }}</div>
    <button @click="handleAdd">点我num++</button>
    <div>car:{{ car }}</div>
    <button @click="handleChange">点我修改car</button>
  </div>
</template>

<script setup lang="ts">
const props = defineProps<{
  modelValue: number;
  car: string;
}>();
const emits = defineEmits<{
  (e: "update:modelValue", num: number): void;
  // (e: "handleChange", car: string): void;
  (e: "update:car", car: string): void;
}>();
const handleAdd = () => {
  emits("update:modelValue", props.modelValue + 1);
};
const handleChange = () => {
  // emits("handleChange", "宝马");
  emits("update:car", "宝马");
};
</script>

五、总结

  • vue2
    • v-model
      • 默认子组件传参为 value,事件触发为 input
      • 可以通过model:{ prop: xxx, event: xxx }进行修改
    • .sync
      • 默认子组件传参可以自定义,如xxx,事件触发为 update:xxx
  • vue3
    • v-model
      • 默认子组件传参为 modelValue,事件触发为 update:modelValue
    • .sync
      • 父组件为 v-model:xxx
      • 默认子组件传参可以自定义,如xxx,事件触发为 update:xxx
即:vue3中将vue2的v-model和.sync进行整合了