jQuery plugin in Vue component: Cannot pass value to prop

前端 未结 3 739
盖世英雄少女心
盖世英雄少女心 2020-12-11 10:36

I have added the jquery redactor plugin in a vue component. The plugin is working fine but I need to access the html so I can see it in Vue.

I have tried everything

相关标签:
3条回答
  • 2020-12-11 11:21

    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>
    
    0 讨论(0)
  • 2020-12-11 11:23

    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));
        }
    };
    
    0 讨论(0)
  • 2020-12-11 11:32

    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

    0 讨论(0)
提交回复
热议问题