Vue2 custom dynamic components

Source: Internet
Author: User

Vue2 custom dynamic components

The following describes how to define dynamic components.

Vue. extend

The idea is to get the component constructor so that we can get new. Vue. extend can achieve: https://cn.vuejs.org/v2/api/#Vue-extend

// Create the constructor var Profile = Vue. extend ({template: '<p >{{ firstName }{{ lastName }}aka {alias }}</p>', data: function () {return {firstName: 'Walter ', lastName: 'white', alias: 'heisenken' }}) // create a Profile instance and attach it to an element. New Profile (). $ mount ('# mount-point ')

This example is provided officially. Let's make a transformation and create a simple message prompt box.

Dynamic component implementation

Create a vue file. Widgets/alert/src/main. vue

<template> <transition name="el-message-fade"><div v-show="visible" class="my-msg">{{message}}</div> </transition></template><script > export default{  data(){   return{    message:'',    visible:true   }   },  methods:{   close(){    setTimeout(()=>{      this.visible = false;    },2000)   },  },  mounted() {  this.close();  } }</script>

This is the composition of our components. If it is in section 1, we can put it into the components Object for use, but here we will create it through the constructor. Create another widgets/alert/src/main. js

Import Vue from 'vue '; let MyMsgConstructor = vue. extend (require ('. /main. vue '); let instance; var MyMsg = function (msg) {instance = new MyMsgConstructor ({data: {message: msg }}) // If the Vue instance does not receive the el option during instantiation, it is in the "not mounted" state and has no associated DOM elements. You can use vm. $ mount () to manually mount an unmounted instance. Instance. $ mount (); document. body. appendChild (instance. $ el) return instance;} export default MyMsg; require ('. /main. vue ') returns an initial component object corresponding to Vue. the options in extend (options) is equivalent to the following code: import alert from '. /main. vue 'let MyMsgConstructor = Vue. extend (alert );

MyMsgConstructor.

Refer to this. _ init in the source code to merge the parameters and run them according to the lifecycle:

 Vue.prototype._init = function (options) { ...// merge options if (options && options._isComponent) {  // optimize internal component instantiation  // since dynamic options merging is pretty slow, and none of the  // internal component options needs special treatment.  initInternalComponent(vm, options); } else {  vm.$options = mergeOptions(  resolveConstructorOptions(vm.constructor),  options || {},  vm  ); }// expose real self vm._self = vm; initLifecycle(vm); initEvents(vm); initRender(vm); callHook(vm, 'beforeCreate'); initInjections(vm); // resolve injections before data/props initState(vm); initProvide(vm); // resolve provide after data/props callHook(vm, 'created'); ... if (vm.$options.el) {  vm.$mount(vm.$options.el); } };

$ Mount () is called to obtain a mount instance. This example is instance. $ el.

You can input the el object in the constructor (note that the mark part in the source code above is also mounted to the vm. $ mount (vm. $ options. el), but if you do not input el, there will be no $ el object after new, you need to manually call $ mount (). This method can directly input the element id.

instance= new MessageConstructor({  el:".leftlist",  data:{   message:msg}})

This el cannot be directly written in the vue file, and an error is reported. Next, we can roughly set it as a Vue object.

Call

Introduce our components in main. js:

//..import VueResource from 'vue-resource'import MyMsg from './widgets/alert/src/main.js';//..//Vue.component("MyMsg", MyMsg);Vue.prototype.$mymsg = MyMsg;

Then test on the page:

<El-button type = "primary" @ click = 'test'> main button </el-button> //.. methods: {test () {this. $ mymsg ("hello vue ");}}

In this way, the basic parameter passing is realized. It is best to remove the element in the close method:

close(){ setTimeout(()=>{  this.visible = false;  this.$el.parentNode.removeChild(this.$el);  },2000) },

Callback Processing

Callback and parameter passing are similar and can be passed in directly in the constructor. First, modify the close method in main. vue:

export default{  data(){   return{    message:'',    visible:true   }   },  methods:{   close(){    setTimeout(()=>{      this.visible = false;      this.$el.parentNode.removeChild(this.$el);    if (typeof this.onClose === 'function') {     this.onClose(this);    }    },2000)   },  },  mounted() {  this.close();  } }

If the onClose method exists, the callback is executed. This method is not available in the initial state. In main. js, You can input

var MyMsg=function(msg,callback){ instance= new MyMsgConstructor({  data:{   message:msg }, methods:{  onClose:callback } })

Here, the parameters and original parameters are merged, rather than overwritten. At this time, the callback can be executed after modification.

 test(){  this.$mymsg("hello vue",()=>{  console.log("closed..")  }); },

You can directly rewrite the close method, but this is not recommended because it may confuse the previous logic and may have repeated encoding. Now it is much more flexible.

Unified management

With the increase of custom dynamic components, adding them one by one in main. js is cumbersome. Therefore, we can allow widgets to provide a uniform exit for reuse in the future. Create an index. js under widgets

import MyMsg from './alert/src/main.js';const components = [MyMsg];let install =function(Vue){ components.map(component => { Vue.component(component.name, component); }); Vue.prototype.$mymsg = MyMsg;}if (typeof window !== 'undefined' && window.Vue) { install(window.Vue);};export default { install}

All custom components are registered through Vue. component. Finally, you can use an install method for export. Because we will use Vue. use next.

Install the Vue. js plug-in. If the plug-in is an object, the install method must be provided. If the plug-in is a function, it will be used as the install method. The install method will be called as a Vue parameter.

That is, provide all components as plug-ins: Add the following code to main. js.

...import VueResource from 'vue-resource'import Widgets from './Widgets/index.js'...Vue.use(Widgets)

This is simple.

Summary: with the use of Vue. extend and Vue. use, our custom components are more flexible and have a simple structure. Based on this, we can build our own UI library. The above comes from learning the Element source code.

Widgets part of the source code: http://files.cnblogs.com/files/stoneniqiu/widgets.zip

The above is a small series of problems encountered by the vue2 custom dynamic components. I hope to help you. If you have any questions, please leave a message for me, the editor will reply to you in a timely manner. Thank you very much for your support for the help House website!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.