Vue3中的v-model

1、v-model

Vue2

Vue2中得 v-model 默认解析成 :value 与 @input

原理实现

:

html 复制代码
<template>
  <div>
    {{ count }}
    <button @click="count++">+1</button>
    <hr />
    <HelloWorld :value="count" @input="count = $event"></HelloWorld>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data() {
    return { count: 0 };
  }
};
</script>

<style></style>

:

html 复制代码
<template>
  <div>
    {{ value }}
    <button @click="$emit('input', value + 1)">+1</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    value: Number,
  },
};
</script>
<style scoped></style>

语法糖实现

:

html 复制代码
<template>
  <div>
    {{ count }}
    <button @click="count++">+1</button>
    <hr />
    <HelloWorld v-model="count" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data() {
    return { count: 0 };
  }
};
</script>

<style></style>

:

html 复制代码
<template>
  <div>
    {{ value }}
    <button @click="$emit('input', value + 1)">+1</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    value: Number,
  },
};
</script>
<style scoped></style>

Vue3

Vue3中得 v-model 默认解析成 :modelValue 与 @update:modelValue

原理实现

:

html 复制代码
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
</script>

<template>
  <div>
    {{ count }}
    <button @click="count++">+1</button>
    <hr />
    <HelloWorld
      :modelValue="count"
      @update:modelValue="count = $event"
    ></HelloWorld>
  </div>
</template>

<style lang="scss" scoped></style>

:

html 复制代码
<script setup lang="ts">
defineProps<{
  modelValue: number
}>()
defineEmits<{
  (e: 'update:modelValue', newCount: number): void
}>()
</script>

<template>
  <div>
    {{ modelValue }}
    <button @click="$emit('update:modelValue', modelValue + 1)">+1</button>
  </div>
</template>

<style lang="scss" scoped></style>

语法糖实现

html 复制代码
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
</script>

<template>
  <div>
    {{ count }}
    <button @click="count++">+1</button>
    <hr />
    <HelloWorld v-model="count"></HelloWorld>
  </div>
</template>

<style lang="scss" scoped></style>

:

html 复制代码
<script setup lang="ts">
defineProps<{
  modelValue: number
}>()
defineEmits<{
  (e: 'update:modelValue', newCount: number): void
}>()
</script>

<template>
  <div>
    {{ modelValue }}
    <button @click="$emit('update:modelValue', modelValue + 1)">+1</button>
  </div>
</template>

<style lang="scss" scoped></style>

2、 .sync

Vue2

Vue2中得 :attr.sync 默认解析成 :attr 与 @update:attr

原理实现

html 复制代码
<template>
  <div>
    {{ count }}
    <button @click="count++">+1</button>
    <hr />
    <HelloWorld :count="count" @setCount="count = $event" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data() {
    return { count: 0 };
  }
};
</script>

<style></style>

html 复制代码
<template>
  <div class="hello">
    {{ count }}
    <button @click="$emit('setCount', count + 1)">+1</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    count: Number,
  },
};
</script>
<style scoped></style>

语法糖实现

html 复制代码
<template>
  <div>
    {{ count }}
    <button @click="count++">+1</button>
    <hr />
    <HelloWorld :count.sync="count" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data() {
    return { count: 0 };
  }
};
</script>

<style></style>

html 复制代码
<template>
  <div class="hello">
    {{ count }}
    <button @click="$emit('update:count', count + 1)">+1</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    count: Number,
  },
};
</script>
<style scoped></style>

Vue3

Vue3中得 v-model:attr 默认解析成 :attr 与 @update:attr

原理实现

:

html 复制代码
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
</script>

<template>
  <div>
    {{ count }}
    <button @click="count++">+1</button>
    <hr />
    <HelloWorld :count="count" @setCount="count = $event"></HelloWorld>
  </div>
</template>

<style lang="scss" scoped></style>

:

html 复制代码
<script setup lang="ts">
defineProps<{
  count: number
}>()
defineEmits<{
  (e: 'setCount', newCount: number): void
}>()
</script>

<template>
  <div>
    {{ count }}
    <button @click="$emit('setCount', count + 1)">+1</button>
  </div>
</template>

<style lang="scss" scoped></style>

语法糖实现

:

html 复制代码
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
</script>

<template>
  <div>
    {{ count }}
    <button @click="count++">+1</button>
    <hr />
    <HelloWorld v-model:count="count"></HelloWorld>
  </div>
</template>

<style lang="scss" scoped></style>

:

html 复制代码
<script setup lang="ts">
defineProps<{
  count: number
}>()
defineEmits<{
  (e: 'update:count', newCount: number): void
}>()
</script>

<template>
  <div>
    {{ count }}
    <button @click="$emit('update:count', count + 1)">+1</button>
  </div>
</template>

<style lang="scss" scoped></style>

3、总结

Vue2中得 v-model 默认解析成 :value 与 @input

Vue3中得 v-model 默认解析成 :modelValue 与 @update:modelValue


Vue2中得 :attr.sync 默认解析成 :attr 与 @update:attr

Vue3中得 v-model:attr 默认解析成 :attr 与 @update:attr


作用:用于在自定义组件中实现父子组件之间的双向数据绑定

也就是说在Vue3中只有v-model,没有.sync

如果父组件只写v-model="xxx",子组件中接收到的props为modelValue ,抛出的自定义事件为update:modelValue

如果父组件写v-model:attr="xxx" (attr为自定义变量),子组件中接收到的props为attr ,抛出的自定义事件为update:attr

即:Vue3中使用双向数据绑定v-model时props不局限于只能接收modelValue,可以自定义

使用方式:

ts 复制代码
父: 
<HelloWorld v-model="count"></HelloWorld>

子:
defineProps<{
  modelValue: number
}>()
defineEmits<{
  (e: 'update:modelValue', newCount: number): void
}>()
$emit('update:modelValue', modelValue + 1)"

=====================================================================================

父:
<HelloWorld v-model:count="count"></HelloWorld>

子:
defineProps<{
  count: number
}>()
defineEmits<{
  (e: 'update:count', newCount: number): void
}>()
$emit('update:count', count + 1)">
相关推荐
Ashley的成长之路1 小时前
前端性能优化实战手册·第2篇:资源加载策略全解
前端·性能优化·资源加载·http/3·性能优化实战·资源加载优化
浅水壁虎1 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥1 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
Getflare1 小时前
前端 + UI 设计 + AI:这不是三个工种,是一个新三角能力模型(附自检清单)
前端·人工智能·ui
oil欧哟1 小时前
我做了一个 Vibe Coding 术语学习站:VibeHub
前端·ai·agent·独立开发·vibe coding
审小匠OpenCPAi2 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution612 小时前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化
mONESY2 小时前
React useState 核心原理与最佳实践:从异步更新到性能优化全解
javascript
腻害兔3 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程