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

Vue3中的常見組件通信之v-model使用詳解

 更新時間:2025年04月08日 17:11:55   作者:m0_63165331  
這篇文章主要介紹了Vue3中的常見組件通信之v-model使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Vue3中的常見組件通信之v-model

概述

? 在vue3中常見的組件通信有props、mitt、v-model、refs、parent、provide、inject、pinia、slot等。不同的組件關系用不同的傳遞方式。

常見的撘配形式如下表所示。

組件關系傳遞方式
父傳子1. props
2. v-model
3. $refs
4. 默認插槽、具名插槽
子傳父1. props
2. 自定義事件
3. v-model
4. $parent
5. 作用域插槽
祖?zhèn)鲗O、孫傳祖1. $attrs
2. provide、inject
兄弟間、任意組件間1. mitt
2. pinia

? props和自定義事件詳見本人另一篇文章:

Vue3中的常見組件通信之props和自定義事件

mitt用法詳見本人另一篇文章:

Vue3中的常見組件通信之mitt

下面接著前面的文章繼續(xù)記錄v-model的用法。

v-model

v-model常用于普通html標簽中的雙向綁定,這個綁定用法無法實現(xiàn)跨組件通信,v-model用在組件標簽中的時候,可以實現(xiàn)父子間的組件通信,而這樣通信方式常用于UI組件庫。

要理解UI組件庫的v-model的雙向通信原理,需要先明白普通html標簽中的v-model的底層原理。

普通HTML標簽中v-model實現(xiàn)雙向綁定的底層原理

在普通html標簽中用v-model可以實現(xiàn)數(shù)據(jù)的雙向綁定,如下代碼所示是把input輸入框里的數(shù)據(jù)與username進行雙向綁定:

<template>
  <div class="father">
    <h3>父組件</h3>    
    <br>
    <input id="input1" type="text" v-model="username">
  </div>
</template>

<script setup lang="ts" name="Father">
	import { ref } from "vue"; 
  // 數(shù)據(jù)
  let username = ref('zhansan')

</script>

<style scoped>
.father {
  height: 300px;
  padding: 20px;
  color: #ffffff;  
  text-align:center; 
  background-image: url(https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406041301030.png);
  background-size: cover
}
#input1{
  color: #000;
}
</style>

運行后在瀏覽器打開vue開發(fā)者工具,如下圖所示:

上圖中更改vue開發(fā)者工具中的username的值頁面也會跟著發(fā)生變化,這個實現(xiàn)的是把數(shù)據(jù)呈現(xiàn)在頁面,如果修改input輸入框中的內(nèi)容,username的數(shù)據(jù)也會跟著發(fā)生改變,這個實現(xiàn)的是頁面?zhèn)飨驍?shù)據(jù),這就雙向綁定中的雙向,而實現(xiàn)這個雙向綁定的關鍵就是在于input標簽中寫了v-model,如下所示:

<input id="input1" type="text" v-model="username">

而上面的代碼實現(xiàn)的底層原理是這樣的,先把上面的代碼改成如下圖所示:

<input id="input1" type="text" :value="username">

這樣可以實現(xiàn)數(shù)據(jù)呈現(xiàn)在頁面,數(shù)據(jù)修改頁面也會跟著修改,但是修改頁面,數(shù)據(jù)卻不會變化,這只實現(xiàn)了一個方向的數(shù)據(jù)綁定,接著再給input標簽增加屬性,如下代碼:

<input 
       id="input1" 
       type="text" 
       :value="username" 
       @input="username=$event.target.value"
       >

這樣再測試,就會發(fā)現(xiàn)頁面中的數(shù)據(jù)也可以傳向數(shù)據(jù)了,修改input標簽中的內(nèi)容,數(shù)據(jù)也會變化。

注意上面代碼中@input="@input="username=event.target.value"這句代碼 ts 會報警,我們需要處理一下,對event.target進行斷言,報警就會消失:

<input 
      id="input1" 
      type="text" 
      :value="username" 
      @input="username=(<HTMLInputElement>$event.target).value"
      >

普通input標簽中v-model實現(xiàn)雙向綁定的底層原理就是:value+@input事件。

組件標簽中v-model中實現(xiàn)雙向綁定

首先準備一個自己的UI組件,作為子組件,代碼如下:

<template>
    <input type="text">
</template>

<script setup lang="ts" name="MyInput">

</script>

<style scoped>
    input{
        background-color:transparent;
        color: #ffffff;
        border: 0px;
        border-bottom: 1px solid #ffffff ;
        margin: 5px;
    }
</style>

然后在父組件中引入:

//引入MyInput組件
  import MyInput from "./MyInput.vue";

在父組件中把MyInput組件呈現(xiàn)在頁面中:

<label>用戶名:<MyInput/></label>

運行效果如下:

這樣效果出來了,但是沒有還沒有實現(xiàn)數(shù)據(jù)綁定,首先在MyInput組件標簽上增加:modelValue屬性和綁定@update:model-value事件,如下代碼:

