最近看到vue版本更新到3.4.x了,其中有个defineModel API,defineModel在3.3的时候是作为实验特性发布的,在3.4中逐渐稳定。这个API就是Vue3简化组件v-model的写法的,所以这篇就一块儿来总结一下vue中的组件v-model
目录
?先说下vue2中的使用,再说下vue3中的使用
下面这个单个v-model中,默认是向子组件传递的value属性,子组件接受value获取到父组件的值,通过$emit发送input事件更新该值。也可以通过配置model修改接受的字段名称和事件名称,具体看如下代码
父组件示例:?
<template>
? <div class="mytest">
? ? <div>父组件的name:{{ name }}</div>
? ? <Child v-model="name" />
? </div>
</template>
<script>
import Child from './child.vue'
export default {
? data() {
? ? return {
? ? ? name: 'WFT'
? ? }
? },
? components: { Child }
}
</script>
?子组件示例:?
<template>
? <div class="child">
? ? <div>我是子组件</div>
? ? <el-input v-model="name" placeholder="请输入内容"></el-input>
? </div>
</template>
<script>
export default {
? model: {
? ? prop: 'value', // 默认就是value
? ? event: 'input' // 默认就是input
? },
? props: {
? ? value: {
? ? ? type: String,
? ? ? default: ''
? ? }
? },
? computed: {
? ? name: {
? ? ? get() {
? ? ? ? return this.value
? ? ? },
? ? ? set(val) {
? ? ? ? this.$emit('input', val)
? ? ? }
? ? }
? }
}
</script>
多个v-model绑定,通过.sync传递,子组件可以通过传递的对应名称接受、通过$emit发送update:名称的事件方式更新对应的父组件中的值
父组件示例:
<template>
? <div class="mytest">
? ? <div>父组件的name:{{ name }}</div>
? ? <div>父组件的age:{{ age }}</div>
? ? <Child :name.sync="name" :age.sync="age" />
? </div>
</template>
<script>
import Child from './child.vue'
export default {
? data() {
? ? return {
? ? ? name: 'WFT',
? ? ? age: 18
? ? }
? },
? components: { Child }
}
</script>
?子组件示例:
<template>
? <div class="child">
? ? <div>我是子组件</div>
? ? <el-input v-model="propName" placeholder="请输入内容"></el-input>
? ? <el-input v-model.number="propAge" placeholder="请输入内容"></el-input>
? </div>
</template>
<script>
export default {
? props: {
? ? name: {
? ? ? type: String,
? ? ? default: ''
? ? },
? ? age: {
? ? ? type: Number,
? ? ? default: 0
? ? }
? },
? computed: {
? ? propName: {
? ? ? get() {
? ? ? ? return this.name
? ? ? },
? ? ? set(val) {
? ? ? ? this.$emit('update:name', val)
? ? ? }
? ? },
? ? propAge: {
? ? ? get() {
? ? ? ? return this.age
? ? ? },
? ? ? set(val) {
? ? ? ? this.$emit('update:age', val)
? ? ? }
? ? }
? }
}
</script>
Vue3中介绍单个v-model绑定和多个v-model绑定中的传统方式和defineModel方式
defineModel是一个新的<script setup>宏,旨在简化支持v-model的组件的实现。它以前在3.3.x中作为实验特性发布,并在3.4.x中逐渐稳定。它现在为使用v-model修饰符提供了更好的支持。无需引入,直接使用即可,同defineProps、defineEmits
父组件示例:
<template>
? <div class="wft-projects">
? ? <div>父组件的name:{{ name }}</div>
? ? <Child v-model="name" />
? </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Child from './child.vue'
?
const name = ref('WFT')
?
</script>
子组件示例:
<template>
? <div class="child">
? ? <h3>我是子组件</h3>
? ? <el-input v-model="propName"></el-input>
? </div>
</template>
<script setup lang='ts'>
import { computed } from 'vue'
?
const props = withDefaults(defineProps<{
? modelValue?: string
}>(), {
? modelValue: '哈哈'
})
?
const emits = defineEmits<{
? (e: 'update:modelValue', params: string): void
}>()
?
const propName = computed({
? get() {
? ? return props.modelValue
? },
? set(val) {
? ? emits('update:modelValue', val)
? }
})
</script>
父组件示例:
同传统方式
<template>
? <div class="wft-projects">
? ? <div>父组件的name:{{ name }}</div>
? ? <Child v-model="name" />
? </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Child from './child.vue'
?
const name = ref('WFT')
?
</script>
子组件示例:
<template>
? <div class="child">
? ? <h3>我是子组件</h3>
? ? <el-input v-model="propName"></el-input>
? </div>
</template>
<script setup lang='ts'>
?
const propName = defineModel<string>('modelValue', { default: 'default value' })
?
</script>
使用defineModel真的是简化了太多代码,使用很方便?
传统方式
父组件示例:
<template>
? <div class="wft-projects">
? ? <div>父组件的name:{{ name }}</div>
? ? <div>父组件的age:{{ age }}</div>
? ? <Child v-model:name="name" v-model:age="age" />
? </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Child from './child.vue'
?
const name = ref('WFT')
const age = ref(18)
?
</script>
子组件示例:
<template>
? <div class="child">
? ? <h3>我是子组件</h3>
? ? <el-input v-model="propName"></el-input>
? ? <el-input v-model.number="propAge"></el-input>
? </div>
</template>
<script setup lang='ts'>
import { computed } from 'vue'
?
const props = withDefaults(defineProps<{
? name?:string,
? age?: number
}>(), {
? name: 'default name',
? age: 0
})
?
const emits = defineEmits<{
? (e: 'update:name', params: string): void
? (e: 'update:age', params: number): void
}>()
?
const propName = computed({
? get() {
? ? return props.name
? },
? set(val) {
? ? emits('update:name', val)
? }
})
const propAge = computed({
? get() {
? ? return props.age
? },
? set(val) {
? ? emits('update:age', val)
? }
})
?
</script>
父组件示例:
同传统方式
<template>
? <div class="wft-projects">
? ? <div>父组件的name:{{ name }}</div>
? ? <div>父组件的age:{{ age }}</div>
? ? <Child v-model:name="name" v-model:age="age" />
? </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Child from './child.vue'
?
const name = ref('WFT')
const age = ref(18)
?
</script>
子组件示例:?
<template>
? <div class="child">
? ? <h3>我组件</h3>
? ? <el-input v-model="propName"></el-input>
? ? <el-input v-model.number="propAge"></el-input>
? </div>
</template>
<script setup lang='ts'>
?
const propName = defineModel<string>('name', { default: 'default name' })
const propAge = defineModel<number>('age', { default: 0 })
?
</script>
————————————————
版权声明:本文为CSDN博主「会说法语的猪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_51431448/article/details/135523213