Javascript VueJS和tinyMCE,自定义指令

Javascript VueJS和tinyMCE,自定义指令,javascript,tinymce,vue.js,Javascript,Tinymce,Vue.js,我一直在努力让VueJS和TinyMCE一起工作。我得出的结论是,使用指令将是一条出路 到目前为止,我已经能够作为一个指令参数传入body,tinyMCE设置内容。然而,我不能让双向绑定工作。我还担心我在tinyMCE api的基础上做的事情是完全错误的 我认为相关的tinyMCE功能是: 及 HTML 不停摆弄 试试这个: // Use JSPM to load dependencies: vue.js 2.1.4, tinymce: 4.5.0 import Vue from 'vue

我一直在努力让VueJS和TinyMCE一起工作。我得出的结论是,使用指令将是一条出路

到目前为止,我已经能够作为一个指令参数传入body,tinyMCE设置内容。然而,我不能让双向绑定工作。我还担心我在tinyMCE api的基础上做的事情是完全错误的

我认为相关的tinyMCE功能是:


HTML 不停摆弄 试试这个:

// Use JSPM to load dependencies: vue.js 2.1.4, tinymce: 4.5.0
import Vue from 'vue/dist/vue';
import tinymce from 'tinymce';

// Local component
var TinymceComponent = {
    template: `<textarea class="form-control">{{ initValue }}</textarea>`,
    props: [ 'initValue', 'disabled' ],
    mounted: function() {
        var vm = this,
            tinymceDict = '/lib/jspm_packages/github/tinymce/tinymce-dist@4.5.1/';

        // Init tinymce
        tinymce.init({
            selector: '#' + vm.$el.id,
            menubar: false,
            toolbar: 'bold italic underline | bullist numlist',
            theme_url: tinymceDict + 'themes/modern/theme.js,
            skin_url: tinymceDict + 'skins/lightgray',
            setup: function(editor) {
                // If the Vue model is disabled, we want to set the Tinymce readonly
                editor.settings.readonly = vm.disabled;

                if (!vm.disabled) {
                    editor.on('blur', function() {
                        var newContent = editor.getContent();

                        // Fire an event to let its parent know
                        vm.$emit('content-updated', newContent);
                    });
                }
            }
        });
    },
    updated: function() {
        // Since we're using Ajax to load data, hence we have to use this hook because when parent's data got loaded, it will fire this hook.
        // Depends on your use case, you might not need this
        var vm = this;

        if (vm.initValue) {
            var editor = tinymce.get(vm.$el.id);
            editor.setContent(vm.initValue);
        }
    }
};

// Vue instance
new Vue({
    ......
    components: {
        'tinymce': TinymceComponent
    }
    ......
});

诀窍是将指令存储在临时变量“that”中,以便您可以从更改事件回调中访问它。

对于Vue.js 2.0,这些指令仅用于应用低级直接DOM操作。他们不再有对Vue实例数据的
引用。(参考号:)

因此,我建议改用
组件

TinymceComponent: HTML(MVC视图)

