VueJS和tinyMCE,自定义指令

开心果

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

到目前为止,我已经能够将主体作为指令参数传递,并且tinyMCE设置内容。但是,我无法通过两种方式进行绑定。我也担心基于tinyMCE api所做的事情完全错误。

我假设相关的tinyMCE函数为:

http://community.tinymce.com/wiki.php/api4:method.tinymce.Editor.setContent

// Sets the content of a specific editor (my_editor in this example)
tinymce.get('my_editor').setContent(data);

http://community.tinymce.com/wiki.php/api4:method.tinymce.Editor.getContent

// Get content of a specific editor:
tinymce.get('content id').getContent()

的HTML

<div id="app">
  <h3>This is the tinyMCE editor</h3>
  <textarea id="editor" v-editor :body="body"></textarea>

  <hr>
  <p>This input field is properly binded</p>
  <input v-model="body">

  <hr>
  <pre>data binding: {{ body }} </pre>
</div>

JS

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'
    }
})

小提琴

https://jsfiddle.net/nf3ftm8f/

David Liang

在Vue.js 2.0中,这些指令仅用于应用低级直接DOM操作。他们不再this引用Vue实例数据。(请参阅:https : //vuejs.org/v2/guide/migration.html#Custom-Directives-simplified

因此,我建议改为使用Component

TinymceComponent:

// 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/[email protected]/';

        // 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
    }
    ......
});

Vue实例(简体)

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();
    }
});

HTML(MVC视图)

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

流量

  1. 首先,数据是通过远程资源(即AJAX)加载的。description得到了一套。
  2. description得到了传下来的通过组件props: initValue
  3. 安装组件后,将tinymce使用初始描述进行初始化。
  4. 它还设置on blur事件以获取更新的内容。
  5. 每当用户失去对编辑器的关注时,就会捕获新内容,并且组件会发出事件content-updated,让父母知道发生了什么事。
  6. 在HTML上,您有v-on:content-updated由于父级正在侦听content-updated事件,因此在发出事件updateDescription时将调用父级方法

!!重要提示!

  • 根据设计,组件具有从父代到组件的1种方式绑定。因此,当description从Vue实例获取更新,组件的initValue属性也应自动更新。
  • 如果我们可以将tinymce编辑器中用户输入的任何内容传递回父Vue实例,但不建议使用2种绑定方式,那就太好了那是您需要$emit触发事件并从组件通知父母的时候。
  • 您不必在parent中定义一个函数并执行v-on:content-updated="updateDescription"您可以直接通过来直接更新数据v-on:content-updated="description = $event"$event有你的组件内部函数定义的参数-该newContent参数。

希望我能解释清楚。这整个过程花了我2个星期才弄清楚!!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章