You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/v2/guide/components-edge-cases.md
+63-1
Original file line number
Diff line number
Diff line change
@@ -173,7 +173,69 @@ So far, you've seen uses of `$emit`, listened to with `v-on`, but Vue instances
173
173
- Listen for an event only once with `$once(eventName, eventHandler)`
174
174
- Stop listening for an event with `$off(eventName, eventHandler)`
175
175
176
-
You normally won't have to use these, but they're available for cases when you need to manually listen for events on a component instance. To learn more about their usage, check out the API for [Events Instance Methods](https://vuejs.org/v2/api/#Instance-Methods-Events).
176
+
You normally won't have to use these, but they're available for cases when you need to manually listen for events on a component instance. They can also be useful as a code organization tool. For example, you may often see this pattern for integrating a 3rd-party library:
177
+
178
+
```js
179
+
// Attach the datepicker to an input once
180
+
// it's mounted to the DOM.
181
+
mounted:function () {
182
+
// Pikaday is a 3rd-party datepicker library
183
+
this.picker=newPikaday({
184
+
field:this.$refs.input,
185
+
format:'YYYY-MM-DD'
186
+
})
187
+
},
188
+
// Right before the component is destroyed,
189
+
// also destroy the datepicker.
190
+
beforeDestroy:function () {
191
+
this.picker.destroy()
192
+
}
193
+
```
194
+
195
+
This has two potential issues:
196
+
197
+
- It requires saving the `picker` to the component instance, when it's possible that only lifecycle hooks need access to it. This isn't terrible, but it could be considered clutter.
198
+
- Our setup code is kept separate from our cleanup code, making it more difficult to programmatically clean up anything we set up.
199
+
200
+
You could resolve both issues with a programmatic listener:
201
+
202
+
```js
203
+
mounted:function () {
204
+
var picker =newPikaday({
205
+
field:this.$refs.input,
206
+
format:'YYYY-MM-DD'
207
+
})
208
+
209
+
this.$once('hook:beforeDestroy', function () {
210
+
picker.destroy()
211
+
})
212
+
}
213
+
```
214
+
215
+
Using this strategy, we could even use Pikaday with several input elements, with each new instance automatically cleaning up after itself:
216
+
217
+
```js
218
+
mounted:function () {
219
+
this.attachDatepicker('startDateInput')
220
+
this.attachDatepicker('endDateInput')
221
+
},
222
+
methods: {
223
+
attachDatepicker:function (refName) {
224
+
var picker =newPikaday({
225
+
field:this.$refs[refName],
226
+
format:'YYYY-MM-DD'
227
+
})
228
+
229
+
this.$once('hook:beforeDestroy', function () {
230
+
picker.destroy()
231
+
})
232
+
}
233
+
}
234
+
```
235
+
236
+
See [this fiddle](https://jsfiddle.net/chrisvfritz/1Leb7up8/) for the full code. Note, however, that if you find yourself having to do a lot of setup and cleanup within a single component, the best solution will usually be to create more modular components. In this case, we'd recommend creating a reusable `<input-datepicker>` component.
237
+
238
+
To learn more about programmatic listeners, check out the API for [Events Instance Methods](https://vuejs.org/v2/api/#Instance-Methods-Events).
177
239
178
240
<pclass="tip">Note that Vue's event system is different from the browser's <ahref="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget">EventTarget API</a>. Though they work similarly, <code>$emit</code>, <code>$on</code>, and <code>$off</code> are <strong>not</strong> aliases for <code>dispatchEvent</code>, <code>addEventListener</code>, and <code>removeEventListener</code>.</p>
0 commit comments