jQuery plugin in Vue component: Cannot pass value to prop

只谈情不闲聊 提交于 2019-11-28 12:52:38

The this.$emit is not a function issue is because this is pointing to the window.

Also I moved the keyup definition into 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));
    }
};

Just to add to @BertEvans superb answer. Here is a solution that adds props and v-model back into the mix. This allows you to get the redactor content as a value and have access to that data in the root.

Component

<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>

Here my working VueJS 2 component with Redactor Editor 3 from Imperavi. Support multi-editor in same view, but editor need unique name/id. Not require jQuery library.

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 usage

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

Example with custom Validator using vee-validate: https://gist.github.com/matinfo/52214f7f34ce6b746b483f0f92e6b5e5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!