Перенос библиотеки JS в компонент Vue

#javascript #vue.js #vuejs2

#javascript #vue.js #vuejs2

Вопрос:

Мне нужно знать, какая наилучшая практика для переноса библиотеки JS DOM в Vue. В качестве примера я буду использовать EditorJS.

 <template>
    <div :id="holder"></div>
</template>

import Editor from '@editorjs/editorjs'

export default {
  name: "editorjs-wrapper",
  props: {
    holder: {
      type: String,
      default: () => {return "vue-editor-js"},
      required: true
    }
  },
  data(){
    return {
        editor: null
    };
  },
  methods: {
    init_editor(){
      this.editor = new Editor({
        holder: this.holder,
        tools: {
        }
      });
    }
  },
  mounted(){
    this.init_editor();
  },
    //... Destroy on destroy
}
  

Первый:

Предположим, у меня есть несколько экземпляров <editorjs-wrapper> в одном представлении без :hook , тогда все намерения будут иметь одинаковый идентификатор.

 <div id="app">
    <editorjs-wrapper></editorjs-wrapper>
    <editorjs-wrapper></editorjs-wrapper>
</div>
  

Все становится немного странным, так как они оба пытаются обработать DOM #vue-editor-js . Было бы лучше, если бы компонент генерировал случайный идентификатор по умолчанию?

Второй:

EditorJS предоставляет save() метод для извлечения ее содержимого. Что лучше для родительского элемента, чтобы иметь возможность вызывать save() метод из EditorJS внутри дочернего элемента?

У меня есть два способа:

  • $emit и наблюдение (события)
 
// Parent
<div id="#app">
    <editorjs-wrapper @save="save_method" :save="save">
</div>
// Child

...
    watch: {
        save: {
            immediate: true,
            handler(new_val, old_val){
                if(new_val) this.editor.save().then(save=>this.$emit('save', save)) // By the way I have not tested it it might be that `this` scope is incorrect... 
            }
        }
    }
...
  

То есть родительский элемент запускает сохранение в дочернем элементе, и таким образом дочерний элемент генерирует событие сохранения после вызова метода из EditorJS.

  • this.$refs.childREF Этот способ обеспечит тесную связь между родительским и дочерним компонентами.

Третий:

Если я хочу обновить содержимое дочернего элемента как родительского, я не знаю, как это сделать, в других проектах, которые я безуспешно пробовал с v-modal для двухсторонней привязки:

 export default{
    name: example,
    props:{
        content: String
    },
    watch:{
        content: {
            handler(new_val, old_val){
                this.update_content(new_val);
            }
        }
    },
    data(){
        return {
            some_js_framework: // Initialized at mount        
        }
    },
    methods: {
        update_content: function(new_val){
            this.some_js_framework.update(new_val)
        },
        update_parent: function(new_val){
            this.$emit('input', this.some_js_framework.get_content());
        }
    },
    mounted(){
        this.some_js_framework = new Some_js_framework();
        this.onchange(this.update_parent);
    }
}
  

Проблема в том:

  1. Обновлено дочернее содержимое
  2. Дочернее событие emit input
  3. Родительский элемент обновляет двустороннее предложение v-model
  4. Поскольку родительский элемент обновил значение, дочерний просмотр обновляется, и, таким образом, onchange обработчик запускается, таким образом, 1. снова.