亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

自定義事件

自定義事件


該頁(yè)面假設(shè)你已經(jīng)閱讀過(guò)了組件基礎(chǔ)。如果你還對(duì)組件不太了解,推薦你先閱讀它。


目錄


事件名


不同于組件和 prop,事件名不存在任何自動(dòng)化的大小寫(xiě)轉(zhuǎn)換。而是觸發(fā)的事件名需要完全匹配監(jiān)聽(tīng)這個(gè)事件所用的名稱(chēng)。舉個(gè)例子,如果觸發(fā)一個(gè) camelCase 名字的事件:

this.$emit('myEvent')

則監(jiān)聽(tīng)這個(gè)名字的 kebab-case 版本是不會(huì)有任何效果的:

<!-- 沒(méi)有效果 -->
<my-component v-on:my-event="doSomething"></my-component>

不同于組件和 prop,事件名不會(huì)被用作一個(gè) JavaScript 變量名或?qū)傩悦?,所以就沒(méi)有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件監(jiān)聽(tīng)器在 DOM 模板中會(huì)被自動(dòng)轉(zhuǎn)換為全小寫(xiě) (因?yàn)?HTML 是大小寫(xiě)不敏感的),所以 v-on:myEvent 將會(huì)變成 v-on:myevent——導(dǎo)致 myEvent 不可能被監(jiān)聽(tīng)到。

因此,我們推薦你始終使用 kebab-case 的事件名


自定義組件的 v-model


2.2.0+ 新增

一個(gè)組件上的 v-model 默認(rèn)會(huì)利用名為 value 的 prop 和名為 input 的事件,但是像單選框、復(fù)選框等類(lèi)型的輸入控件可能會(huì)將 value 特性用于不同的目的。model 選項(xiàng)可以用來(lái)避免這樣的沖突:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

現(xiàn)在在這個(gè)組件上使用 v-model 的時(shí)候:

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

這里的 lovingVue 的值將會(huì)傳入這個(gè)名為 checked 的 prop。同時(shí)當(dāng) <base-checkbox> 觸發(fā)一個(gè) change 事件并附帶一個(gè)新的值的時(shí)候,這個(gè) lovingVue 的屬性將會(huì)被更新。

注意你仍然需要在組件的 props 選項(xiàng)里聲明 checked 這個(gè) prop。


將原生事件綁定到組件


你可能有很多次想要在一個(gè)組件的根元素上直接監(jiān)聽(tīng)一個(gè)原生事件。這時(shí),你可以使用 v-on.native 修飾符:

<base-input v-on:focus.native="onFocus"></base-input>

在有的時(shí)候這是很有用的,不過(guò)在你嘗試監(jiān)聽(tīng)一個(gè)類(lèi)似 <input> 的非常特定的元素時(shí),這并不是個(gè)好主意。比如上述 <base-input> 組件可能做了如下重構(gòu),所以根元素實(shí)際上是一個(gè) <label> 元素:

<label>
  {{ label }}
  <input
    v-bind="$attrs"
    v-bind:value="value"
    v-on:input="$emit('input', $event.target.value)"
  >
</label>

這時(shí),父級(jí)的 .native 監(jiān)聽(tīng)器將靜默失敗。它不會(huì)產(chǎn)生任何報(bào)錯(cuò),但是 onFocus 處理函數(shù)不會(huì)如你預(yù)期地被調(diào)用。

為了解決這個(gè)問(wèn)題,Vue 提供了一個(gè) $listeners 屬性,它是一個(gè)對(duì)象,里面包含了作用在這個(gè)組件上的所有監(jiān)聽(tīng)器。例如:

{
  focus: function (event) { /* ... */ }
  input: function (value) { /* ... */ },
}

有了這個(gè) $listeners 屬性,你就可以配合 v-on="$listeners" 將所有的事件監(jiān)聽(tīng)器指向這個(gè)組件的某個(gè)特定的子元素。對(duì)于類(lèi)似 <input> 的你希望它也可以配合 v-model 工作的組件來(lái)說(shuō),為這些監(jiān)聽(tīng)器創(chuàng)建一個(gè)類(lèi)似下述 inputListeners 的計(jì)算屬性通常是非常有用的:

Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  computed: {
    inputListeners: function () {
      var vm = this
      // `Object.assign` 將所有的對(duì)象合并為一個(gè)新對(duì)象
      return Object.assign({},
        // 我們從父級(jí)添加所有的監(jiān)聽(tīng)器
        this.$listeners,
        // 然后我們添加自定義監(jiān)聽(tīng)器,
        // 或覆寫(xiě)一些監(jiān)聽(tīng)器的行為
        {
          // 這里確保組件配合 `v-model` 的工作
          input: function (event) {
            vm.$emit('input', event.target.value)
          }
        }
      )
    }
  },
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on="inputListeners"
      >
    </label>
  `
})

現(xiàn)在 <base-input> 組件是一個(gè)完全透明的包裹器了,也就是說(shuō)它可以完全像一個(gè)普通的 <input> 元素一樣使用了:所有跟它相同的特性和監(jiān)聽(tīng)器的都可以工作。


.sync 修飾符


2.3.0+ 新增

在有些情況下,我們可能需要對(duì)一個(gè) prop 進(jìn)行“雙向綁定”。不幸的是,真正的雙向綁定會(huì)帶來(lái)維護(hù)上的問(wèn)題,因?yàn)樽咏M件可以修改父組件,且在父組件和子組件都沒(méi)有明顯的改動(dòng)來(lái)源。

這也是為什么我們推薦以 update:myPropName 的模式觸發(fā)事件取而代之。舉個(gè)例子,在一個(gè)包含 title prop 的假設(shè)的組件中,我們可以用以下方法表達(dá)對(duì)其賦新值的意圖:

this.$emit('update:title', newTitle)

然后父組件可以監(jiān)聽(tīng)那個(gè)事件并根據(jù)需要更新一個(gè)本地的數(shù)據(jù)屬性。例如:

<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event"
></text-document>

為了方便起見(jiàn),我們?yōu)檫@種模式提供一個(gè)縮寫(xiě),即 .sync 修飾符:

<text-document v-bind:title.sync="doc.title"></text-document>

注意帶有 .sync 修飾符的 v-bind 不能和表達(dá)式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是無(wú)效的)。取而代之的是,你只能提供你想要綁定的屬性名,類(lèi)似 v-model。

當(dāng)我們用一個(gè)對(duì)象同時(shí)設(shè)置多個(gè) prop 的時(shí)候,也可以將這個(gè) .sync 修飾符和 v-bind 配合使用:

<text-document v-bind.sync="doc"></text-document>

這樣會(huì)把 doc 對(duì)象中的每一個(gè)屬性 (如 title) 都作為一個(gè)獨(dú)立的 prop 傳進(jìn)去,然后各自添加用于更新的 v-on 監(jiān)聽(tīng)器。

將 v-bind.sync 用在一個(gè)字面量的對(duì)象上,例如 v-bind.sync=”{ title: doc.title }”,是無(wú)法正常工作的,因?yàn)樵诮馕鲆粋€(gè)像這樣的復(fù)雜表達(dá)式的時(shí)候,有很多邊緣情況需要考慮。