맞춤 이벤트


이 페이지에서는 구성 요소 기본 사항을 읽었다고 가정합니다. 아직 컴포넌트에 대해 잘 모르신다면 먼저 읽어보시길 권합니다.


디렉터리


이벤트 이름


컴포넌트 및 소품과 달리 이벤트 이름에는 자동 대소문자 변환이 없습니다. 대신, 트리거된 이벤트의 이름은 이 이벤트를 수신하는 데 사용된 이름과 정확히 일치해야 합니다. 예를 들어, camelCase 이름이 있는 이벤트가 트리거되면

this.$emit('myEvent')

이 이름의 케밥 케이스 버전을 듣는 것은 아무런 효과가 없습니다.

<!-- 没有效果 -->
<my-component v-on:my-event="doSomething"></my-component>

구성 요소 및 소품과 달리 이벤트 이름은 JavaScript로 사용되지 않습니다. 변수 이름이나 속성 이름이므로 camelCase나 PascalCase를 사용할 이유가 없습니다. 그리고 v-on 이벤트 리스너는 DOM 템플릿에서 자동으로 모두 소문자로 변환됩니다(HTML은 대소문자를 구분하지 않기 때문). 따라서 v-on:myEvent는 다음과 같이 됩니다. v-on:myevent - myEvent를 모니터링할 수 없게 만듭니다. v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。

因此,我们推荐你始终使用 kebab-case 的事件名


自定义组件的 v-model


