Skip to content

Commit e3768a5

Browse files
committed
Auto-generate unique key so that Vue will diff the component/directive elements correctly. This fixes Polyconseil#29
1 parent 7aca4f2 commit e3768a5

File tree

5 files changed

+63
-0
lines changed

5 files changed

+63
-0
lines changed

src/component.js

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import translate from './translate'
2+
import uuid from './uuid'
23

34

45
/**
@@ -74,6 +75,12 @@ export default {
7475
},
7576

7677
render: function (createElement) {
78+
// this is to fix the problem of usage with v-if, see #29
79+
// we should auto-generate unique key if user hasn't define one
80+
if (!this.$vnode.key) {
81+
this.$vnode.key = uuid()
82+
}
83+
7784
// The text must be wraped inside a root HTML element, so we use a <span> (by default).
7885
// https://github.com/vuejs/vue/blob/a4fcdb/src/compiler/parser/index.js#L209
7986
return createElement(this.tag, [this.translation])

src/directive.js

+7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import interpolate from './interpolate'
22
import translate from './translate'
33
import { _Vue } from './localVue'
4+
import uuid from './uuid'
45

56

67
const updateTranslation = (el, binding, vnode) => {
@@ -49,6 +50,12 @@ export default {
4950

5051
bind (el, binding, vnode) {
5152

53+
// this is to fix the problem of usage with v-if, see #29
54+
// we should auto-generate unique key if user hasn't define one
55+
if (!vnode.key) {
56+
vnode.key = uuid()
57+
}
58+
5259
// Get the raw HTML and store it in the element's dataset (as advised in Vue's official guide).
5360
// Note: not trimming the content here as it should be picked up as-is by the extractor.
5461
let msgid = el.innerHTML

src/uuid.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* eslint-disable */
2+
3+
// from https://gist.github.com/jcxplorer/823878
4+
export default function uuid() {
5+
var uuid = "", i, random;
6+
for (i = 0; i < 32; i++) {
7+
random = Math.random() * 16 | 0;
8+
9+
if (i == 8 || i == 12 || i == 16 || i == 20) {
10+
uuid += "-"
11+
}
12+
uuid += (i == 12 ? 4 : (i == 16 ? (random & 3 | 8) : random)).toString(16);
13+
}
14+
return uuid;
15+
}

test/specs/component.spec.js

+17
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,23 @@ describe('translate component tests', () => {
168168
// }).to.throw('`translate-n` and `translate-plural` attributes must be used together: %{ n } car.')
169169
// })
170170

171+
it('supports conditional rendering such as v-if, v-else-if, v-else', (done) => {
172+
Vue.config.language = 'en_US'
173+
let vm = new Vue({
174+
template: `
175+
<translate v-if="show">Pending</translate>
176+
<translate v-else>Hello %{ name }</translate>
177+
`,
178+
data: {show: true, name: 'John Doe'},
179+
}).$mount()
180+
expect(vm.$el.innerHTML).to.equal('Pending')
181+
vm.show = false
182+
vm.$nextTick(function () {
183+
expect(vm.$el.innerHTML).to.equal('Hello John Doe')
184+
done()
185+
})
186+
})
187+
171188
})
172189

173190
describe('translate component tests for interpolation', () => {

test/specs/directive.spec.js

+17
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,21 @@ describe('translate directive tests', () => {
161161
})
162162
})
163163

164+
it('supports conditional rendering such as v-if, v-else-if, v-else', (done) => {
165+
Vue.config.language = 'en_US'
166+
let vm = new Vue({
167+
template: `
168+
<div v-if="show" v-translate>Pending</div>
169+
<div v-else v-translate>Hello <strong>%{ name }</strong></div>
170+
`,
171+
data: {show: true, name: 'John Doe'},
172+
}).$mount()
173+
expect(vm.$el.innerHTML).to.equal('Pending')
174+
vm.show = false
175+
vm.$nextTick(function () {
176+
expect(vm.$el.innerHTML).to.equal('Hello <strong>John Doe</strong>')
177+
done()
178+
})
179+
})
180+
164181
})

0 commit comments

Comments
 (0)