How to use v-model on custom components in Vue3?

Parent component: use v-model two-way binding to pass values

Subassembly:

1. The variable name received in defineProps is fixed as modelValue

(In the following code, it is equivalent to replacing the gender passed through v-model with modelValue, which is a fixed syntax)

// parent component
<script setup lang="ts">
import { ref } from 'vue'
const options = [
  { label: 'male', value: 1 },
  { label: 'female', value: 0 }
]
const gender = ref(1) // default gender
</script>
<template>
  <CpRadioBtn :options="options" v-model="gender"></CpRadioBtn>
</template>
<style></style>

2. Pass: emit( 'update:modelValue' , value) to directly modify the value without passing events to the parent component

('update:modelValue' is also a fixed way of writing, value is what value you want to change, and you can pass the parameter directly)

// 子组件
<script setup lang="ts">
defineProps<{
  options: { label: string; value: number }[]
  modelValue: number | string
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: number | string): void
}>()
</script>

<template>
  <div class="cp-radio-btn">
    <a
      class="item"
      href="javascript:;"
      v-for="item in options"
      :key="item.label"
      :class="{ active: item.value == modelValue }"
      @click="emit('update:modelValue', item.value)"
      >{ { item.label }}
    </a>
    <!-- <a class="item" href="javascript:;">女</a> -->
  </div>
</template>

<style lang="scss" scoped>
.cp-radio-btn {
  display: flex;
  flex-wrap: wrap;
  .item {
    height: 32px;
    min-width: 60px;
    line-height: 30px;
    padding: 0 14px;
    text-align: center;
    border: 1px solid var(--cp-bg);
    background-color: var(--cp-bg);
    margin-right: 10px;
    box-sizing: border-box;
    color: var(--cp-text2);
    margin-bottom: 10px;
    border-radius: 4px;
    transition: all 0.3s;
    &.active {
      border-color: var(--cp-primary);
      background-color: var(--cp-plain);
    }
  }
}
</style>
 

 

Guess you like

Origin blog.csdn.net/weixin_48082900/article/details/129149267