diff --git a/src/mixins/id.js b/src/mixins/id.js index 10b4ded14c6..fe8066e27ba 100644 --- a/src/mixins/id.js +++ b/src/mixins/id.js @@ -1,6 +1,7 @@ /* * SSR Safe Client Side ID attribute generation - * + * id's can only be generated client side, after mount. + * this._uid is not synched between server and client. */ export default { @@ -10,21 +11,35 @@ export default { default: null } }, - methods: { - safeId (suffix = '') { - const id = this.id || this.localId_ || null - if (!id) { - return null - } - suffix = String(suffix).replace(/\s+/g, '_') - return suffix ? id + '_' + suffix : id + data () { + return { + localId_: null } }, + mounted () { + // mounted only occurs client side + this.$nextTick(() => { + // Update dom with auto ID after dom loaded to prevent + // SSR hydration errors. + this.localId_ = `__BVID__${this._uid}` + }) + }, computed: { - localId_ () { - if (!this.$isServer && !this.id && typeof this._uid !== 'undefined') { - return '__BVID__' + this._uid + safeId () { + // Computed property that returns a dynamic function for creating the ID. + // Reacts to changes in both .id and .localId_ And regens a new function + const id = this.id || this.localId_ + + // We return a function that accepts an optional suffix string + // So this computed prop looks and works like a method!!! + const fn = (suffix) => { + if (!id) { + return null + } + suffix = String(suffix || '').replace(/\s+/g, '_') + return suffix ? id + '_' + suffix : id } + return fn } } }