我具有以下组成部分:
//wrapper component
<template>
<div class="form-group form-group-text">
<label v-if="label" :for="fieldId()">{{ label }}</label>
<tiny-wrapper :key="pk"
class="form-control builderEditor"
:id="id"
:name="fieldName()"
v-model="form[field.key]"
:init="editorSettings"
:content="field.content"
></tiny-wrapper>
</div>
</template>
<script>
import Vue from 'vue'
import BuilderHelper from './builder-helper'
import TinyWrapper from '../tiny-wrapper'
export default Vue.extend({
props: [
'pk',
'title',
'fieldKey',
'field',
'databaseName',
'required',
'disabled',
'options',
'label',
'locale',
'hidden',
],
mixins: [BuilderHelper],
components: {
'tiny-wrapper': TinyWrapper,
},
computed: {
editorSettings() {
return {
// editor_selector: '.builderEditor',
selector: '#' + this.id,
menubar: '',
toolbar: 'bold italic | link',
height: 150,
contextmenu: 'bold italic | link',
forced_root_block: false,
invalid_elements: 'script',
statusbar: false,
resize: false,
browser_spellcheck: true,
}
}
},
})
</script>
和
// child component
<template>
<textarea :id="id" ref="editor" class="form-control" :class="classList" :value="content"></textarea>
</template>
<script>
import Vue from 'vue'
import 'tinymce/tinymce'
export default Vue.extend({
props: {
init: {
type: Object,
},
id: {
type: String,
required: true,
},
classList: {
type: String,
},
value: {
type: String,
}
},
data: function () {
return {
content: '',
tinyOptions: {},
}
},
mounted() {
// this.content = this.value
this.tinyOptions = Object.assign(window.tinyMCESettings, {
selector: '#' + this.id,
init_instance_callback: this.initInstanceCallback,
}, this.init)
tinymce.init(this.tinyOptions)
},
methods: {
initInstanceCallback(editor) {
editor.setContent(this.value)
editor.on('change', e => {
this.update(editor)
})
editor.on('keyup', e => {
this.update(editor)
})
this.$parent.$on('reset', () => editor.setContent(''))
},
update(editor) {
this.content = editor.getContent()
this.$emit('input', this.content)
},
}
})
</script>
我在文档中使用了10次包装组件。
每个包装器组件的子组件中的数据都相同,状态由最后实例化的子组件中的数据共享/覆盖。我在做什么错了?
答案 0 :(得分:1)
我无法从问题中看出这是否是您面临的问题,但这是 a 问题。
首次在tinyOptions
函数中创建data
时,便为其分配了一个新的空对象。那也行。该组件的每个实例将对该属性具有自己的独特对象。什么都没有分享。
但是,我们点击了
this.tinyOptions = Object.assign(window.tinyMCESettings, {
selector: '#' + this.id,
init_instance_callback: this.initInstanceCallback,
}, this.init)
这将一个不同的对象分配给tinyOptions
属性,因此原始的空对象将被丢弃。就其本身而言,这将不是问题。但是,让我们考虑一下这里发生了什么。上面的代码大致等效于以下代码:
window.tinyMCESettings.selector = '#' + this.id
window.tinyMCESettings.init_instance_callback = this.initInstanceCallback,
for (const prop in this.init) {
window.tinyMCESettings[prop] = this.init[prop]
}
this.tinyOptions = window.tinyMCESettings
所以它要做的是更新对象window.tinyMCESettings
的属性,然后将该对象分配给tinyOptions
属性。
所有组件都将捕获相同的window.tinyMCESettings
对象并更改其属性。尽管每个组件都有其自己独特的tinyOptions
属性,但所有这些属性最终都指向同一对象。
一种解决方案是将所有内容复制到一个新的空对象中:
this.tinyOptions = Object.assign({}, window.tinyMCESettings, {
selector: '#' + this.id,
init_instance_callback: this.initInstanceCallback,
}, this.init)
我个人将使用...
语法:
this.tinyOptions = {
...window.tinyMCESettings,
selector: '#' + this.id,
init_instance_callback: this.initInstanceCallback,
...this.init
}
由您选择。
要注意的关键是window.tinyMCESettings
的属性现在正在复制到新对象,而不仅仅是直接使用该对象。