模板变化
# 模板变化
v-model的变化
v-model修饰符
我们先来看 v-model 的变化,以前我们可以通过特定的方式定义组件来使用 v-model 简化代码,如果想要定义第二个 v-model 是无法实现的,只能通过属性定义修饰符(如::value.sync)来替代这个方式,但是啊 这两种方式虽然看上去不同,但是实现是一样的。所以 vue3 中作者就二选其一去掉了其中一个。
v-model 的变化
v-model实质
<ChileComp :value @input="value=$event" />
简写为
<ChileComp v-model:value />
何为 v-model 就是定义一个 props 和 一个 事件 然后 通过事件修改 props值
这是我们以前的做法
然而 Vue3 觉得 两种方法有些重复就删掉了修饰符替代的那种
大体上还是没变
也是定义一个 props 和 一个事件 只不过 默认情况下,props 是 modelValue,然后我们要修改的是 modelValue 的值 所以事件为 update:modelValue.
father
<v-modal-test v-for="item in dateRef" :key="item.id" v-model="item.status" />
child
<template> <input type="checkbox" :checked="modelValue" @change="handleChange" /> </template> <script> export default { props: { modelValue: Boolean, update: Function, }, }; </script>
继续,
我们通过定义的 handleChange 事件拿到 event.target.checked 这个 checkbox 的值后怎么来触发父组件的事件呢? 以前是通过 this.$emit 但是现在没有 this 了
setup 存在两个参数
params1:props 这个属性指向的是我们的 props
Params2:这个属性是一些组件内置函数 这里面有emit、slots、attrs
这样可以继续进行了,
setup(props, self) { const handleChange = (e) => { self.emit("update:modelValue", e.target.checked); }; return { handleChange, }; },
那么我们如何定义第二个 v-model 呢?
可以通过给 v-model 添加属性的方式 如 v-model:text , 然后子组件 通过 update 事件修改 text 的属性值 就 ok 了 update:text
father
<v-modal-test v-for="item in dateRef" :key="item.id" v-model="item.status" v-model:text="item.name" />
child
<template> <input type="checkbox" :checked="modelValue" @change="handleChange" /> <input type="text" :value="text" @input="handleInput" /> </template> <script> export default { props: { modelValue: Boolean, update: Function, text: String, }, setup(props, self) { const handleChange = (e) => { self.emit("update:modelValue", e.target.checked); }; const handleInput = (e) => { let val = e.target.value; self.emit("update:text", val); }; return { handleChange, handleInput, }; }, }; </script>
修饰符
Vue3 删除了修饰符功能,改为自定义的方式。
怎么自定义呢?
父组件呢还是和原来保持不变,只不过逻辑全都交由子组件实现。
father
<v-modal-test v-for="item in dateRef" :key="item.id" v-model="item.status" v-model:text.trim="item.name" />
我们在 text 属性那里添加了修饰符 trim 在 Vue2 中已经内置不需处理,但 Vue3 不同
我们要在子组件的 props 中定义一个 Modifiers 如果你定义了修饰符,会自定帮你放入Modifiers 中。 定义方式是 属性名 + Modifiers
Child
props: { modelValue: Boolean, update: Function, text: String, textModifiers: { default: () => ({}), }, },
观察结果:我们定义了 trim 修饰符,然后 它就帮我们把 trim 这个属性放入了 textModifiers 很灵活
textModifiers:{ trim: true }
接下来我们只需要在使用的时候按需使用就可以了
const handleInput = (e) => { let val = e.target.value; if (props.textModifiers.trim) { val = val.trim(); } self.emit("update:text", val); };
完整代码:Child
<template> <input type="checkbox" :checked="modelValue" @change="handleChange" /> <input type="text" :value="text" @input="handleInput" /> </template> <script> export default { props: { modelValue: Boolean, update: Function, text: String, textModifiers: { default: () => ({}), }, }, setup(props, self) { const handleChange = (e) => { self.emit("update:modelValue", e.target.checked); }; const handleInput = (e) => { let val = e.target.value; if (props.textModifiers.trim) { val = val.trim(); } self.emit("update:text", val); }; return { handleChange, handleInput, }; }, }; </script>