首頁 > web前端 > Vue.js > 主體

自訂元件中如何用v-model?聊聊.sync修飾符的使用場景

青灯夜游
發布: 2022-02-01 08:00:34
轉載
2993 人瀏覽過

自訂元件中如何用v-model?什麼場景下會使用 .sync 修飾符?以下這篇文章為大家介紹一下自訂元件中使用v-model的方法、.sync修飾符的使用場景,希望對大家有幫助!

自訂元件中如何用v-model?聊聊.sync修飾符的使用場景

【相關推薦:vue.js影片教學

如何在自訂元件中使用v -model ?

答案:

自訂元件中如何用v-model?聊聊.sync修飾符的使用場景

#程式碼實作如下:

<input :value="value" @input="handleInput" placeholder="edit me" />

  // ...
  props: {
    value: {
      type: String,
      default: &#39;&#39;
    }
  },
  methods: {
    handleInput(e) {
      this.$emit(&#39;input&#39;, e.target.value)
    }
  }
  // ...
登入後複製

引用的地方:

<v-base-model v-model="baseModelValue" />
// ...
data() {
  return {
    baseModelValue: &#39;&#39;
  }
}
// ...
登入後複製

可以看到,一個元件上的 v-model 預設會利用名為 value 的prop 和名為 input 的事件,但像單一選框、複選框等類型的輸入控制項可能會將 value 屬性用於不同的目的

model 選項可以用來避免這樣的衝突:

自訂prop 名和事件名,程式碼實作如下:

<input type="checkbox" :checked="checked" @change="handleChange" />

  // ...
  model: {
    prop: &#39;checked&#39;,
    event: &#39;change&#39;
  },
  props: {
    checked: Boolean
  },
  methods: {
    handleChange(e) {
      this.$emit(&#39;change&#39;, e.target.checked)
    }
  }
  // ...
登入後複製

引用的地方:

<v-base-checkbox v-model="baseCheckboxValue" />

data() {
  return {
    baseCheckboxValue: false
  }
}
登入後複製

這裡的 baseCheckboxValue 的值將會傳入這個名為 checked 的prop。同時當 <v-base-checkbox> 觸發一個 change 事件並附帶一個新的值的時候,baseCheckboxValue 的值將會更新。

⚠️ 注意你仍需要在元件的 props 選項裡宣告 checked 這個 prop。

說實話,日常開發中,我不是很喜歡直接寫v-model,不寫v-model 可以讓程式碼更容易被理解,因為傳參值和事件都一目了然嘛,而且也符合單向資料流的特性。

但是用了 v-model 確實會讓程式碼簡潔很多,有利有弊,就看取捨了。

什麼場景下會使用 .sync 修飾符?

答:父子元件交互,父元件傳遞給子元件 prop 值,子元件拋出事件,通知父元件改變這個綁定的值,可以用.sync修飾符簡寫。

第一次接觸 .sync 修飾符,是我在使用 element-ui 的 dialog 元件時,看到visible屬性上有這麼鬼東西。

自訂元件中如何用v-model?聊聊.sync修飾符的使用場景

自訂元件中如何用v-model?聊聊.sync修飾符的使用場景

我心想,還實現了異步和同步的情況下展示彈窗嗎,是不是還有個.async 寫法。

然後去看了 vue 文檔,才發現自己太年輕了,還好遇到不懂的都是自己先去查一查,要是直接去問同事,會很羞恥的,hhh。

那麼這個 .sync 修飾符到底是怎麼用的呢?別急,要理解 .sync 修飾符的用法,還是要從 vue 單向資料流說起。

在文章 聊聊Vue中如果不透過v-model實現雙向綁定? 中,我們聊到了 vue 的單向資料流。

子元件不能改變父元件傳遞給它的 prop 屬性,建議的做法是它拋出事件,通知父元件自行改變綁定的值。

我們透過一個計數器功能來感受vue 的單向資料流

子元件程式碼:

<template>
  <div class="test-sync">
    <button @click="add">count + 1</button>
    <p>我们是ti {{ count }} 冠军</p>
  </div>
</template>

<script>
export default {
  name: &#39;test-sync&#39;,
  props: {
    count: {
      type: Number,
      default: 0
    }
  },
  methods: {
    add() {
      this.$emit(&#39;update:count&#39;, this.count + 1)
    }
  }
}
</script>
登入後複製

父元件程式碼:

<test-sync :count="count" @update:count="handleAdd" />
//...
data() {
  return {
    count: 8
  }
}
//...
methods: {
  handleAdd(val) {
    this.count = val
  }
}
登入後複製

自訂元件中如何用v-model?聊聊.sync修飾符的使用場景

#可以看到,我們透過子元件拋出事件,通知父元件改變綁定的值,實作了子元件prop 值的變更。

整個流程如下:

自訂元件中如何用v-model?聊聊.sync修飾符的使用場景

這樣的單向資料流的寫法,是vue 一直推薦的,vue 為了方便這種寫法,在2.3.0 版本新增了.sync 修飾符這個語法糖。

把上面的計數器功能用 .sync 改寫一下。

父元件代碼:

<test-sync :count.sync="count" />
//...
data() {
  return {
    count: 8
  }
}
//...
登入後複製

是不是簡潔了許多,有了.sync 修飾符,就不用再寫事件了

⚠️ 注意,子元件內部emit 事件的時候,事件名稱必須寫成update:count 的形式,不然.sync 功能無法生效。

看着名字如此高大上的功能,居然和 v-model 一样,只是一个语法糖,我了解到真相后,只能手动[捂脸哭]。

那么回到 element-ui dialog 弹窗的 visible 属性,该怎么去用 .sync 属性呢?

很显然,也只是语法糖而已,使用 .sync 修饰符的话,可以少写一点代码。

<el-dialog :visible="dialogVisible" @close="dialogVisible = false">
登入後複製

等价于

<el-dialog :visible.sync="dialogVisible">
登入後複製

⚠️ 注意,不写 .sync 修饰符的话,一定要手动地去调用 close 方法,然后把 dialogVisible 置为 false,不然即使点击关闭按钮也无法关闭弹窗。

为了验证我们的想法,直接去查看 element-ui 的源码

自訂元件中如何用v-model?聊聊.sync修飾符的使用場景

果然在 dialog 组件源码的 178 行中发现了我们想要的代码:

this.$emit(&#39;update:visible&#39;, false);
登入後複製

总结

在之前的文章《聊聊Vue中如果不通过v-model实现双向绑定?》 中,我们聊到了 vue 的单向数据流。

这一讲,我们继续聊 v-model 和 .sync 修饰符,结果还是重点讲了 vue 的单向数据流

可见,vue 的单向数据流思想有多么重要,它几乎影响到了你日常开发中的所有组件的设计。

早年的我啥也不懂,直接上手写页面,导致测试的时候,各种 bug 层出不穷,究其根本,就是没有理解 vue 单向数据流的思想,设计的组件数据流转出了问题,还越陷越深,为了解 bug 写出更多 bug。

以后再有人问你 v-model 和 .sync 修饰符相关的问题,咱啥也不管,先把 vue 的单向数据流讲一遍。

希望我的 vue 系列文章能帮助到前端路上的你。

更多编程相关知识,请访问:编程入门!!

以上是自訂元件中如何用v-model?聊聊.sync修飾符的使用場景的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板