jQuery Vue 组件中的插件:无法将值传递给 prop

jQuery plugin in Vue component: Cannot pass value to prop

我在 vue 组件中添加了 jquery redactor 插件。该插件工作正常,但我需要访问 html 以便我可以在 Vue 中看到它。

我已经尝试了所有我能想到的方法,方法,计算属性,但我找不到办法。这特别棘手,因为 Redactor 将新的 html 添加到 dom 中,我需要从添加的 html.

中获取数据

目前我遇到了这个错误,this.$emit is not a function。我需要将 .redactor-editor 的 html 值放入道具中,以便它在 vue 数据中可用。 var textContent 在控制台中正确打印出来,但我无法在 prop 中显示它。非常感谢任何帮助。

组件

<template>
  <div>
    <textarea class="form-control question-create-editor" id="question_description" placeholder="Go wild with all the details here - make image upload work" rows="3">
  </div>
</template>

<script>
  export default {
    props: ['redactorValue'],
    mounted: function(){
          $('#question-create-form .question-create-editor').redactor({
            imageUpload:'/urlGoesHereBro/',
            plugins: ['video', 'imagemanager', 'counter', 'limiter'],
            buttonsHide:['html', 'formatting', 'deleted', 'indent', 'outdent', 'alignment', 'horizontalrule']
          });
    },
    computed: {
      redactorValue: function(){
        $('#question-create-form .redactor-editor').on('keyup', function(){
          var textContent = $('#question-create-form .redactor-editor').html();
          console.log( 'textContent = ' + textContent );
          this.$emit('redactorValue', textContent);
        });
      }
    }
};

HTML

<vueredactor></vueredactor>

this.$emit is not a function 问题是因为 this 指向 window

我还把 keyup 定义移到了 mounted

export default {
    data(){
        return {
            redactorValue: null
        }
    },
    mounted: function(){
          $('#question-create-form .question-create-editor').redactor({
            imageUpload:'/urlGoesHereBro/',
            plugins: ['video', 'imagemanager', 'counter', 'limiter'],
            buttonsHide:['html', 'formatting', 'deleted', 'indent', 'outdent', 'alignment', 'horizontalrule']
          });

          $('#question-create-form .redactor-editor').on('keyup', function(){
              this.redactorValue = $('#question-create-form .redactor-editor').html();
          }.bind(this));
    }
};

只是为了添加到@BertEvans 精湛的答案。这是一个将 props 和 v-model 重新添加到组合中的解决方案。这允许您将编校内容作为一个值获取,并可以访问根目录中的该数据。

组件

<template>
  <div>
    <textarea class="form-control question-create-editor" id="question_description" placeholder="Go wild with all the details here - make image upload work" rows="3">
  </div>
</template>

<script>
  export default {
      props: ['value'],
      data(){
          return {
              redactorValue: null
          }
      },
      mounted: function(){
            $('#question-create-form .question-create-editor').redactor({
              imageUpload:'/urlGoesHereBro/',
              plugins: ['video', 'imagemanager', 'counter', 'limiter'],
              buttonsHide:['html', 'formatting', 'deleted', 'indent', 'outdent', 'alignment', 'horizontalrule']
            });

            $('#question-create-form .redactor-editor').on('blur', function(){
                this.redactorValue = $('#question-create-form .redactor-editor').html();
                this.$emit('input', this.redactorValue);
            }.bind(this));
      }
  };
</script>

JS

Vue.component('vueredactor', require('./components/redactor.vue'));

var App = new Vue({
                el: '#app',
                data: {
                  redactorContent: null
                }
            });

HTML

<div id="app>
    <vueredactor v-model="redactorContent"></vueredactor>
</div>

这是我使用来自 Imperavi 的 Redactor Editor 3 的 VueJS 2 组件。 在同一视图中支持多个编辑器,但编辑器需要唯一 name/id。 不需要 jQuery 库。

