From 105888d103c6a2452a586a7a715714da3b65abf2 Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Mon, 18 Jun 2018 20:08:38 +0900 Subject: [PATCH] :bug: bug(directive): fix cannot unbind bug closes #377 --- src/directive.js | 10 +++++++++ src/install.js | 4 ++-- test/unit/issues.test.js | 47 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/directive.js b/src/directive.js index cb9b70c2e..bd09689f1 100644 --- a/src/directive.js +++ b/src/directive.js @@ -16,6 +16,16 @@ export function update (el: any, binding: Object, vnode: any, oldVNode: any): vo t(el, binding, vnode) } +export function unbind (el: any, binding: Object, vnode: any, oldVNode: any): void { + if (!assert(el, vnode)) { return } + + el.textContent = '' + el._vt = undefined + delete el['_vt'] + el._locale = undefined + delete el['_locale'] +} + function assert (el: any, vnode: any): boolean { const vm: any = vnode.context if (!vm) { diff --git a/src/install.js b/src/install.js index 6ac4e473b..750206eeb 100644 --- a/src/install.js +++ b/src/install.js @@ -2,7 +2,7 @@ import { warn } from './util' import extend from './extend' import mixin from './mixin' import component from './component' -import { bind, update } from './directive' +import { bind, update, unbind } from './directive' export let Vue @@ -29,7 +29,7 @@ export function install (_Vue) { extend(Vue) Vue.mixin(mixin) - Vue.directive('t', { bind, update }) + Vue.directive('t', { bind, update, unbind }) Vue.component(component.name, component) // use object-based merge strategy diff --git a/test/unit/issues.test.js b/test/unit/issues.test.js index 0b0791ac6..782d391a1 100644 --- a/test/unit/issues.test.js +++ b/test/unit/issues.test.js @@ -1,5 +1,6 @@ import messages from './fixture/index' import { parse } from '../../src/format' +const compiler = require('vue-template-compiler') describe('issues', () => { let vm, i18n @@ -287,7 +288,7 @@ describe('issues', () => { }) describe('#259', () => { - it('this points to the right', (done) => { + it('this points to the right', done => { const vm = new Vue({ i18n: new VueI18n({ locale: 'en', @@ -314,4 +315,48 @@ describe('issues', () => { done() }) }) + + describe('#377', () => { + it('should be destroyed', done => { + const el = document.createElement('div') + const template = `
+

TIMEOUT : {{ timeout }}

+
+ +
+
+ {{ $t('CANNOT_REPRODUCE_WITHOUT_THIS') }} +
+
` + const { render, staticRenderFns } = compiler.compileToFunctions(template) + const vm = new Vue({ + i18n: new VueI18n({ locale: 'id' }), + data () { + return { timeout: false } + }, + methods: { + startLoading: function () { + this.timeout = true + setTimeout(() => { + this.timeout = false + }, 100) + } + }, + render, + staticRenderFns + }).$mount(el) + + Vue.nextTick(() => { + assert.equal(vm.$refs.el1.outerHTML, '
SHOULD_NOT_DISPLAY_WHEN_TIMEOUT_EQUAL_TRUE
') + vm.startLoading() + delay(50).then(() => { + assert.equal(vm.$refs.el2.outerHTML, '
CANNOT_REPRODUCE_WITHOUT_THIS
') + delay(60).then(() => { + assert.equal(vm.$refs.el1.outerHTML, '
SHOULD_NOT_DISPLAY_WHEN_TIMEOUT_EQUAL_TRUE
') + done() + }) + }) + }) + }) + }) })