夜间模式
组件中的v-model
通过v-model进行组件通信
vue
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>
<template>
<h1>{{ msg }}</h1>
<Child v-model="msg" />
</template>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
vue
<script setup>
const model = defineModel()
</script>
<template>
<span>My input</span> <input v-model="model">
</template>
1
2
3
4
5
6
7
2
3
4
5
6
7
在vue 3.4之前,是使用props 与Emits进行这样的操作的
vue
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>
<template>
<h1>{{ msg }}</h1>
<Child
:modelValue="msg"
@update:modelValue="$event => (msg = $event)"
/>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
vue
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input
:value="modelValue"
@input="emit('update:modelValue', $event.target.value)"
/>
</template>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
自定义事件名必须以update:
开头
defineModel() 简化了这一步骤
配置:
js
// 使 v-model 必填
const model = defineModel({ required: true })
// 提供一个默认值
const model = defineModel({ default: 0 })
1
2
3
4
5
2
3
4
5
绑定参数
为设定的defineModel绑定特定的值
vue
<script setup>
import { ref } from 'vue'
import MyComponent from './MyComponent.vue'
const bookTitle = ref('v-model argument example')
</script>
<template>
<h1>{{ bookTitle }}</h1>
<MyComponent v-model:title="bookTitle" />
</template>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
vue
<script setup>
const title = defineModel('title')
</script>
<template>
<input type="text" v-model="title" />
</template>
1
2
3
4
5
6
7
2
3
4
5
6
7
如果需要配置项
js
const title = defineModel('title', { required: true })
1
vue
<script setup>
defineProps({
title: {
required: true
}
})
defineEmits(['update:title'])
</script>
<template>
<input
type="text"
:value="title"
@input="$emit('update:title', $event.target.value)"
/>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
可以实现多个v-model的绑定
vue
<script setup>
import { ref } from 'vue'
import UserName from './UserName.vue'
const first = ref('John')
const last = ref('Doe')
</script>
<template>
<h1>{{ first }} {{ last }}</h1>
<UserName
v-model:first-name="first"
v-model:last-name="last"
/>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vue
<script setup>
const firstName = defineModel('firstName')
const lastName = defineModel('lastName')
</script>
<template>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
</template>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
vue
<script setup>
import { ref } from 'vue'
import UserName from './UserName.vue'
const first = ref('John')
const last = ref('Doe')
</script>
<template>
<h1>{{ first }} {{ last }}</h1>
<UserName
:first-name="first"
:last-name="last"
@update:firstName="$event => (first = $event)"
@update:lastName="$event => (last = $event)"
/>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
vue
<script setup>
defineProps({
firstName: String,
lastName: String
})
defineEmits(['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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
TIP
这就是组件库的制作方法
自定义修饰符
可以使用原先v-model的修饰符
也可以自定义修饰符
vue
<script setup>
import { ref } from 'vue'
import MyComponent from './MyComponent.vue'
const mytext = ref('hello')
const mynum = ref(1)
</script>
<template>
<h1>{{mytext}}</h1>
<h1>{{mynum}}</h1>
<MyComponent v-model:mytext.capitalize="mytext" v-model:mynum.number="mynum"/>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vue
<script setup>
import { defineModel } from 'vue'
// 使用 defineModel 来处理 v-model 和修饰符
const [mytext, { capitalize }] = defineModel('mytext',{
set(value) {
if (capitalize) {
return value.toUpperCase() // 处理 capitalize 修饰符
}
return value
}
})
console.log(capitalize) // { capitalize: true }
const num = defineModel('mynum') // 处理数字类型的 v-model
</script>
<template>
<!-- 使用 v-model 来实现双向绑定 -->
<input type="text" v-model="mytext" />
<input type="number" v-model="num" />
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
3.4 版本以前
vue
<script setup>
const props = defineProps({
modelValue: String,
modelModifiers: { default: () => ({}) }
})
const emit = defineEmits(['update:modelValue'])
function emitValue(e) {
let value = e.target.value
if (props.modelModifiers.capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1)
}
emit('update:modelValue', value)
}
</script>
<template>
<input type="text" :value="modelValue" @input="emitValue" />
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
使用参数时
vue
<UserName
v-model:first-name.capitalize="first"
v-model:last-name.uppercase="last"
/>
1
2
3
4
2
3
4
vue
<script setup>
const [firstName, firstNameModifiers] = defineModel('firstName')
const [lastName, lastNameModifiers] = defineModel('lastName')
console.log(firstNameModifiers) // { capitalize: true }
console.log(lastNameModifiers) // { uppercase: true }
</script>
1
2
3
4
5
6
7
2
3
4
5
6
7
vue
<script setup>
const props = defineProps({
firstName: String,
lastName: String,
firstNameModifiers: { default: () => ({}) },
lastNameModifiers: { default: () => ({}) }
})
defineEmits(['update:firstName', 'update:lastName'])
console.log(props.firstNameModifiers) // { capitalize: true }
console.log(props.lastNameModifiers) // { uppercase: true }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12