这是我参与新手入门的第2篇文章
前文写了深入学习v-model的学习,今天分享下组件上v-model实现vue3.x与vue2.x的区别在哪。
前序
上文讲了v-model是v-bind和v-on的结合体如下:
<!-- v-model -->
<input type="text" v-model="value">
<!-- v-bind 和 v-on -->
<input type="text" :value="value" @input="value = $event.target.value">
复制代码
这两行代码实现的功能是相同的。
正篇
vue2.x 未与model选项的结合
我们先写一个son
组件:
<template>
<div class="son">
<!-- 这里的v-bind="$attrs"是继承了其他各位的attribute(属性) 这里: type='text' -->
<input v-bind="$attrs" :value="value" @input="update">
</div>
</template>
<script>
export default {
props: {
value: {
type: String
}
},
methods: {
update(e) {
this.$emit('input', e.target.value)
}
},
}
</script>
复制代码
父组件使用子组件实现v-model:
<template>
<div class="parent">
<!-- type='text' 通过 v-bind="$attrs" 传给了input -->
<son type='text' v-model="value"></son>
</div>
</template>
<script>
import son from './son.vue'
export default {
components: {
son
},
data() {
return {
value: 'false'
}
},
}
</script>
复制代码
vue2.x与model选项的结合
是不是以为前面就结束了,不!还有内容。前面说v-model是v-bind和v-on的结合,当我们把input类型改成checkbox是后你会发现是没有实现数据的双向绑定。
更改代码
<template>
<div class="son">
<!-- 这里的v-bind="$attrs"是继承了其他各位的attribute(属性) -->
<input v-bind="$attrs" :checked="value" @change="update">
</div>
</template>
<script>
export default {
props: {
value: {
type: Boolean
}
},
methods: {
update(e) {
this.$emit('change', e.target.checked)
}
},
}
</script>
<template>
<div class="parent">
<!-- type='text' 通过 v-bind="$attrs" 传给了input -->
<son type='checkbox' v-model="value"></son>
</div>
</template>
<script>
import son from './son.vue'
export default {
components: {
son
},
data() {
return {
value: false
}
},
}
</script>
复制代码
这里为什么不能实现呢?
原因
:因为v-model是v-bind和v-on的结合默认v-bind是绑定的value,v-on是绑定input事件,在第一个代码中input类型为text时候value和input正好对应上去,然后在类型为checkbox的绑定值为checked与change,因此无效。
注意点:
text和textarea元素使用value属性和input事件
checkbox和radio使用checked属性和change事件
select使用value和change事件
因此在vue2.2新增了model选项。如此就可以更改v-model它们的默认项:
<template>
<div class="son">
<!-- 这里的v-bind="$attrs"是继承了其他各位的attribute(属性) -->
<input v-bind="$attrs" :checked="value" @change="update">
</div>
</template>
<script>
export default {
model: {
prop: 'value',
event: 'change'
},
props: {
value: {
type: Boolean
}
},
methods: {
update(e) {
this.$emit('change', e.target.checked)
}
},
}
</script>
复制代码
此处只给子组件代码,父组件的代码还是前面一个,未进行修改。
vue3.x的实现
由于之前所说v-model结合.sync修饰符的特点因此就无需model的选项,此处只贴上checkbox类型的代码。
son:
<template>
<input type="checkbox" :checked="modelValue" @change="change" >
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
props: {
modelValue: {
type: Boolean
}
},
setup(props, context) {
const change = (e) => {
// 这里再扯下使用'update:modelValue'是生成了@update:modelValue的事件
context.emit('update:modelValue', e.target.checked)
}
return {
change
}
}
})
</script>
复制代码
parent:
<template>
<div>
{{ value }}
<son v-model="value"></son>
</div>
</template>
<script lang='ts'>
import { ref } from 'vue'
import son from './son.vue';
export default {
components: {
son
},
setup() {
const value = ref(false)
return {
value
}
},
}
</script>
复制代码
总结
-
vue2.x的v-model默认绑定的是
value值
和input事件
-
vue2.x改变默认值与事件使用
model选项
-
vue3.x 由于
结合.sync
因此可以直接更改,因为生成对应的事件。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END