2.2.0+ 新增

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的model 选项可以用来避免这样的冲突:

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)"
    >
  `
})

现在在这个组件上使用 v-model 的时候:

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

这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 <base-checkbox> 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的属性将会被更新。

注意你仍然需要在组件的 props 选项里声明 checked 这个 prop。


将原生事件绑定到组件


你可能有很多次想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 v-on.native

따라서 🎜항상 kebab-case 이벤트 이름🎜을 사용하는 것이 좋습니다. 🎜🎜🎜🎜

🎜🎜Custom 컴포넌트의 v-model🎜🎜🎜🎜🎜🎜2.2.0+ 컴포넌트 코드에 🎜🎜🎜 추가>v-model 는 기본적으로 value라는 prop과 input이라는 이벤트를 사용하지만 라디오 버튼, 확인란 등과 같은 유형은 다른 목적에 대한 >value 속성 🎜. 이러한 충돌을 피하기 위해 model 옵션을 사용할 수 있습니다. 🎜
<base-input v-on:focus.native="onFocus"></base-input>
🎜이제 이 구성 요소에서 v-model을 사용하는 경우: 🎜
<label>
  {{ label }}
  <input
    v-bind="$attrs"
    v-bind:value="value"
    v-on:input="$emit('input', $event.target.value)"
  >
</label>
🎜여기 lovingVue code>의 값은 checked라는 prop에 전달됩니다. 동시에 <base-checkbox>가 새로운 값으로 change 이벤트를 트리거하면 이 lovingVue의 속성이 업데이트됩니다. . 🎜🎜🎜구성요소의 props 옵션에서 checked prop을 선언해야 한다는 점에 유의하세요. 🎜🎜🎜🎜🎜

🎜🎜네이티브 이벤트를 구성 요소에 바인딩 🎜🎜🎜🎜🎜 구성 요소의 루트 요소에서 직접 네이티브 이벤트를 듣고 싶은 경우가 많습니다. 이때 v-on.native 수정자를 사용할 수 있습니다: 🎜
{
  focus: function (event) { /* ... */ }
  input: function (value) { /* ... */ },
}

이 기능은 때때로 유용할 수 있지만 <input>과 같은 매우 구체적인 요소를 듣고자 할 때는 좋은 생각이 아닙니다. 예를 들어 위의 <base-input> 구성 요소는 다음과 같이 리팩터링되었을 수 있으므로 루트 요소는 실제로 <label> 요소입니다. <input> 的非常特定的元素时,这并不是个好主意。比如上述 <base-input> 组件可能做了如下重构,所以根元素实际上是一个 <label> 元素:

Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  computed: {
    inputListeners: function () {
      var vm = this
      // `Object.assign` 将所有的对象合并为一个新对象
      return Object.assign({},
        // 我们从父级添加所有的监听器
        this.$listeners,
        // 然后我们添加自定义监听器,
        // 或覆写一些监听器的行为
        {
          // 这里确保组件配合 `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>
  `
})

这时,父级的 .native 监听器将静默失败。它不会产生任何报错,但是 onFocus 处理函数不会如你预期地被调用。

为了解决这个问题,Vue 提供了一个 $listeners 属性,它是一个对象,里面包含了作用在这个组件上的所有监听器。例如:

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

有了这个 $listeners 属性,你就可以配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素。对于类似 <input> 的你希望它也可以配合 v-model 工作的组件来说,为这些监听器创建一个类似下述 inputListeners 的计算属性通常是非常有用的:

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

现在 <base-input> 组件是一个完全透明的包裹器了,也就是说它可以完全像一个普通的 <input> 元素一样使用了:所有跟它相同的特性和监听器的都可以工作。


.sync 修饰符


2.3.0+ 新增

在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源。

这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之。举个例子,在一个包含 title prop 的假设的组件中,我们可以用以下方法表达对其赋新值的意图:

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

然后父组件可以监听那个事件并根据需要更新一个本地的数据属性。例如:

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

为了方便起见,我们为这种模式提供一个缩写,即 .sync 修饰符:

rrreee

注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的属性名,类似 v-model

当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bindrrreee

At 이번에는 상위 레벨 .native 리스너가 자동으로 실패합니다. 오류는 생성되지 않지만 onFocus 핸들러는 예상대로 호출되지 않습니다. 🎜🎜이 문제를 해결하기 위해 Vue는 이 구성 요소에서 작동하는 모든 리스너를 포함하는 개체인 $listeners 속성을 ​​제공합니다. 예: 🎜rrreee🎜이 $listeners 속성을 ​​사용하면 v-on="$listeners"를 사용하여 모든 이벤트 리스너가 이 구성 요소의 특정 부분을 가리킬 수 있습니다. 특정 하위 요소. v-model과 함께 작업하려는 <input>와 같은 구성 요소의 경우 이러한 리스너에 대해 다음과 같은 inputListeners<를 생성합니다. /code의 계산된 속성 >는 종종 매우 유용합니다. 🎜rrreee🎜이제 <base-input> 구성 요소는 완전히 투명한 래퍼이므로 일반 <와 똑같이 사용할 수 있습니다. code> 요소: 동일한 속성과 리스너가 모두 작동합니다. 🎜🎜
🎜

.sync 수정자


🎜2.3.0+ New 🎜
🎜In some In some 경우에 따라 prop에 대해 "양방향 바인딩"을 수행해야 할 수도 있습니다. 불행하게도 진정한 양방향 바인딩은 하위 구성 요소가 상위 또는 하위 구성 요소의 명백한 변경 소스 없이 상위 구성 요소를 수정할 수 있기 때문에 유지 관리 문제를 발생시킵니다. 🎜🎜이 때문에 update:myPropName 모드를 사용하여 이벤트를 트리거하는 것이 좋습니다. 예를 들어 title prop이 포함된 가상 구성 요소에서 다음을 사용하여 새 값을 할당하려는 의도를 표현할 수 있습니다. 🎜rrreee🎜 그런 다음 상위 구성 요소는 해당 이벤트를 수신하고 필요에 따라 업데이트할 수 있습니다. 로컬 데이터 속성. 예: 🎜rrreee🎜편의를 위해 이 모드에 대한 약어인 .sync를 제공합니다. 수정자: 🎜rrreee
🎜.sync 수정 v-bind는 표현식과 함께 사용할 수 없습니다(예: v-bind:title.sync="doc.title + '!' "는 유효하지 않습니다). . 대신 v-model과 같이 바인딩하려는 속성의 이름만 제공할 수 있습니다. 🎜
🎜객체를 사용하여 동시에 여러 prop을 설정할 때 v-bind와 함께 이 .sync 수정자를 사용할 수도 있습니다. 🎜rrreee

이것은 문서 개체의 각 속성(예: 제목)을 독립 prop으로 전달한 다음 업데이트를 위해 v-on 리스너를 추가합니다.

will v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”, 이렇게 복잡한 표현식을 구문 분석할 때 고려해야 할 극단적인 경우가 많기 때문에 제대로 작동하지 않습니다.