맞춤 이벤트
이 페이지에서는 구성 요소 기본 사항을 읽었다고 가정합니다. 아직 컴포넌트에 대해 잘 모르신다면 먼저 읽어보시길 권합니다.
디렉터리
이벤트 이름
컴포넌트 및 소품과 달리 이벤트 이름에는 자동 대소문자 변환이 없습니다. 대신, 트리거된 이벤트의 이름은 이 이벤트를 수신하는 데 사용된 이름과 정확히 일치해야 합니다. 예를 들어, 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) { /* ... */ },
}
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
修饰符:
注意带有
.sync
修饰符的v-bind
不能和表达式一起使用 (例如v-bind:title.sync=”doc.title + ‘!’
” 是无效的)。取而代之的是,你只能提供你想要绑定的属性名,类似v-model
。
当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync
修饰符和 v-bind
rrreee
.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🎜🎜객체를 사용하여 동시에 여러 prop을 설정할 때.sync
수정v-bind
는 표현식과 함께 사용할 수 없습니다(예:v-bind:title.sync="doc.title + '!'
"는 유효하지 않습니다). . 대신v-model
과 같이 바인딩하려는 속성의 이름만 제공할 수 있습니다. 🎜
v-bind
와 함께 이 .sync
수정자를 사용할 수도 있습니다. 🎜rrreee이것은 문서 개체의 각 속성(예: 제목)을 독립 prop으로 전달한 다음 업데이트를 위해 v-on 리스너를 추가합니다.
will
v-bind.sync
用在一个字面量的对象上,例如v-bind.sync=”{ title: doc.title }”
, 이렇게 복잡한 표현식을 구문 분석할 때 고려해야 할 극단적인 경우가 많기 때문에 제대로 작동하지 않습니다.