本文介绍: 提起vmodel,想必都不陌生,作为vue经典语法,帮助我们编写项目时候,省了很多很多的事情,本文着重记录vmodel组件上的绑定使用!在默认的情况下,组件的都是使用modelValue作为自己prop使用update:modelValue作为对应更新事件,有时候我们需要去改动一哈!基本规则就是自定义propxxx, 对应更新事件update:xxx, 组件上就变成了vmodel:xxx写法,下面以value举例

目录

前言:

回忆基本的原生用法:

原生input的封装:

自定义v-model参数:

对el-input的二次封装:

多个v-model进行绑定:

v-model修饰符:

v-model自定义参数与自定义修饰符的结合:


前言

        提起vmodel,想必都不陌生,作为vue的经典语法,帮助我们编写项目时候,省了很多很多的事情,本文着重记录v-model组件上的绑定使用

回忆基本原生用法

使用原生input我们一般这么写:

<input type="text" v-model="name">

此种写法相当于以下写法:

<input type="text" :value="name" @input="e=> name = e.target.value">
<input type="text" :value="name" @input="name = $event.target.value"&gt;

 而当我们一个组件使用v-model的写法时,实际写法时长这个样子:

<custom-input :model-value="name" @update:modelValue="newValue=&gt;name = newValue"></custom-input>

请注意model-value与@update:modelValue并不是我规定的,而是vue规定的!

于是乎,我们如果想写成这样使用,那就需要将组件内部input value值与modelValue进行绑定

原生input时间触发时,利用@update:modelValue将新值携带出去!

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

原生input的封装

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

<script setup>
	import { defineProps, defineEmits } from "vue"

	const props = defineProps(['modelValue'])
	const emit = defineEmits(['update:modelValue'])
</script>

或者另一种写法:

<template>
	<div>modelValue: <input v-model="value"></div>
</template>

<script setup>
	import {defineProps,defineEmits,computed} from "vue"

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

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

两种写法都可,这样我们可以引入我们自定义组件采用如此写法

<template>
	<custom-input v-model="name"></custom-input>
	<div>name:{{name}}</div>
</template>

<script setup>
    import {ref} from "vue";
	import CustomInput from "./components/custom-input/index.vue";
	
	const name = ref('')
</script>

自定义v-model参数

默认的情况下,组件的都是使用modelValue作为自己prop,使用update:modelValue作为对应更新事件,有时候我们需要去改动一哈!

基本规则就是自定义prop:xxx, 对应更新事件:update:xxx, 组件上就变成了v-model:xxx的写法,下面以value举例

<template>
	<div>自定义v-model的参数,例:value: <input :value="value" @input="$emit('update:value', $event.target.value)"></div>
</template>

<script setup>
	import {defineProps,defineEmits} from "vue"

	const props = defineProps(['value'])
	const emit = defineEmits(['update:value'])
</script>

那么我们在组件上使用就变成了这样子:

<custom-input v-model:value="name"></custom-input>

所以,当我们使用elementplus中的el-input组件时,会发现是这样的写法

当使用Naive UI或者Ant Design Vue中的input组件时,会发现是这样写法

 

总得来说,就是elementplus用了默认的,而另外两个对其进行了自定义参数,而且参数是value!

至于另外一种使用computed的写法,依照最基础的版本,进行编辑即可

对el-input的二次封装

在正常写项目的时候,一般都会选择一个适用项目ui框架,不管是elementplus或者naive等等,我们不可能说自己去写一个原生的input组件进行封装,除非你的input长得特别奇特。。。大部分情况下,我们对ui组件库的组件进行二次封装即可,更多的可能业务上的封装

这里以el-input举例,上面说到,el-input其实是用的默认参数modelValue,我们通过阅读el-input文档可以看出来—el-input

 故,当我们在对el-input进行二次封装的时候,需要这么写:

<template>
	<div>
		modelValue:
		<el-input :model-value="modelValue" @input="$emit('update:modelValue',$event)" />
	</div>
</template>

<script setup>
	import {defineProps,defineEmits} from "vue"

	const props = defineProps(['modelValue'])
	const emit = defineEmits(['update:modelValue'])
</script>

