Vue.component
Vue.component
这个组件是注册一个全局组件
Vue.component('my-constom',{
template: '<div>{{msg}}</div>',
props: {
msg: {
type: String,
default: 'default message'
}
}
})
第一个参数是组件的名称,第二个组件是要传入的对象,在vue中所有的组件都是一个vue的实例,所以组件传入的对象跟new Vue传入的对象是一样的,也有data,props,created等参数;
这样直接用是注册一个全局的对象,但是有时候不想注册全局的对象,那么可以使用一下的方法注册一个局部对象:
var ComponentA={/*...*/}
var ComponentB={/*...*/}
var ComponentC={/*...*/}
//在想使用的组件中
new Vue({
el:"#app",
components:{
'component-a':ComponentA,
'component-b':ComponentB,
'component-c':ComponentC
}
})
注册过程
有时候又想了解一下Vue的内部是注册组件的,或者我们定义的全局组件存在哪里,这时候就需要断点调试一下看看,下边是调试时候的截图:
实际上注册组件,注册自定义指令都是走的这个方法
先去判读type是component,先去走validateComponentName方法是一个正则匹配
在判断传入的definition是一个对象继续执行,赋值名称,再去调用this.option._base.extend(dfinition);这个方法是构造一个组件,这是个重点方法下面是截图
Vue.extend
是个重点的方法,进行一系列操作最终renturn构造函数
定义sub函数,继承this(Vue),init生命周期,最终返回改构造函数,就是一个Vue的实例;
返回实例之后赋值给this.option在第一张截图的this.option[type+'s'] [id]中;组件定义完成;
以上就是组件的定义过程;
使用过程
在定义过程中返回的构造函数里边的语句debugger,可以清楚的看到组件在使用的时候调用了this._init(options),往下执行就能看到执行过程的函数调用堆栈如图:
发现最终是在update时候执行的,具体怎么执行不做过多分析,有兴趣可以看一下Vue技术揭秘网站里边有清楚分析;Vue时间执行主要是patch,和update;
Vue.extend()
在自定义组件的时候内部用到了Vue.extend()方法,但是也可以直接调用Vue.extend(),这个方法最终也是返回了一个Vue的构造函数,具体过程分析注册component的时候已经进行了分析,具体可以看一下源码;从使用的过程中也能看出来他最终的返回值
const component = Vue.extend({
template: '<div>{{msg}}</div>',
props: {
msg: {
type: String,
default: 'default message'
}
},
name: 'Test'
})
Vue.component('Test')
new Vue({
el: '#root',
data() {
return {
message: "Test Extend Component"
}
}
})
使用vue.extend可以构造一个更简单的插件,在调用的时候甚至不用传参数就可以实现,具体原理就是使用Vue.extend()扩展出一个组件,在一个function中实例化这个组件并且挂在到Vue根元素上,最终将这个function挂在到vue的原型上,这样只需要调用这个函数就可以调用这个组件,非常的方便,常见的是load,弹出框,异步确认框的组件,
具体操作步骤:
使用Vue.extend()扩展一个组件,并且写好样式;
定义一个function,在里边初始化第一步扩展的组件;
将定义的function挂到Vue.prototype上边。
代码如下:扩展一个loading组件跟Vue.directive非常相似
//定义组件 const LoadComponent = Vue.extend({ template: `<div id="load-wrapper">{{msg}}</div>`, props: { msg: { type: String, default: "loading" } } }) //定义函数 function loading(msg) { new LoadComponent({ props: { msg: { type: String, default: msg } } }).$mount("#app"); return () => { document.body.removeChild(document.getElementById("load-wrapper")) }
}
//挂载
Vue.prototype.loading = loading //使用 methods: { showLoading() { const hide = this.loading("正在加载中")
setTimeout(() => {
hide()
}, 2000)
}
}
## Vue.use()
有些公共代码集成为一个插件,可以同过npm包安装也可以模块化调用,要想在Vue中使用这些插件,需要Vue.use引入,这样就可以在任何一个组件中this.loading()去调用了;
直接把Vue.extend()的loading封装成一个插件用Vue.use引入
+ 代码如下
```js
const loadingPlugins = {
install: (vm) => {
const LoadComponent = Vue.extend({
template: `<div id="load-wrapper">{{msg}}</div>`,
props: {
msg: {
type: String,
default: "loading"
}
}
})
function loading(msg) {
new LoadComponent({
props: {
msg: {
type: String,
default: msg
}
}
}).$mount("#app");
return () => {
document.body.removeChild(document.getElementById("load-wrapper"))
}
}
Vue.prototype.$loading = loading
}
}
Vue.use(loadingPlugins)
// 使用
methods: {
showLoading() {
const hide = this.$loading("正在加载中")
setTimeout(() => {
hide()
}, 2000)
}
}
实际上Vue.use执行过程是在this下边建了一个_installedPlugins的数组当执行的时候去判断传入的参数,并且执行改函数,最后将传入的push到数组里边。
源码如下:
所以说我们在任何组件的地方都能访问到这个函数并且去执行他