簡體   English   中英

如何將 Vue 實例重構為工作組件

[英]How to refactor a Vue instance into a working component

我有一個正在運行的 Vue 實例,但現在我正在嘗試將它重構為我正在處理的項目的組件。 我是 Vue 的新手,所以這對我來說都是學習的。

這是代碼筆上代碼的鏈接https://codepen.io/qinglu/pen/mOKgPP?editors=1010

到目前為止,這就是我能用我的知識把它變成的所有東西

export default 
{
    name: "vue-tinymce",
    data() 
    {
        return {
            content: "test content",
            content1: "text1 content1",
            tinymceOptions: tinymceOptions
        }
    },
    mounted()
    {
        var vm = this,
        options = $.extend(true, {}, tinymceOptions); // use jquery temporary

        // make an deep copy of options;should not modify tinymceOptions
        options.selector  =undefined;
        options.target  =vm.$el; // use options.target instead of options.selector

        var oldSetup = options.setup || function() {};
        options.setup = function(editor) 
        {
            console.log("setup");

            //Decorate origin one
            oldSetup(editor);  

            // Bind keyup
            editor.on("keyup",function(e)
            {
                // update model value;
                var value=editor.getContent();

                // Dom to model,this was a problem,when input in editor ? it will focus in 
                // the first line first word;
                vm.$emit("input",value); // who receive this event?
            });

            editor.on("blur",function()
            {
                vm.allowSetContent=true;
            });

            editor.on("focus",function()
            {
                vm.allowSetContent=false;
            });
        };

        tinymce.init(options)
            .then(function(editors)
            {
                vm.editor=editors[0];
            });
        }
    }
};

所以這里有很多關於做到這一點的最佳方法要說,但基本上你想將道具傳遞到你的 tinyMce 組件中,然后讓你在父級上發出的“輸入”事件的偵聽器,它可以做一點事。 為了清晰和可重用性,我建議嘗試使用Vue 單文件組件

甚至還有一個如何從 Vue 文檔導入和“組件化”應用程序的實時示例

我通過在 JS 中創建一個名為“mce-parent”的父組件來證明這一點,該組件接收道具並將它們通過自身傳遞到 tinyMce 組件中。 在 'parent-mce' 組件中,您會看到@inputv-on:input的簡寫,它捕獲您發出的事件並將其發送到作用域方法doSomething() 我在這里修改了你的例子https://codepen.io/anon/pen/OdmZOV?editors=1010

這是代碼:

html

<div id="example">
  <input type="text" v-model="content" class="form-control" />

  
  <div class="row">
    <div class="col-md-6">
      <!-- Don't need to pass the MCE options,
      as they're in the mce-parent component -->
      <mce-parent :value="content"></mce-parent>
    </div>
    <div class="col-md-6">
  
    </div>
  </div>
</div> 

tinyMce 組件

export default Vue.component("vue-tinymce",{
  template:"<textarea>{{value}}</textarea>",
  props:["value","options"],
  mounted:function(){
    var vm=this,
       options=$.extend(true, {}, tinymceOptions); // use jquery temporary
    
    // make an deep copy of options;should not modify tinymceOptions
    options.selector=undefined;
    options.target=vm.$el; // use options.target instand of options.selector
    var oldSetup=options.setup||function(){};
    
    options.setup=function(editor){
      console.log("setup");
      
      //Decorate origni one
      oldSetup(editor);
      
      // Bind keyup
      editor.on("keyup",function(e){
        // update model value;
        var value=editor.getContent();
        // Dom to model,this was a problem,when input in editor ? it will focus in the first line first word;
        vm.$emit("input",value); // who recieve this event?
      });
      
      editor.on("blur",function(){
        vm.allowSetContent=true;
      });
      
      editor.on("focus",function(){
         vm.allowSetContent=false;
      })
    };
    
    tinymce.init(options).then(function(editors){
      vm.editor=editors[0];
    })
  },
  watch:{
    value:function(content)
    {
      if(this.editor&&this.allowSetContent)
      {
        // setContent will let editor focus in first line and first world
        this.editor.setContent(content);
      }
    }
  }
});

mce-父組件

// this is just an example
import tinyMce from './components/TinyMce.js';
Vue.component("mce-parent",{
  data : {
    return {
      tinymceOptions : tinymceOptions,
    }
  },
  template:`<div class='mce-parent'>`
              `<tiny-mce @input="doSomething" :value="value" :options="tinymceOptions"/>`
              `</tiny-mce>`
            `</div>`,
  props : ['value'],
  components : { 'tiny-mce' : tinyMce },
  methods : {
    doSomething(value){
      console.log(value)
    }
  }
});

var tinymceOptions={
  selector: 'textarea',
  height: 200,
  menubar: true,
  plugins: [
    'advlist autolink lists link image charmap print preview hr anchor pagebreak',
    'searchreplace wordcount visualblocks visualchars code fullscreen',
    'insertdatetime media nonbreaking save table contextmenu directionality',
    'emoticons template paste textcolor colorpicker textpattern imagetools codesample toc'
  ],
  toolbar1: 'undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
  toolbar2: 'print preview media | forecolor backcolor emoticons | codesample',
  valid_elements:"*[*]",
  content_css: '//www.tinymce.com/css/codepen.min.css',
  images_upload_url: 'postAcceptor.php',
  images_upload_base_path: '/some/basepath',
  images_upload_credentials: true,
  images_upload_handler: function (blobInfo, success, failure) {
    var xhr, formData;
    xhr = new XMLHttpRequest();
    xhr.withCredentials = false;
    xhr.open('POST', 'postAcceptor.php');
    xhr.onload = function() {
      var json;

      if (xhr.status != 200) {
        failure('HTTP Error: ' + xhr.status);
        return;
      }
      json = JSON.parse(xhr.responseText);

      if (!json || typeof json.location != 'string') {
        failure('Invalid JSON: ' + xhr.responseText);
        return;
      }
      success(json.location);
    };
    formData = new FormData();
    formData.append('file', blobInfo.blob(), fileName(blobInfo));
    xhr.send(formData);
  },
  image_title: true, 
  // enable automatic uploads of images represented by blob or data URIs
  automatic_uploads: true,
  // URL of our upload handler (for more details check: https://www.tinymce.com/docs/configure/file-image-upload/#images_upload_url)
  images_upload_url: 'postAcceptor.php',
  // here we add custom filepicker only to Image dialog
  file_picker_types: 'image', 
  // and here's our custom image picker
  file_picker_callback: function(cb, value, meta) {
    var input = document.createElement('input');
    input.setAttribute('type', 'file');
    input.setAttribute('accept', 'image/*');
    
    // Note: In modern browsers input[type="file"] is functional without 
    // even adding it to the DOM, but that might not be the case in some older
    // or quirky browsers like IE, so you might want to add it to the DOM
    // just in case, and visually hide it. And do not forget do remove it
    // once you do not need it anymore.

    input.onchange = function() {
      var file = this.files[0];
      
      // Note: Now we need to register the blob in TinyMCEs image blob
      // registry. In the next release this part hopefully won't be
      // necessary, as we are looking to handle it internally.
      var id = 'blobid' + (new Date()).getTime();
      var blobCache = tinymce.activeEditor.editorUpload.blobCache;
      var blobInfo = blobCache.create(id, file);
      blobCache.add(blobInfo);
      
      // call the callback and populate the Title field with the file name
      cb(blobInfo.blobUri(), { title: file.name });
    };
    
    input.click();
  }
};

主 Vue 應用程序入口點


var vm=new Vue({
  el:"#example",
  data:{
    content:"test content",
    content1:"text1 content1"
   }
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM