最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3 SFC 和 TSX 方式自定義組件實(shí)現(xiàn) v-model的詳細(xì)過(guò)程

 更新時(shí)間:2022年10月21日 14:56:54   作者:程序員優(yōu)雅哥(\/同)  
v-model 是 vue3 中的一個(gè)內(nèi)置指令,很多表單元素都可以使用這個(gè)屬性,如 input、checkbox 等,咱可以在自定義組件中實(shí)現(xiàn) v-model,這篇文章主要介紹了Vue3 SFC 和 TSX 方式自定義組件實(shí)現(xiàn) v-model,需要的朋友可以參考下

1 v-model

1.1 理解 v-model

v-model 是 vue3 中的一個(gè)內(nèi)置指令,很多表單元素都可以使用這個(gè)屬性,如 input、checkbox 等,咱可以在自定義組件中實(shí)現(xiàn) v-model。v-model 本質(zhì)上是一個(gè)語(yǔ)法糖:

  • 綁定父組件傳遞過(guò)來(lái)的 modelValue 屬性;
  • 值改變時(shí)向父組件發(fā)出事件 update:modelValue。

1.2 案例描述

理解了 v-model 的本質(zhì),咱可以分別使用 SFC(.vue 文件)和 TSX(.tsx)方式定義一個(gè)組件 person-name ,使該組件可以使用 v-model。

person-name 包括兩個(gè)輸入框,分別是“姓”(familyName)和“名”(firstName)兩個(gè)字段,v-model 傳遞的數(shù)據(jù)格式為:

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

首先定義該類(lèi)型 person-name-type.ts:

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

1.3 編寫(xiě)樣式

編寫(xiě) person-name.scss 樣式文件,后面再兩個(gè)組件中分別引入:

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

2 編寫(xiě)組件

2.1 實(shí)現(xiàn)思路

person-name 組件實(shí)現(xiàn)邏輯比較簡(jiǎn)單:

  • template 中放置兩個(gè)輸入框 el-input,分別對(duì)應(yīng) 姓 和 名 兩個(gè)字段;
  • 定義兩個(gè)變量 innerFamilyName 和 innerFirstName 綁定兩個(gè)輸入框的值;
  • 在 props 定義 modeValue 屬性,接收父組件傳遞過(guò)來(lái)的 PersonName 類(lèi)型的對(duì)象;
  • 使用 watch 深度監(jiān)聽(tīng) modelValue,當(dāng)其屬性值有變化時(shí),重新賦值給上面綁定輸入框的兩個(gè)變量;
  • 當(dāng)兩個(gè)輸入框觸發(fā) input 事件時(shí),通過(guò) update:modelValue 事件通知父組件,從而實(shí)現(xiàn) v-model。

2.2 SFC(.vue)中的實(shí)現(xiàn)

創(chuàng)建組件文件 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 TSX(.tsx)中的實(shí)現(xiàn)

創(chuàng)建組件文件 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 使用組件

創(chuàng)建父組件 demo-v-model.vue,在里面使用上面定義的兩個(gè)組件:

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

運(yùn)行效果如下:

上面部分使用 .vue 編寫(xiě)的組件,下面部分使用 .tsx 編寫(xiě)的組件,兩者獨(dú)立綁定 v-model,運(yùn)行效果完全一致。

  • 子組件可以接收到父組件傳遞的初始值;
  • 子組件值改變時(shí)會(huì)通知到父組件;
  • 父組件改變值時(shí),子組件會(huì)響應(yīng)變更。

到此這篇關(guān)于Vue3 SFC 和 TSX 方式自定義組件實(shí)現(xiàn) v-model的文章就介紹到這了,更多相關(guān)Vue3 自定義組件v-model內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue開(kāi)發(fā)自定義的全局公共組件詳解

    vue開(kāi)發(fā)自定義的全局公共組件詳解

    本文介紹了如何開(kāi)發(fā)自定義全局公共組件的兩種方法,第一種方法是通過(guò)在components文件夾中創(chuàng)建新的組件文件夾,例如Loading文件夾,并在其中創(chuàng)建index.js和index.vue文件,通過(guò)在vue的入口文件main.js中進(jìn)行引入,可以實(shí)現(xiàn)組件的全局調(diào)用
    2024-10-10
  • element-ui upload組件多文件上傳的示例代碼

    element-ui upload組件多文件上傳的示例代碼

    這篇文章主要介紹了element-ui upload組件多文件上傳的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • 詳解Vue2和Vue3的區(qū)別以及其鉤子函數(shù)的使用

    詳解Vue2和Vue3的區(qū)別以及其鉤子函數(shù)的使用

    Vue.js?3?和?Vue.js?2?是兩個(gè)主要版本的流行前端框架,它們之間有很多區(qū)別,包括性能優(yōu)化、新特性和改進(jìn)的API等,下面就跟隨小編一起來(lái)看看他們的使用區(qū)別吧
    2024-01-01
  • Vue.js列表渲染綁定jQuery插件的正確姿勢(shì)

    Vue.js列表渲染綁定jQuery插件的正確姿勢(shì)

    這篇文章主要為大家詳細(xì)介紹了Vue.js列表渲染綁定jQuery插件的正確姿勢(shì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 淺談Vue使用Cascader級(jí)聯(lián)選擇器數(shù)據(jù)回顯中的坑

    淺談Vue使用Cascader級(jí)聯(lián)選擇器數(shù)據(jù)回顯中的坑

    這篇文章主要介紹了淺談Vue使用Cascader級(jí)聯(lián)選擇器數(shù)據(jù)回顯中的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • Vuex的各個(gè)模塊封裝的實(shí)現(xiàn)

    Vuex的各個(gè)模塊封裝的實(shí)現(xiàn)

    這篇文章主要介紹了Vuex的各個(gè)模塊封裝的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • vue實(shí)現(xiàn)動(dòng)態(tài)面包屑導(dǎo)航

    vue實(shí)現(xiàn)動(dòng)態(tài)面包屑導(dǎo)航

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)動(dòng)態(tài)面包屑導(dǎo)航的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue style width a href動(dòng)態(tài)拼接問(wèn)題的解決

    vue style width a href動(dòng)態(tài)拼接問(wèn)題的解決

    這篇文章主要介紹了vue style width a href動(dòng)態(tài)拼接問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • vue中使用unity3D如何實(shí)現(xiàn)webGL將要呈現(xiàn)的效果

    vue中使用unity3D如何實(shí)現(xiàn)webGL將要呈現(xiàn)的效果

    這篇文章主要介紹了vue中使用unity3D如何實(shí)現(xiàn)webGL將要呈現(xiàn)的效果,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Vue實(shí)現(xiàn)驗(yàn)證碼功能

    Vue實(shí)現(xiàn)驗(yàn)證碼功能

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12

最新評(píng)論

石棉县| 乃东县| 吴桥县| 分宜县| 石门县| 灵璧县| 什邡市| 赤城县| 门源| 广西| 富顺县| 夏津县| 卓资县| 西贡区| 湖南省| 读书| 新蔡县| 绥阳县| 蕲春县| 德令哈市| 西安市| 舟曲县| 论坛| 西丰县| 杨浦区| 林州市| 兴化市| 昔阳县| 武陟县| 姜堰市| 宁都县| 东丰县| 十堰市| 高安市| 宜州市| 娄底市| 长汀县| 定西市| 遵义县| 永春县| 都江堰市|