【问题标题】:VueJs: Textarea input bindingVueJs:文本区域输入绑定
【发布时间】:2017-12-13 04:37:36
【问题描述】:

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

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

<input
  :value="value"
  @input="update($event.target.value)"
>

但是在 textarea 上这不起作用。

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

我的Editor 组件目前看起来像这样:

<template>
    <div class="editor" :class="groupCss">
        <textarea :id="id" v-model="input"></textarea>
    </div>
</template>

<script>
    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()
            }
        }
    }
</script>

我将它包含在父组件中

<html-editor
    v-model="fields.body"
    id="body"
></html-editor>

然而,每当父组件的模型值发生变化时——它不会触发观察者——实际上不会更新编辑器的窗口。

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

关于我如何处理它的任何指针?

【问题讨论】:

标签: vue.js vuejs2 vue-component


【解决方案1】:

要破译的代码相当多,但我要做的是将文本区域和所见即所得 HTML 窗口分解为两个不同的组件,然后让父级同步值,所以:

TextArea 组件:

<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 window
 */
Vue.component('wysiwyg', {
  template: `<div v-html="html"></div>`,
  props: {
    html: {
      default: '',
      type: String
    }
  }
}); 

那里没什么大不了的,它只是渲染作为道具传递的 HTML。

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

<div id="app">
  <wysiwyg :html="value"></wysiwyg>
  <editor v-model="value"></editor>
</div>

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

现在,当编辑器更改时,它会将事件发送回父级,父级会更新value,然后在所见即所得窗口中触发该更改。以下是全部内容:https://jsfiddle.net/Lnpmbpcr/

【讨论】:

  • 谢谢@craig_h - 我会试一试
  • 嗯 - 我认为它不会起作用,因为所见即所得也需要在更新内容时发出 input - 目前它只会在您输入 @ 时更新 wysiwyg 987654331@,恐怕不是我想要的。还是谢谢。
  • 嗯,好的,在这种情况下,我建议您查看vuex,这样您就可以提取共享状态,而不是尝试自己在组件之间发出和同步状态。
  • 我最终使用了事件处理程序 - 当父模型更改时,我触发事件 - 从编辑器中捕获 - 然后执行更新。
猜你喜欢
  • 1970-01-01
  • 2019-07-09
  • 2015-06-08
  • 2018-04-01
  • 2016-11-29
  • 2011-01-07
  • 2015-01-22
  • 1970-01-01
  • 2017-02-13
相关资源
最近更新 更多