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

vue3中v-model的用法詳解

 更新時間:2023年04月24日 11:33:14   作者:好大貓  
vue 提供了很多自定義指令,大大方便了我們的開發(fā),其中最常用的也就是 v-model,他可以在組件上使用以實現(xiàn)雙向綁定。它可以綁定多種數(shù)據(jù)結構, 今天總結一下用法

綁定單個屬性

基礎綁定

以 自定義組件 CustomInput 舉例

<script setup>
    const txt = ref('');
 </script>
 
 <template>
  <CustomInput v-model="txt" />
 </template>

v-model 會被展開為如下的形式

<CustomInput
  :modelValue="txt"
  @update:modelValue="newValue => txt = newValue"
/>

<CustomInput> 組件內(nèi)部需要做兩件事:

  • 將內(nèi)部原生 <input> 元素的 value attribute 綁定到 modelValue prop
  • 當原生的 input 事件觸發(fā)時,觸發(fā)一個攜帶了新值的 update:modelValue 自定義事件

這里是相應的代碼:

<script setup>
const props = defineProps({
  'modelValue': String,
})
const emit = defineEmits(["update:modelValue"])
</script>

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

有些人會覺得這種寫法過于繁瑣,會導致標簽代碼變得冗長

另一種在組件內(nèi)實現(xiàn) v-model 的方式是使用一個可寫的,同時具有 getter 和 setter 的 computed 屬性

computed 綁定

使用computed 屬性時, get 方法需返回 modelValue prop,而 set 方法需觸發(fā)相應的事件

<script setup>
const value = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    emit("update:modelValue", value)
  }
})
</script>

<template>
 <input v-model="value" />
</template>

這種寫法可以簡化標簽中的屬性,邏輯清晰

單個屬性可以使用 v-model 輕松搞定,如果多個屬性都需要雙向綁定呢?

?? v-model 綁定多個屬性

默認情況下,v-model 在組件上都是使用 modelValue 作為 prop,并以 update:modelValue 作為對應的事件

但我們可以通過給 v-model 指定一個參數(shù)來更改這些名字:

<template>
    <CustomInput v-model:first-name="first" v-model:last-name="last" />
</template>

同樣的,也可以用兩種方式綁定,只是 prop 從原來的 modelValue 變?yōu)榱藗魅氲膮?shù)名,對應的事件也變成了 update:參數(shù)名

 <script setup>
 const props = defineProps({
  firstName: String,
  lastName: String,
})
// 在computed中 使用
const emit = defineEmits(['update:firstName', 'update:lastName'])
</script>

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

?? 綁定對象

在一個復雜的組件中,如果多個字段需要雙向綁定,如果使用上文所示方法的話,會有一些繁瑣

介紹兩種雙向綁定對象的做法

定義父組件 searchBar 為一個復雜表單組件

<script setup>
import { ref } from "vue"

const modelValue = ref({
  keyword: "123",
  selectValue: "",
  options: [
    {
      label: "全部",
      value: ""
    },
    {
      label: "a1",
      value: "1"
    },
    {
      label: "a2",
      value: "2"
    },
  ]
})
</script>

<template>
    <searchBar v-model="modelValue" />
</template>

那么在 searchBar 組件內(nèi),我們接收 modelValue 并定義類型為 Object

<template>
  <div>
    <!-- <input type="text" v-model="modelValue.keyword"> 可以實現(xiàn)雙向綁定 -->
    <input type="text" 
      :value="modelValue.keyword"
      @input="handleKeywordChange"
    >
    <select v-model="modelValue.selectValue">
      <option v-for="o in modelValue.options" :key="o.value" :value="o.value">
        {{ o.label }}
      </option>
    </select>
  </div>
</template>

<script lang="ts" setup>

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({})
  }
})

const emit = defineEmits(["update:modelValue"]);

// 以 input 舉例
const handleKeywordChange=(val)=>{
  emit("update:modelValue",{
    ...props.modelValue,
    keyword:val.target.value
  })
}
</script>

如果傳入對象的話,如注釋所介紹的那樣
<input type="text" v-model="modelValue.keyword">雖然可以直接進行雙向綁定,但是這樣會破壞單項數(shù)據(jù)流

和上文的 emit 觸發(fā)事件一樣,但是傳遞的數(shù)據(jù)則變成了對象

雖然使用 emit 可以觸發(fā)雙向綁定,但是過于繁瑣,下面介紹一種更優(yōu)雅的寫法,可以說是一種奇技淫巧 -- computed + prxoy

如果使用 computed 綁定,你可能會寫出這種代碼

<template>
      <input type="text" v-model="model.keyword">
 </template>
 
<script lang="ts" setup>

const model = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    // console.log(value) // 發(fā)現(xiàn)沒有打印
     emit("update:modelValue", {
      ...props.modelValue,
       keyword: value
     })
  }
})
<script>

但是當你輸入的時候,你會發(fā)現(xiàn)并沒有觸發(fā) setter, 因為 computed 會做一層代理,代理對象沒有發(fā)生修改

如果想要觸發(fā) setter ,如下圖:

// 只有這樣才會變化
 model.value = {
   keyword:"asdfad"
 }

這種方法無法觸發(fā) setter,也就無法雙向綁定,該怎么辦呢?

