VueJs:文本区域输入绑定

Posted

技术标签:

【中文标题】VueJs:文本区域输入绑定【英文标题】:VueJs: Textarea input binding 【发布时间】: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 textarea 值只使用v-modelvuejs.org/v2/guide/forms.html#Multiline-text 【参考方案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,这样您就可以提取共享状态,而不是尝试自己在组件之间发出和同步状态。 我最终使用了事件处理程序 - 当父模型更改时,我触发事件 - 从编辑器中捕获 - 然后执行更新。

以上是关于VueJs:文本区域输入绑定的主要内容,如果未能解决你的问题,请参考以下文章

xd区域文本在哪

无法正则表达式文本区域,但如果它是输入则可以

用于文本区域的 Bootstrap 5 浮动标签与滚动输入重叠

Javascript / jQuery 获取我正在输入的文本区域的 id [重复]

MSER+NMS文本区域检测

用于类似***的输入文本区域的JQuery?文本-​​>HTML