Los componentes personalizados Vue3 SFC y TSX implementan el modelo v

1 modelo v

1.1 Entendiendo el modelo v

v-model  es una instrucción integrada en vue3. Muchos elementos de formulario pueden usar este atributo, como  input , checkbox , etc. Podemos implementar v-model  en componentes personalizados  . v-model  es esencialmente un azúcar sintáctico:

  • Enlace el atributo modelValue pasado por el componente principal   ;
  • Emita el evento update:modelValue al componente principal cuando cambie el valor  .

1.2 Descripción del caso

Después de comprender  la esencia de v-model  , podemos usar SFC (archivo .vue) y TSX (.tsx) para definir un  nombre de persona del componente  para que el componente pueda usar  v-model .

person-name  incluye dos cuadros de entrada, a saber, "apellido" ( familyName ) y "first name" ( firstName ),  el formato de datos pasado por v-model es:

{ familyName: '张', firstName: '三' }

Primero defina el tipo  person-name-type.ts :

export interface PersonName {
  /** 姓 */
  familyName?: string;
  /** 名 */
  firstName?: string;
}

1.3 Estilos de escritura

Escriba  el  archivo de estilo person-name.scss e impórtelo en los dos componentes más adelante:

.person-name {
  .el-form-item {
    width: 200px;
  }
}

2 Escribir componentes

2.1 Ideas de implementación

La lógica de implementación del componente nombre-persona  es relativamente simple:

  1.  Coloque dos casillas de entrada  el-input en la plantilla , correspondientes a  los dos campos de apellido  y  nombre respectivamente  ;
  2. Defina dos variables  innerFamilyName  e  innerFirstName  para vincular los valores de los dos cuadros de entrada;
  3.  Defina  el atributo modeValue en  props para recibir el  objeto de tipo PersonName  pasado por el componente principal  ;
  4. Use  watch  para monitorear  modelValue en profundidad , y cuando cambie el valor de su atributo, reasígnelo a las dos variables vinculadas al cuadro de entrada anterior;
  5. Cuando los dos cuadros de entrada activan  el evento de entrada  , se notifica al componente principal a través  del  evento update:modelValue para implementar  v-model .

2.2 Implementación en SFC (.vue)

Cree el archivo de componente  person-name-sfc.vue :

<template>
  <div class="person-name">
    <el-form-item label="姓">
      <el-input v-model="innerFamilyName" @input="onInput"></el-input>
    </el-form-item>
    <el-form-item label="名">
      <el-input v-model="innerFirstName" @input="onInput"></el-input>
    </el-form-item>
  </div>
</template>

<script lang="ts" setup name="person-name-sfc">
import { PropType, ref, watch } from 'vue'
import { PersonName } from './person-name-type'

const props = defineProps({
  modelValue: {
    type: Object as PropType<PersonName>,
    required: true,
    default: () => ({})
  }
})

const emits = defineEmits(['update:modelValue'])

const innerFamilyName = ref('')
const innerFirstName = ref('')

watch(() => props.modelValue, (newVal) => {
  innerFamilyName.value = newVal?.familyName || ''
  innerFirstName.value = newVal?.firstName || ''
}, {
  deep: true,
  immediate: true
})

const onInput = () => {
  emits('update:modelValue', {
    familyName: innerFamilyName.value,
    firstName: innerFirstName.value
  })
}
</script>

<style scoped lang="scss">
@import "./person-name";
</style>

2.3 Implementación en TSX (.tsx)

Cree el archivo de componente  person-name-tsx.tsx :

import { defineComponent, PropType, ref, watch } from 'vue'
import { PersonName } from './person-name-type'
import './person-name.scss'

export default defineComponent({
  name: 'person-name-tsx',
  props: {
    modelValue: {
      type: Object as PropType<PersonName>,
      required: true,
      default: () => ({})
    }
  },
  emits: ['update:modelValue'],
  setup (props, context) {
    const innerFamilyName = ref(props.modelValue.familyName)
    const innerFirstName = ref(props.modelValue.firstName)

    const onInput = () => {
      context.emit('update:modelValue', {
        familyName: innerFamilyName.value,
        firstName: innerFirstName.value
      })
    }

    watch(() => props.modelValue, (newVal) => {
      innerFamilyName.value = newVal?.familyName || ''
      innerFirstName.value = newVal?.firstName || ''
    }, {
      deep: true,
      immediate: true
    })

    return () => (
      <div class="person-name">
        <el-form-item label="姓">
          <el-input vModel={innerFamilyName.value} onInput={onInput}/>
        </el-form-item>
        <el-form-item label="名">
          <el-input vModel={innerFirstName.value} onInput={onInput}/>
        </el-form-item>
      </div>
    )
  }
})

3 Uso de componentes

Cree el componente principal  demo-v-model.vue y use los dos componentes definidos anteriormente:

<template>
  <div>
    <person-name-sfc v-model="personName1"></person-name-sfc>
    <el-button @click="onResetClick1">reset</el-button>
    <div>{
   
   {personName1}}</div>
  </div>
  <el-divider />
  <div>
    <person-name-tsx v-model="personName2"></person-name-tsx>
    <el-button @click="onResetClick2">reset</el-button>
    <div>{
   
   {personName2}}</div>
  </div>
</template>

<script lang="ts" setup>
import PersonNameSfc from '@/components/model/person-name-sfc.vue'
import { ref } from 'vue'
import { PersonName } from '@/components/model/person-name-type'
import PersonNameTsx from '@/components/model/person-name-tsx'

const defaultPersonName = { familyName: '张', firstName: '三' }

const personName1 = ref<PersonName>({ ...defaultPersonName })
const personName2 = ref<PersonName>({ ...defaultPersonName })

const onResetClick1 = () => {
  personName1.value = { ...defaultPersonName }
}
const onResetClick2 = () => {
  personName2.value = { ...defaultPersonName }
}
</script>

El efecto de ejecución es el siguiente:

La parte superior usa los componentes escritos en .vue, y la parte inferior usa los componentes escritos en .tsx. Los dos están vinculados al  modelo v de forma independiente , y el efecto de la operación es exactamente el mismo.

  1. Los componentes secundarios pueden recibir el valor inicial pasado por el componente principal;
  2. Cuando cambie el valor del componente secundario, se lo notificará al componente principal;
  3. Cuando el componente principal cambia su valor, el componente secundario responde al cambio. 

Supongo que te gusta

Origin blog.csdn.net/weixin_47367099/article/details/127536510
Recomendado
Clasificación