getter 中返回 一個 代理對象!getter 中返回 一個 代理對象!getter 中返回 一個 代理對象!

因為 proxy代理的對象是和被代理對象屬性是保持一致的,所以我們使用 proxy 包裹原對象

那么 v-model 綁定的是代理之后的對象,如果代理對象屬性發(fā)生了改變,則會觸發(fā)代理對象中的 set 方法,此時我們可以觸發(fā) emit

const model = computed({
  get() {
    return new Proxy(props.modelValue, {
      set(obj, name, val) {
        emit("update:modelValue", {
          ...obj,
          [name]: val
        })
        return true
      }
    })
  },
  set(value) {
    emit("update:modelValue", {
      ...props.modelValue,
      keyword: value
    })
  }
})

修飾符

我們知道 v-model 有一些內(nèi)置的修飾符,例如 .trim,.number 和 .lazy。

在某些場景下,我們可能想要一個自定義組件的 v-model 支持自定義的修飾符。

我們來創(chuàng)建一個自定義的修飾符 capitalize,它會自動將 v-model 綁定輸入的字符串值第一個字母轉為大寫:

  <CustomInput v-model.capitalize="txt" />

我們添加了capitalize修飾符,他會被自動傳入到 prop 中的 modelModifiers 中

<script setup>
const props = defineProps({
  modelValue: String,
  modelModifiers: {
    default: () => ({})
  }
})

const emitValue = (e) => {
  let value = e.target.value;
  // 使用 修飾符
  if (props.modelModifiers.capitalize) {
    value = value.charAt(0).toUpperCase() + value.slice(1)
  }
  emit('update:modelValue', value)
}
</script>

<template>
  <input :value="modelValue" @input="emitValue" />
</template>

總結

在 vue 中, 我們可以使用 v-model 指令進行很方便的雙向綁定,配合修飾符可以完成很多有趣的功能

以上就是vue3中v-model的用法詳解的詳細內(nèi)容,更多關于vue3 v-model用法 的資料請關注腳本之家其它相關文章!

相關文章

  • vue視頻播放暫停代碼

    vue視頻播放暫停代碼

    今天小編就為大家分享一篇vue視頻播放暫停代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • 在vue react中如何使用Web Components組件

    在vue react中如何使用Web Components組件

    這篇文章主要介紹了在vue react中如何使用Web Components組件問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Vue中使用jsencrypt進行RSA非對稱加密的操作方法

    Vue中使用jsencrypt進行RSA非對稱加密的操作方法

    這篇文章主要介紹了Vue中使用jsencrypt進行RSA非對稱加密,在這里需要注意要加密的數(shù)據(jù)必須是字符串,對Vue?RSA非對稱加密相關知識感興趣的朋友一起看看吧
    2022-04-04
  • vue實現(xiàn)登錄時的圖片驗證碼

    vue實現(xiàn)登錄時的圖片驗證碼

    這篇文章主要為大家詳細介紹了vue實現(xiàn)登錄時的圖片驗證碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • vue后臺管理如何配置動態(tài)路由菜單

    vue后臺管理如何配置動態(tài)路由菜單

    這篇文章主要介紹了vue后臺管理如何配置動態(tài)路由菜單,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue?項目的成功發(fā)布和部署的實現(xiàn)

    Vue?項目的成功發(fā)布和部署的實現(xiàn)

    本文主要介紹了Vue?項目的成功發(fā)布和部署的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • 結合el-upload組件實現(xiàn)大文件分片上傳功能

    結合el-upload組件實現(xiàn)大文件分片上傳功能

    Element UI的el-upload上傳組件相信各位小伙伴都已經(jīng)非常熟悉,最近接了一個新需求,要求在el-upload組件基礎上實現(xiàn)分片上傳功能,即小于等于5M文件正常上傳,大于5M文件切成5M每片上傳,那么這個功能怎么實現(xiàn)呢?一起看看吧
    2022-09-09
  • vue請求接口并且攜帶token的實現(xiàn)

    vue請求接口并且攜帶token的實現(xiàn)

    本文主要介紹了vue請求接口并且攜帶token的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • vue.js實現(xiàn)的綁定class操作示例

    vue.js實現(xiàn)的綁定class操作示例

    這篇文章主要介紹了vue.js實現(xiàn)的綁定class操作,結合實例形式分析了vue.js綁定class常見的3種操作技巧,需要的朋友可以參考下
    2018-07-07
  • Vue3.0路由跳轉攜帶參數(shù)的示例詳解

    Vue3.0路由跳轉攜帶參數(shù)的示例詳解

    這篇文章主要介紹了Vue3.0路由跳轉攜帶參數(shù)的示例代碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04

最新評論

泸水县| 湖北省| 安陆市| 汝南县| 阳城县| 上思县| 康乐县| 望城县| 台江县| 通山县| 胶南市| 墨脱县| 伊春市| 桓台县| 合作市| 平和县| 化州市| 海伦市| 兰西县| 淮北市| 永定县| 崇礼县| 马山县| 酒泉市| 灵丘县| 达孜县| 黔江区| 抚宁县| 谷城县| 怀化市| 射洪县| 林西县| 揭东县| 来宾市| 北川| 衡山县| 甘泉县| 石泉县| 焉耆| 综艺| 合肥市|