<MyInput :modelValue="username" @update:model-value="username=$event"/>

然后需要在MyInput組件中聲明props和聲明事件來接收數(shù)據(jù)和事件:

//接收props
defineProps(["modelValue"])
//聲明事件
let emit = defineEmits(['update:model-value'])

最后在MyInput組件中的普通html標簽中添加:value屬性和綁定@input事件:

<input 
       type="text" 
       :value="modelValue"
       @input="emit('update:model-value',(<HTMLInputElement>$event.target).value)"
>

至此,已經(jīng)實現(xiàn)了父組件和子組件MyInput組件的雙向通信,如下圖所示:

最后在父組件中的MyInput組件標簽上可以直接簡寫為如下代碼:

<MyInput v-model="username"/>

實現(xiàn)的效果是完全一樣的。

我們在用UI組件庫的時候可以直接這樣寫,前提是UI組件庫已經(jīng)處理好了底層邏輯。

以下是完整代碼:

  • 父組件:
<template>
  <div class="father">
    <h3>父組件</h3>    
    <br>
    <!-- <input id="input1" type="text" v-model="username"> -->

    <!-- 下面是v-model 的本質(zhì) -->
    <!-- <input 
      id="input1" 
      type="text" 
      :value="username" 
      @input="username=(<HTMLInputElement>$event.target).value"
      > -->
    
    <!-- 下面是v-model 的本質(zhì) -->
    <!-- <label>用戶名:<MyInput :modelValue="username" @update:model-value="username=$event"/></label> -->

    <label>用戶名:<MyInput v-model="username"/></label>

  </div>
</template>

<script setup lang="ts" name="Father">
	import { ref } from "vue"; 
  //引入MyInput組件
  import MyInput from "./MyInput.vue";
  // 數(shù)據(jù)
  let username = ref('zhansan')

</script>

<style scoped>
.father {
  height: 300px;
  padding: 20px;
  color: #ffffff;  
  text-align:center; 
  background-image: url(https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406041301030.png);
  background-size: cover
}
#input1{
  color: #000;
}
</style>
  • MyInput組件:
<template>
    <input 
        type="text" 
        :value="modelValue"
        @input="emit('update:model-value',(<HTMLInputElement>$event.target).value)"
    >
</template>

<script setup lang="ts" name="MyInput">
    //聲明props
    defineProps(["modelValue"])
    //聲明事件
    let emit = defineEmits(['update:model-value'])
</script>

<style scoped>
    input{
        background-color:transparent;
        color: #ffffff;
        border: 0px;
        border-bottom: 1px solid #ffffff ;
        margin: 5px;
    }
</style>

一個UI組件實現(xiàn)多個數(shù)據(jù)傳送

在父組件中可以改value,比如改成usName,如下代碼所示:

<MyInput v-model:usName="username"/>

這個代碼的本質(zhì)是如下代碼:

<MyInput :usName="username" @update:usName="username=$event"/>

在MyInput組件代碼中就需要改成如下代碼:

<template>
    <input 
        type="text" 
        :value="usName"
        @input="emit('update:usName',(<HTMLInputElement>$event.target).value)"
    >
</template>

<script setup lang="ts" name="MyInput">
    //聲明props
    defineProps(["usName"])
    //聲明事件
    let emit = defineEmits(['update:usName'])
</script>

這樣改完后運行效果跟之前是完全一樣的,接下來再擴展一下,父組件中的MyInput標簽改成如下代碼:

<MyInput v-model:usName="username" v-model:paword="password"/>

然后在MyInput組件中代碼改成如下:

<template>
    <input 
        type="text" 
        :value="usName"
        @input="emit('update:usName',(<HTMLInputElement>$event.target).value)"
    >
    <br>
    <input 
        type="text" 
        :value="paword"
        @input="emit('update:paword',(<HTMLInputElement>$event.target).value)"
    >
</template>

<script setup lang="ts" name="MyInput">
    //聲明props
    defineProps(["usName",'paword'])
    //聲明事件
    let emit = defineEmits(['update:usName','update:paword'])
</script>

這樣就實現(xiàn)一個組件內(nèi)雙向綁定兩個數(shù)據(jù)了,如下圖所示:

總結(jié)

v-model可以實現(xiàn)父子間的通信,v-model即可以設置在普通html標簽中,也可以設置在組件標簽中,設置在組件標簽中可以實現(xiàn)父子間的雙向通信,前提是子組件底層做了處理。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

最新評論

安远县| 霍邱县| 无极县| 克山县| 河池市| 军事| 和顺县| 东台市| 克什克腾旗| 泰来县| 视频| 罗平县| 天门市| 鄂尔多斯市| 达拉特旗| 通河县| 察雅县| 常山县| 石柱| 兰州市| 商水县| 库车县| 奉新县| 元氏县| 凯里市| 团风县| 左贡县| 兴城市| 楚雄市| 龙岩市| 安岳县| 栖霞市| 南木林县| 荣成市| 洛扎县| 长春市| 广饶县| 南充市| 孝义市| 三明市| 安仁县|