This time I will bring you a detailed explanation of the use of vue's custom dynamic components. What are the precautions for using vue's custom dynamic components? Here are practical cases, let's take a look.
After learning the Vue family bucket and some UI, it is basically enough, but using components in the way of elements is still not flexible enough. For example, we need to call the components directly through js code instead of using attributes every time on the page. Control component performance. Let's talk about how to define dynamic components.
The idea is to get the constructor of the component, so that we can create new. And Vue.extend can do it: https://cn.vuejs.org/v2/api/#Vue-extend
// 创建构造器var Profile = Vue.extend({ template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } })// 创建 Profile 实例,并挂载到一个元素上。new Profile().$mount('#mount-point')
The official provides this example, let’s make some modifications, Make a simple message box.
Create a vue file. widgets/alert/src/main.vue
<template> <transition name="el-message-fade"><p v-show="visible" class="my-msg">{{message}}</p> </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 component. If it is the first section, we can put it into the components object and use it, but here we have to 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 }})//如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用 vm.$mount() 手动地挂载一个未挂载的实例。instance.$mount(); document.body.appendChild(instance.$el) return instance; } export default MyMsg;
require('./main.vue') returns a component initial object, corresponding to the options in Vue.extend( options ), this place Equivalent to the following code:
import alert from './main.vue'let MyMsgConstructor = Vue.extend(alert);
and MyMsgConstructor is as follows.
Refer to this._init in the source code, the parameters will be merged, and then called according to the life cycle run:
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 to obtain a mount instance. This example is instance.$el.
You can pass in the el object in the construction method (note that the mark part in the source code above is also mounted vm.$mount(vm .$options.el), but if you do not pass in el, there will be no $el object after new, so you need to manually call $mount().
instance= new MessageConstructor({ el:".leftlist", data:{ message:msg }})
This el cannot be written directly in the vue file, and an error will be reported. Next, we can simply set it as a Vue object
//..import VueResource from 'vue-resource'import MyMsg from './widgets/alert/src/main.js';//..//Vue.component("MyMsg", MyMsg);Vue.prototype.$mymsg = MyMsg;
Then test it on the page:
<el-button type="primary" @click='test'>主要按钮</el-button>//..
methods:{
test(){
this.$mymsg("hello vue");
} }
This implements basic parameter passing. 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
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, execute this callback. There is no such method in the initial state. Then in main.js, you can pass in
var MyMsg=function(msg,callback){ instance= new MyMsgConstructor({ data:{ message:msg }, methods:{ onClose:callback } })
. The parameters here are merged with the original parameters, rather than overridden. At this time, you can modify the calling place. The callback can be executed.
test(){ this.$mymsg("hello vue",()=>{ console.log("closed..") }); },
You can rewrite the close method directly, but this is not recommended because it may mess up the previous logic and may cause repeated coding.
## It is much more flexible now. #Unified Management If the number of custom dynamic components increases, it will be cumbersome to add them one by one in main.js, so here we can let widgets provide a unified outlet for easy reuse in the future. Create a new index.js under widgetsimport 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 }
##Install the Vue.js plug-in. If the plug-in is an object, the
installmethod must be provided. If the plug-in is a function, it will be called as a parameter of the install method. .
也就是把所有的组件当插件提供:在main.js中加入下面的代码即可。
... import VueResource from 'vue-resource'import Widgets from './Widgets/index.js'... Vue.use(Widgets)
这样就很简洁了。
小结: 通过Vue.extend和Vue.use的使用,我们自定义的组件更具有灵活性,而且结构很简明,基于此我们可以构建自己的UI库。以上来自于对Element源码的学习。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
The above is the detailed content of Detailed explanation of the use of custom dynamic components in Vue. For more information, please follow other related articles on the PHP Chinese website!