Vue3: About the usage of v-model

Table of contents

Foreword:

Recall the basic native usage:

Encapsulation of native input:

Custom v-model parameters:

Secondary encapsulation of el-input:

Binding multiple v-models:

v-model modifier:

Combination of v-model custom parameters and custom modifiers:


Foreword:

        Speaking of v-model, you must be familiar with it. As a classic grammar of vue, it helps us save a lot of things when writing projects. This article focuses on recording the binding and use of v-model on components!

Recall the basic native usage:

Using native input, we generally write like this:

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

This notation is equivalent to the following notation:

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

 And when we use the v-model writing method on a component, the actual writing time looks like this:

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

Please note that model-value and @update:modelValue are not specified by me, but by vue!

So, if we want to use it like this, we need to bind the input value inside the component to the modelValue.

When the original input time is triggered, use @update:modelValue to carry the new value out!

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

Encapsulation of native 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>

or another way of writing:

<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>

Both ways of writing are available, so that we can introduce our custom components, using this way of writing

<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>

Custom v-model parameters:

By default, all components use modelValue as their prop, and update:modelValue as the corresponding update event. Sometimes we need to change it!

The basic rule is, the custom prop: xxx, the corresponding update event: update: xxx, the component becomes v-model: xxx, the following is an example of 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>

Then we use it on the component and it becomes like this:

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

So, when we use the el-input component in element-plus, we will find that it is written like this

When using the input component in Naive UI or Ant Design Vue, you will find that it is written like this

 

In general, element-plus uses the default, while the other two have customized parameters for it, and the parameters are value!

As for another way of writing using computed, just edit according to the most basic version!

Secondary encapsulation of el-input:

When writing a project normally, we usually choose a ui framework suitable for the project, whether it is element-plus or naive, etc., we can’t say that we can write a native input component for packaging, unless your input looks particularly strange . . . In most cases, we can re-encapsulate the components of the ui component library, and more likely to be business encapsulation.

Here we take el-input as an example. As mentioned above, el-input actually uses the default parameter modelValue. We can also see it by reading the el-input document --- el- input ;

 Therefore, when we re-encapsulate el-input, we need to write:

<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>

If you are using the Naive UI component library, then you need to use value and update:value when you re-encapsulate the n-input component, and the same is true for other component libraries!

Binding multiple v-models:

When we write multiple input boxes or other such form components in a custom component, we must use multiple v-models on the component. At this time, the default modelValue is not enough for us, so we A custom v-model parameter is required. It's very simple, just write it together and it's 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 modifier:

Regarding the modifiers of v-model, you know that there are some built-in modifiers, such as .trim, .number and the like. Sometimes, we need custom modifiers, see the example below!

There is a requirement: When you enter the word "Qianjue" in the input box, it will become ***. This modifier, I decided to name it .replace, and the written effect looks like this!

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

So how to write inside the component?

First of all, we need to write the default modelValue in props, and then we need to add modelModifiers, which is also the default, and modelValue is matched. Note that the default value of modelModifiers is an empty object!

<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>

Print props can see the following content,

 When we use v-model.replace on the component, replace is true here, then we can happily proceed to the next step, here I use lodash's _replace method: lodash's _replace

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

The page display will look like this: *** is Qian Jue, hehe!

Combination of v-model custom parameters and custom modifiers:

The demand comes again: when we enter lowercase letters, it will automatically change to the corresponding uppercase letters.

In this case, modelValue and modelModifiers can no longer be used, of course. The rule at this time is that we customize a parameter xxx, and the corresponding modelModifiers will become xxxModifiers. Here, taking value as an example, props will have two parameters, value and 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>

Components use:

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

 At this point, how we enter lowercase letters will be automatically converted to uppercase, which is a success!

Guess you like

Origin blog.csdn.net/qq_42543244/article/details/129164599