一、介绍vue.extend的使用
1、最近研究element-ui中消息弹this.$message的源码实现,发现内部使用了Vue.extend(),下面介绍一下该方法。
2、Vue.extend(options)
- 参数:
{Object} options - 用法:
使用基础Vue构造器,创建一个"子类"。参数是一个包含组件选项的对象。
需要注意,在Vue.extend()中data选项必须是函数。
3、先看一个简单示例
<html>
<head>
<title>Vue.extend 用法</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="mount-point"></div>
<script>
// 创建构造器
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')
</script>
</body>
</html>
结果显示如下:
Walter White aka Heisenberg
可以看到,extend 创建的是 Vue 构造器,而不是我们平时常写的组件实例,所以不可以通过 new Vue({ components: testExtend }) 来直接使用,需要通过 new Profile().$mount(’#mount-point’) 来挂载到指定的元素上。 我个人的理解来看,extend提供了一个能够构造组件的函数(也就是构造器)。在一些特定的应用场景(如自己构建一个复杂弹窗)下,我们使用这种函数式的构造组件的方法,会更灵活一些。
总结一下:
const Profile = Vue.extend() // 返回一个组件构造器
new Profile() // 组件实例化
new Profile().$mount('#mount-point') // 把组件挂载到指定的元素上
二、Vue.extend()实现MessageBox弹窗弹框
1、新建一个messageBox.vue
<template>
<div id="confirm" v-if='flag'>
<div class="contents" >
<div class="content-top">{{text.title}}</div>
<div class="content-center">{{text.msg}}</div>
<div class="content-bottom">
<button type='primary' @click='ok' class="left">{{text.btn.ok}}</button>
<button type='info' @click='no' class="right">{{text.btn.no}}</button>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
flag:true,
text:{
title:'标题',
msg:'这是一个弹出框组件',
btn:{
ok:'确定',
no:'取消'
}
}
}
},
methods: {
ok(){
this.flag=false;
},
no(){
this.flag=false;
}
}
}
</script>
2、新建messageBox.js
import Vue from 'vue'
import Confirm from './MessageBox.vue'
let confirmStructor=Vue.extend(Confirm) //返回一个实例创建的构造器,但实例构造器需要进行挂载到页面中
let theConfirm = function(text){
return new Promise((resolve,reject)=>{ //返回一个promise,进行异步操作,成功时返回,失败时返回
let confirmDom=new confirmStructor({
el:document.createElement('div')
})
//在body中动态创建一个div元素,之后此div将会替换成整个vue文件的内容
//此时的confirmDom通俗讲就是相当于是整个组件对象,通过对象调用属性的方法来进行组件中数据的使用
//可以通过$el属性来访问创建的组件实例
document.body.appendChild(confirmDom.$el)
//此时进行创建组件的逻辑处理
confirmDom.text=text // 将需要传入的文本内容传给组件实例
confirmDom.ok=()=>{
resolve() // 点击正确按钮时
confirmDom.flag=false;
}
confirmDom.no=()=>{
resolve() //失败时返回的操作
confirmDom.flag=false;
}
})
}
//将逻辑函数进行导出和暴露
export default theConfirm
3、mian.js引入挂载到全局
import Vue from 'vue';
import store from './store/index'
import App from './App.vue';
import router from './router';
import theConfirm from './components/messageBox.js'
Vue.config.productionTip = false;
Vue.prototype.$Myconfirm=theConfirm
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
4、页面使用
this.$Myconfirm({
title:'标题',
msg:'内容',
btn:{ ok:'确定', no:'取消'}
}).then(()=>{
console.log('ok')
}).catch(()=>{
console.log('no')
})