......
......
流动
  • 首先,通过远程资源(即AJAX)加载数据。已设置
    说明
  • 说明
    通过
    props:initValue
    传递给组件
  • 安装组件时,
    tinymce
    将使用初始描述进行初始化
  • 它还设置了
    on blur
    事件以获取更新的内容
  • 每当用户在编辑器上失去焦点时,就会捕获一个新的内容,并且组件会发出一个事件
    content updated
    ,让家长知道发生了什么事情
  • 在Html上,您已经更新了
    v-On:content
    。由于父级正在侦听
    内容更新
    事件,因此在发出事件时将调用父级方法
    updateDescription
  • !!两个重要的注意事项!!
    • 根据设计,组件具有从父组件到组件的单向绑定。因此,当从Vue实例更新
      description
      时,组件的
      initValue
      属性也应该自动更新
    • 如果我们可以将用户在
      tinymce
      编辑器中键入的任何内容传递回父Vue实例,那就太好了,但是不应该使用双向绑定。这时您需要使用
      $emit
      触发事件并从组件通知父级
    • 您不必在父级中定义函数,只需执行
      v-on:content updated=“updateDescription”
      。您可以通过执行
      v-on:content updated=“description=$event”
      直接更新数据。
      $event
      具有您为组件内的函数定义的参数--
      newContent
      参数

    希望我解释清楚。这整件事花了我两个星期才弄明白

    这是Vue的Tinymce组件。

    了解v型和自定义输入组件也很好:

    Vue.component('tinymce'{
    道具:['value'],
    模板:``,
    方法:{
    updateValue:函数(值){
    console.log(值);
    这个.emit('input',value.trim());
    }
    },
    挂载:函数(){
    var分量=此;
    tinymce.init({
    目标:这个$el.children[0],
    设置:函数(编辑器){
    编辑者:关于('Change',函数(e){
    updateValue(editor.getContent());
    })
    }
    });
    }
    });
    
    现在,TinyMCE周围有一个薄薄的包装,使其更易于在Vue应用程序中使用

    它是开源的,上面有代码

    安装:

     import Editor from '@tinymce/tinyme-vue';
    
    用法:

    <editor api-key="API_KEY" :init="{plugins: 'wordcount'}"></editor>
    
    模板:

    
    

    其中API_KEY是您的API密钥的来源。init部分与默认init语句相同,只是不需要选择器。有关示例,请参见。

    这是正确的方法。您还可以向tinymce控件添加一个“onChange”侦听器,并使用它向父Vue实例发出一个“change”事件,以便您在任何更改时得到通知,而不仅仅是在焦点丢失时。这是迄今为止最好/最简单的解决方案。谢谢
    tinymce.init({
        selector:'#editor',
    });
    
    Vue.directive('editor', {
        twoWay: true,
        params: ['body'],
    
        bind: function () {
            tinyMCE.get('editor').setContent(this.params.body);
            tinyMCE.get('editor').on('change', function(e) {
                alert("changed");
            });
        },
        update: function (value) {
            $(this.el).val(value).trigger('change')
        },
    });
    
    var editor = new Vue({
        el: '#app',
        data: {
            body: 'The message'
        }
    })
    
    Vue.directive('editor', {
      twoWay: true,
      params: ['body'],
    
      bind: function () {
        tinyMCE.get('editor').setContent(this.params.body);
        var that = this;
        tinyMCE.get('editor').on('change', function(e) {
          that.vm.body = this.getContent();
        });
      }
    });
    
    // Use JSPM to load dependencies: vue.js 2.1.4, tinymce: 4.5.0
    import Vue from 'vue/dist/vue';
    import tinymce from 'tinymce';
    
    // Local component
    var TinymceComponent = {
        template: `<textarea class="form-control">{{ initValue }}</textarea>`,
        props: [ 'initValue', 'disabled' ],
        mounted: function() {
            var vm = this,
                tinymceDict = '/lib/jspm_packages/github/tinymce/tinymce-dist@4.5.1/';
    
            // Init tinymce
            tinymce.init({
                selector: '#' + vm.$el.id,
                menubar: false,
                toolbar: 'bold italic underline | bullist numlist',
                theme_url: tinymceDict + 'themes/modern/theme.js,
                skin_url: tinymceDict + 'skins/lightgray',
                setup: function(editor) {
                    // If the Vue model is disabled, we want to set the Tinymce readonly
                    editor.settings.readonly = vm.disabled;
    
                    if (!vm.disabled) {
                        editor.on('blur', function() {
                            var newContent = editor.getContent();
    
                            // Fire an event to let its parent know
                            vm.$emit('content-updated', newContent);
                        });
                    }
                }
            });
        },
        updated: function() {
            // Since we're using Ajax to load data, hence we have to use this hook because when parent's data got loaded, it will fire this hook.
            // Depends on your use case, you might not need this
            var vm = this;
    
            if (vm.initValue) {
                var editor = tinymce.get(vm.$el.id);
                editor.setContent(vm.initValue);
            }
        }
    };
    
    // Vue instance
    new Vue({
        ......
        components: {
            'tinymce': TinymceComponent
        }
        ......
    });
    
    new Vue({
        el: '#some-id',
        data: {
            ......
            description: null
            ......
        },
        components: {
            'tinymce': TinymceComponent
        },
        methods: {
            ......
            updateDescription: function(newContent) {
                this.description = newContent;
            },
            load: function() {
                ......
                this.description = "Oh yeah";
                ......
            }
            ......
        },
        mounted: function() {
            this.load();
        }
    });
    
    <form id="some-id">
        ......
        <div class="form-group">
            <tinymce :init-value="description"
                     v-on:content-updated="updateDescription"
                     :id="description-tinymce"
                     :disabled="false">
            </tinymce>
        </div>
        ......
    </form>
    
    $ npm install @tinymce/tinymce-vue
    
     import Editor from '@tinymce/tinyme-vue';
    
    <editor api-key="API_KEY" :init="{plugins: 'wordcount'}"></editor>