自定义组件中使用v-model

HTML表单元素v-model双向绑定

<custom-input v-model="searchText"/>

当在一个自定义组件上使用v-model时,v-model 会被展开为如下的形式
将父组件实例上的searchText绑定给自定义组件的modelValue属性
在父组件中,监听自定义组件的update:modelValue事件,当自定义组件使用$emit触发update:modelValue事件时(并携带了事件参数),对应的监听函数将执行,并且将事件参数的值更新给父组件实例上的searchText,由于修改了响应式数据,从而引发重新渲染。

<CustomInput
  :modelValue="searchText"
  @update:modelValue="newValue => searchText = newValue"
/>

子组件

<template>

    <input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
    
    {{ modelValue }}
    
</template>

<script>

export default {
    name: 'CustomInput',
    data() {
        return {
        }
    },
    props: ['modelValue']
}

</script>

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

使用computed属性实现v-model双向绑定

另一种在组件内实现 v-model 的方式是使用一个可写的,同时具有 getter 和 setter 的 computed 属性。

get 方法需返回 modelValue prop,而 set 方法需触发相应的事件

过程分析:
1. 父组件通过v-model指令, 将值通过props的方式传递给了子组件定义的modelValue
2. 子组件中使用计算属性value, 读此属性返回modelValue, 修改此属性将触发 update:modelValue事件
3. 当子组件初始化时, 模板被渲染, 拿到父组件传过来的modelValue,
模板中用到计算属性value的地方,计算属性value的get将被触发,于是返回modeValue的值
4. 当修改子组件input框中的内容时, 将会把修改后的内容赋值给计算属性value,
计算属性value的set将会触发,将会把修改后的内容交给父组件的update:modelValue事件处理函数,
从而子组件又开始更新渲染模板,于是跟第三步是一样的

父组件

 <custom-input2 v-model="value1"/>

子组件

 <!-- <input v-model="value" /> --> 
    <!-- 以上等价于下方 -->
    <input :value="value" @input="value = $event.target.value"/> 

const props = defineProps({
  modelValue: {
    type: String,
  },
});

const emit = defineEmits(['update:modelValue']);

const value = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    emit('update:modelValue', value)
  }
})

多个v-model

可以在单个组件实例上,创建多个v-model双向绑定,组件上的每一个 v-model 都会同步不同的 prop,(v-model的prop 名称将默认为modelValue)

<UserName
  v-model:first-name="first"
  v-model:last-name="last"
/>
<!-- UserName组件 -->
<script>
export default {
  props: {
    firstName: String,
    lastName: String
  },
  emits: ['update:firstName', 'update:lastName']
}
</script>

<template>
  <input
    type="text"
    :value="firstName"
    @input="$emit('update:firstName', $event.target.value)"
  />
  <input
    type="text"
    :value="lastName"
    @input="$emit('update:lastName', $event.target.value)"
  />
</template>

vue3.4更新了defineModel

目前没用过。

似乎会自动创建一个双向绑定的props。

欢迎阅读!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