关于vue.js:VueJs:Textarea输入绑定

VueJs: Textarea input binding

我试图弄清楚如何从组件内部检测textarea上值的变化。

对于输入,我们可以简单地使用

1
2
3
4
<input
  :value="value"
  @input="update($event.target.value)"
>

但是在textarea上,这将无法正常工作。

我正在使用的是CKEditor组件,当父组件(附加到此子组件)的模型值更新时,它应该更新所见即所得的内容。

我的Editor组件当前如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<template>
   
        <textarea :id="id" v-model="input"></textarea>
   
</template>


    export default {
        props: {
            value: {
                type: String,
                default: ''
            },
            id: {
                type: String,
                required: false,
                default: 'editor'
            }
        },
        data() {
            return {
                input: this.$slots.default ? this.$slots.default[0].text : '',
                config: {
                    ...
                }
            }
        },
        watch: {
            input(value) {
                this.update(value);
            }
        },
        methods: {
            update(value) {
                CKEDITOR.instances[this.id].setData(value);
            },
            fire(value) {
                this.$emit('input', value);
            }
        },
        mounted () {
            CKEDITOR.replace(this.id, this.config);
            CKEDITOR.instances[this.id].setData(this.input);
            this.fire(this.input);
            CKEDITOR.instances[this.id].on('change', () => {
                this.fire(CKEDITOR.instances[this.id].getData());
            });
        },
        destroyed () {
            if (CKEDITOR.instances[this.id]) {
                CKEDITOR.instances[this.id].destroy()
            }
        }
    }

我将其包含在父组件中

1
2
3
4
<html-editor
    v-model="fields.body"
    id="body"
></html-editor>

但是,只要父组件的模型值发生更改-它不会触发观察程序-实际上就不会更新编辑器的窗口。

当父组件的模型fields.body更新时,我只需要调用update()方法。

关于我该如何处理的任何指示?


这是需要解密的代码,但是我要做的是将文本区域和WYSIWYG HTML窗口分解为两个不同的组件,然后让父级同步值,因此:

TextArea组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template id="editor">
  <textarea :value="value" @input="$emit('input', $event.target.value)" rows="10" cols="50"></textarea>
</template>

/**
 *  Editor TextArea
 */
Vue.component('editor', {
  template: '#editor',
  props: {
    value: {
      default: '',
      type: String
    }
  }
});

我在这里所做的所有事情都是在输入更改时将输入发送回父级,我将输入用作事件名称,将value用作属性,以便可以在编辑器上使用v-model。 现在,我只需要一个wysiwyg窗口来显示代码:

所见即所得窗口:

1
2
3
4
5
6
7
8
9
10
11
12
/**
 * WYSIWYG window
 */
Vue.component('wysiwyg', {
  template: ``,
  props: {
    html: {
      default: '',
      type: String
    }
  }
});

没什么可做的,它只是呈现作为道具传递的HTML。

最后,我只需要在组件之间同步值:

1
2
3
4
5
6
7
8
9
10
  <wysiwyg :html="value"></wysiwyg>
  <editor v-model="value"></editor>


new Vue({
  el: '#app',
  data: {
    value: 'Hello World'
  }
})

现在,当编辑器更改时,它将事件发回给父级,父级将更新value并依次触发所见即所得窗口中的更改。 这是整个过程:https://jsfiddle.net/Lnpmbpcr/