RedactorEditor.vue

<template>
<div class="redactor">
    <textarea ref="redactorContainer" :id="id" :value="value"></textarea>
</div>
</template>
<script>
    import 'addons/redactor/css/redactor.css'
    import 'addons/redactor/redactor'
    //import 'addons/redactor/plugins/wordslimiter/wordslimiter'
    //import 'addons/redactor/plugins/beyondgrammar/beyondgrammar'

    export default {
        name: 'redactor-editor',
        props: {
            value: {
                required: true,
                twoWay: true
            },
            id: {
                type: String,
                default: 'editor'
            },
            minHeight: {
                type: String,
                default: '300px',
            },
            maxHeight: {
                type: String,
                default: '800px',
            },
            buttons: {
                type: Array,
                default: () => ['html', 'format', 'bold', 'italic', 'deleted', 'lists', 'link']
            },
            plugins: {
                type: Array,
                default: () => []
            },
            wordslimiter: {
                type: Number,
                default: 0
            },
            beyondgrammarSettings: {
                type: Object,
                default: null
            }
        },
        data () {
            return {
                propValue: this.value
            }
        },
        created () {
            this.isChanging = false;
            this.app = null;
        },
        mounted () {
            var me = this;
            this.app = $R(this.$refs.redactorContainer, {
                style: true,
                breakline: false,
                shortcodes: false,
                pasteClean: true,
                autoparseImages: false,
                autoparseVideo: false,
                multipleUpload: false,
                clipboardUpload: false,
                pasteLinkTarget: '_blank',
                placeholder: 'Write your text here ...',
                minHeight: this.minHeight,
                maxHeight: this.maxHeight,
                buttons: this.buttons,
                plugins: this.plugins,
                wordslimiter: this.wordslimiter,
                beyondgrammar: this.beyondgrammarSettings,
                callbacks: {
                    start: function() {
                        // set initial data
                        this.source.setCode(me.propValue);
                    },
                    blur: function (e) {
                        // keyup not work with last typed text, fix sync with v-model by using blur
                        if (!me.isChanging) {
                            me.isChanging = true;
                            var code = this.source.getCode()
                            me.propValue = (code === null || code.length === 0 ? null : code);
                            me.$emit('input', me.propValue);
                            me.$nextTick(function() {
                                me.isChanging = false;
                            });
                        }
                    }
                }
            })
        },
        destroyed () {
            this.app = $R(this.$refs.redactorContainer)
            if (this.app) {
                this.app.destroy()
            }
        }
    };
</script>

App.vue

import Vue from 'vue'
import RedactorEditor from './components/RedactorEditor.vue'

// app
const app = new Vue({
    el: '#my-app',
    data: {
       editorButtons: ['undo', 'redo', 'bold', 'italic', 'lists', 'link'],
       editorPlugins: [],
       beyondgrammarSettings: {}
       editorHTMLContent: '',
    },
    components: {
        RedactorEditor
    }
}

HTML 用法

<redactor-editor
    v-model="editorHTMLContent"
    :text-value="editorHTMLContent"
    :id="'editor_1"
    :name="'editor_1"
    :plugins="editorPlugins"
    :buttons="editorButtons"
></redactor-editor>

使用 vee-validate 的自定义验证器示例:https://gist.github.com/matinfo/52214f7f34ce6b746b483f0f92e6b5e5

任何想以其他方式举办活动的人

即使你想使用 $emit 还有另一种方法使用 EventBus 只需创建一个事件-bus.js 文件并写入此

import Vue from 'vue';
const EventBus  = new Vue();
export default EventBus;

将其导入您的组件后

import EventBus from '/your path/event-bus.js';

然后你可以发射它

EventBus.emit('myevent','I am boy');

要接收它,您不必在接收组件 prop 上指定事件名称

你可以做到这一点

EventBus.on('myevent',value=>{
console.log(value) // I am boy will be displayed
})