vue如何自定义组件v-model
作者:不努力code
这篇文章主要介绍了vue如何自定义组件v-model问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
vue自定义组件v-model
官网的话
允许一个自定义组件在使用 v-model
时定制 prop 和 event。
默认情况下,一个组件上的 v-model
会把 value
用作 prop 且把 input
用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value
prop 来达到不同的目的。
使用 model
选项可以回避这些情况产生的冲突。
效果
父组件:
<template> <view class="index"> 我是父级组件{{msg}} <!-- 相当于: <node :value="msg" @input="v=>msg=v"></node>--> <node v-model="msg"></node> </view> </template> <script lang="ts"> import Vue from "vue"; import node from"./node.vue" export default Vue.extend({ components:{ node }, data() { return { msg:"abc", }; }, mounted() { // uni.navigateTo({ // url: "/pages/login/login", // }); }, }); </script> <style scoped> .index{ border: solid 1px orange; } </style>
子组件
<template> <view class="node"> <text>我是子级组件</text> <el-input v-model="result" placeholder="请输入内容"></el-input> </view> </template> <script lang="ts"> import Vue from "vue"; export default Vue.extend({ props: { value: { type: [String, Number], }, }, data() { return {}; }, computed: { result: { get(): string | number { return this.value; }, set(v: string | number) { console.log("我执行了"); this.$emit("input", v); }, }, }, }); </script> <style scoped> .node { margin: 50px 0; width: 500px; border: solid black 2px; } </style>
如果要想自定义value的名字和事件名,修改一下字组件即可,如:
<template> <view class="node"> <text>我是子级组件</text> <el-input v-model="result" placeholder="请输入内容"></el-input> </view> </template> <script lang="ts"> import Vue from "vue"; export default Vue.extend({ model: { prop: 'modelValue', event: 'change' }, props: { modelValue: { type: [String, Number], }, }, data() { return {}; }, computed: { result: { get(): string | number { return this.modelValue; }, set(v: string | number) { console.log("我执行了"); this.$emit("change", v); }, }, }, }); </script> <style scoped> .node { margin: 50px 0; width: 500px; border: solid black 2px; } </style>
vue2与vue3在自定义组件v-model上的区别
在vue开发中,通常会对一个自定义的组件进行封装,并实现v-model双向绑定功能
在 Vue 2 中,通常这样实现
父组件
<template> <Child v-model="number"></Child> </template> <script> export default { data() { return { number: 0 } }, components: { Child: () => import("./Child.vue") } } </script>
子组件
<template> <button @click="handleClick">{{ value }}</button> </template> <script> export default { props: { value: Number }, methods: { handleClick() { // 通过emit一个input事件出去,实现 v-model this.$emit('input', this.value + 1) } } } </script>
在 vue 3 中,通过这样实现
父组件
<template> <Child v-model="number"></Child> </template> <script lang="ts"> import { defineComponent, ref } from 'vue'; export default defineComponent({ setup() { const number = ref(0); return { number }; }, }); </script>
子组件
<template> <button @click="handleClick">{{ value }}</button> </template> <script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({ props: { // 更换成了 modelValue modelValue: Number }, setup(props, { emit }) { // 关闭弹出层 const handleClick = () => emit('update:modelValue', props.modelValue + 1); return { handleClick }; }, }); </script>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。