【Vue3.x】v-model 的破坏性更改

Vue3 model

v-model 其实是一个语法糖 通过props 和 emit组合而成的

破坏性的变动,相较于vue2的变动(具体写法改变请看下面):

  • prop:value -> modelValue;
  • 事件:input -> update:modelValue;
  • v-bind 的 .sync 修饰符和组件的 model 选项已移除
  • 新增 支持多个v-model
  • 新增 支持自定义 修饰符 Modifiers

使用场景

在输入框上实现双向绑定,仅限在以下几种组件。

  • <input>
  • <select>
  • <textarea>
  • components自定义组件

修饰符

  • .lazy ——监听 change 事件而不是 input
  • .number ——将输入的合法符串转为数字
  • .trim ——移除输入内容两端空格
  • 自定义修饰符

写法具体更改

  1. 默认v-model 的props为modelValue,并以update:modelValue。这是固定的语法。

  2. 使用多个v-model,可以使用 <MyComponentv-model:title="bookTitle" />

  3. 子组件接收v-model传值,使用defineProps()配合泛型字面量接收。

const props = defineProps<{
    modelValue: boolean,    // 默认v-model,modelValue为固定语法
    textVal: string,        // 自定义多个v-model,textVal为自定义名字
    textValModifiers?: {    // 给自定义v-model的textVal添加修饰语,textValModifiers为固定语法(Modifiers)
        isBt: boolean       // 自定义修饰符isBt
    }
}>()
  1. 子组件通知父组件修改,使用defineEmits()
// 默认v-model的update:modelValue,多个自定义v-model为update:textVal,textVal为自定义名字(和父组件定义名字一致)
const emit = defineEmits(['update:modelValue', 'update:textVal'])
const close = () => {
    emit('update:modelValue', false)
}
const change = (e: Event) => {
    const target = e.target as HTMLInputElement
    // 自定义修饰符isBt的用处。
    emit('update:textVal', props?.textValModifiers?.isBt ? target.value + '变态' : target.value)

}

案例

🚩以下是v-model进行组件通信,封装组件。并且罗列了改变和需要记忆的点

父组件App.vue

<template>
    <div>
        <div>我是App父组件</div>
        <div>isShow : {{isShow}}</div>
        <div>text: {{text}}</div>
        <div>
            <button @click="isShow=!isShow ">开关</button>
        </div>
        <hr>
        <VModel v-model="isShow" v-model:textVal.isBt="text"></VModel>
    </div>
</template>
<script setup lang='ts'>
import VModel from "./components/v-model.vue";

let isShow = ref<boolean>(true)
let text =ref<string>('小曼')

</script>

子组件VModel

<template>
    <div>我是子组件</div>
    <div v-if="modelValue" class="model">
        {{modelValue}}
        <div @click="close" class="close"><button>关闭</button></div>
        <h3>我是v-model子组件 dialog</h3>
        <div>内容:<input @input="change" :value="textVal" type="text"></div>
    </div>
</template>
<script setup lang='ts'>
// vue2 value   vue3 modelValue

const props = defineProps<{
    modelValue: boolean,
    textVal: string,
    textValModifiers?: {
        isBt: boolean
    }
}>()

// 固定语法
const emit = defineEmits(['update:modelValue', 'update:textVal'])
const close = () => {
    emit('update:modelValue', false)
}
const change = (e: Event) => {
    const target = e.target as HTMLInputElement
    emit('update:textVal', props?.textValModifiers?.isBt ? target.value + '变态' : target.value)

}
</script>
posted @ 2022-10-06 19:02  wanglei1900  阅读(266)  评论(0编辑  收藏  举报