欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > vue3学习记录-v-model

vue3学习记录-v-model

2024/10/24 4:47:10 来源:https://blog.csdn.net/qq_45030898/article/details/143163131  浏览:    关键词:vue3学习记录-v-model

vue3学习记录-v-model

  • 1.疑问
  • 2 用法
    • 2.1底层原理
    • 2.2 多个v-model
    • 2.3 defineModel()
    • 2.4 自定义修饰符

1.疑问

像那种原生标签,例如input、textarea 及 select上使用v-model,会创建双向数据绑定。那像那种自定义的组件v-model是怎么实现双向绑定的呢。

2 用法

2.1底层原理

一个名为 modelValue 的 prop,本地 ref 的值与其同步;
一个名为 update:modelValue 的事件,当本地 ref 的值发生变更时触发。

//父组件
<script setup>
import A from './components/A.vue';
import { ref } from 'vue';
const countModel = ref(0);
</script>
<template><div class="container"><p>countModel:{{ countModel }}</p><A v-model="countModel"></A><B v-model="countModel1"></B></div>
</template>//子组件
<template>
<input type="text" :value="modelValue" @input="inputChange">
</template>
<script setup>
defineProps({modelValue:String
})
const inputChange =(e) =>{console.log(e.target.value)emit('update:modelValue',e.target.value)
}
const emit = defineEmits(['update:modelValue'])
</script>

父组件中的 v-model=“foo” 将被编译为:

<A
:modelValue=“countModel”
@update:modelValue=“$event => (countModel= $event)”
/>

2.2 多个v-model

Vue 3 允许在一个组件上使用多个 v-model

<!-- CustomForm.vue -->
<script setup>
defineProps(['firstName', 'lastName'])
defineEmits(['update:firstName', 'update:lastName'])
</script><template><input :value="firstName"@input="$emit('update:firstName', $event.target.value)"/><input :value="lastName"@input="$emit('update:lastName', $event.target.value)"/>
</template>//父组件
<script setup>
import CustomForm from './components/CustomForm.vue';
import { ref } from 'vue';
const firstName = ref('')
const lastName = ref('')
</script>
<template><div class="container"><CustomFormv-model:firstName="firstName"v-model:lastName="lastName"/><p>全名:{{ firstName }} {{ lastName }}</p></div>
</template>

2.3 defineModel()

从 Vue 3.4 开始,推荐的实现方式是使用 defineModel() 宏:

<!-- Child.vue -->
<script setup>
const model = defineModel()function update() {model.value++
}
</script><template><div><div>Parent bound v-model is: {{ model }}</div><input type="text" v-model="model"><button @click="update">Increment</button></div>
</template>

defineModel的写法input绑定值用的是v-model,单个或则多个v-model和底层原理类似的写法

2.4 自定义修饰符

Vue 3 还允许我们为 v-model 创建自定义修饰符。自定义一个capitalize实现首字母大写.

<script setup>
import B from './components/B.vue';
import { ref } from 'vue';
const countModel = ref('');
</script><template><div class="container"><B v-model.capitalize="countModel"></B></div>
</template><template>
<input type="text" :value="modelValue" @input="inputChange">
</template><script setup>
import { ref, reactive} from 'vue'
const props = defineProps({modelValue:String,modelModifiers:{default: ()=> {}}
})
const inputChange =(e) =>{let value = e.target.valueif (props.modelModifiers.capitalize) {value = value.charAt(0).toUpperCase() + value.slice(1)}emit('update:modelValue',value)
}
const emit = defineEmits(['update:modelValue'])
</script>

3.4之后的写法

<!-- Child.vue -->
<script setup>
const [model, modifiers] = defineModel({set(val){if(modifiers.capitalize){return val.charAt(0).toUpperCase() + val.slice(1)}return val}
})
</script><template><div>Parent bound v-model is: {{ model }}</div><input type="text" v-model="model">
</template>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com