Appearance
父组件
vue
<template>
<Rating v-model="value"></Rating>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Rating from '@/components/Rating/index.vue' // 导入组件
const value = ref(0)
</script>子组件
vue
<template>
<view class="rating">
<view v-for="(item, index) in starNum" :key="index"
class="l-icons icon-xingxing" :class="[index+1 <= modelValue ? 'icon-select' : 'icon-noselect']"
:style="{color: index+1 <= modelValue ? activeColor : unActiveColor, fontSize: fontSize}" @click="ratingClick(index)">
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
type Props = {
modelValue: number, // 父组件写v-model时,收到的参数
}
const props = withDefaults(defineProps<Props>(), {
modelValue: 0,
})
const emit = defineEmits<{
(event: 'update:modelValue', value:number): void
}>()
const ratingClick = (index) => {
// 更新父组件的值
emit('update:modelValue', index+1)
}
// 定义当前组件暴露出去的属性,父组件通过ref方式能够调用
defineExpose({
})
</script>组件双向绑定
v-model可以在组件上实现双向绑定。 当前v-model使用在原生元素上时:
html
<input v-model="text"/>编译模板会对v-model进行更冗长的等价展开。所以上面的代码等价于下面的代码:
html
<input value="text" @input="text => $event.target.value" />当v-model使用在组件上时,v-model会被展开:
html
<Rating :modelValue="text" @update:modelValue="newValue => text = newValue"></Rating>要让列子实际工作起来,我们需要在子组件Rating内部做两件事
- 将内部的值绑定到modelValue上
- 当内部值触发改变时,触发一个携带新的值update:modelValue自定义事件
vue
<template>
<view class="rating" @click="ratingClick(index)">
{{ modelValue }}
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
type Props = {
modelValue: number, // 父组件写v-model时,收到的参数
}
const props = withDefaults(defineProps<Props>(), {
modelValue: 0,
})
const emit = defineEmits<{
(event: 'update:modelValue', value:number): void
}>()
const ratingClick = () => {
// 更新父组件的值
emit('update:modelValue', props.modelValue + 1)
}
</script>modelValue为默认v-model参数。如下,如果这样,modelValue就替换成title
v-model:title="text"