如果你是用的Naive UI组件库,那么在你对n-input组件进行二次封装的时候,就需要使用value,update:value了,其他的组件库也是如此!

多个v-model进行绑定:

当我们在自定义的组件中写多个输入框或者是其他之类的表单式组件,那就必须在组件上使用多个v-model,这个时候默认的modelValue已经不够我们使用了,所以我们必须要进行自定义v-model参数。很简单,写一起就ok

<template>
	<div>
		modelValue:
		<el-input :model-value="modelValue" @input="$emit('update:modelValue',$event)" />
	</div>
	<div>
		自定义v-model的参数,例:value:
		<el-input :model-value="value" @input="$emit('update:value',$event)" />
	</div>
</template>

<script setup>
	import {defineProps,defineEmits} from "vue"

	const props = defineProps(['modelValue', 'value'])
	const emit = defineEmits(['update:modelValue', 'update:value'])
</script>
<template>
	<custom-el-input v-model="name" v-model:value="desc"></custom-el-input>
	<div>name:{{name}}</div>
	<div>desc:{{desc}}</div>


</template>

<script setup>
	import CustomElInput from "./components/custom-el-input/index.vue"
	import {ref} from "vue";
	const name = ref('')
	const desc = ref('')
</script>

v-model修饰符

关于v-model的修饰符知道有一些内置修饰符例如.trim,.number之类的。有时候,我们需要自定义修饰符,看下面的例子

有个需求:要求当你在输入框输入 “千珏” 二字的时候,就变成 *** 。此修饰符,我决定命名为.replace写出来的效果这个样子的!

<custom-el-input v-model.replace="name"></custom-el-input>

那么组件内部如何去写?

首先我们需要在props里面写上默认的modelValue,其次我们还需要添加上modelModifiers,这个也是默认的,和modelValue都是配套的,注意modelModifiers默认值一个对象

<template>
	<div>modelValue:
		<el-input :model-value="modelValue" @input="input" />
	</div>
</template>

<script setup>
	import {defineProps,defineEmits} from "vue";
	const props = defineProps({
		modelValue: String,
		modelModifiers: {default: () => ({})}
	})
	const emit = defineEmits(['update:modelValue'])

	/* 将 千珏 关键字代替为 *** 字 */
	const input = (value) => {
		console.log(props);
	}
</script>

打印props可以看到如下内容

 当我们在组件上使用 v-model.replace时,在此处replacetrue,那我们就可以愉快的进行下一步了,这里我使用了lodash_replace方法:lodash的_replace

	/* 将 千珏 关键字代替为 *** 字 */
	const input = (value) => {
		const replace = props.modelModifiers.replace
		const keyWord = '千珏'
		const replaceWord = '***'
		if (replace) {
			value = _replace(value, keyWord, replaceWord)
		}
		emit('update:modelValue', value)
	}

页面展示就会长这个样子:***就是千珏了,嘿嘿!

v-model自定义参数与自定义修饰符结合

需求又来了:当我们输入小写字母时,自动变为对应大写字母

对于此种情况,modelValue与modelModifiers当然就不能再用了。此时的规则就是,我们自定义一个参数xxx,而对应的modelModifiers将变成xxxModifiers,这里以value举例,props就会有两个参数,value和valueModifiers。

<template>
	<div>自定义v-model的参数,例:value:
		<el-input :model-value="value" @input="input" />
	</div>
</template>

<script setup>
	import {defineProps,defineEmits} from "vue";
	import _toUpper from "lodash/toUpper"
	const props = defineProps({
		value: String,
		valueModifiers: {
			default: () => ({})
		}
	})
	const emit = defineEmits(['update:value'])

	/* 将 小写字母 转化为 大写字母 */
	const input = (value) => {
		const toUpper = props.valueModifiers.toUpper
		if (toUpper) {
			value = _toUpper(value)
		}
		emit('update:value', value)
	}
</script>

组件使用:

<custom-el-input v-model:value.toUpper="desc"></custom-el-input>

 此时,我们如何输入小写字母都会被自动转化为大写,这就成功了!

原文地址:https://blog.csdn.net/qq_42543244/article/details/129164599

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_37574.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注