agularJS 中,我使用一个全局的 factory 定义了一个 dict 变量,并在 dict 中创建了一些 alert、confirm 的组件,并且返回一个 promise 对象,方便后续的连续调用,又可以避免每个页面都要引入一次组件。 Vue 中所有的东西都是组件,不能像 angularJS 那样可以定义一个 factory,只能思考其他的方法。
我们以 alert 弹窗为例。
首先弹窗可能存在于任何一个组件中,所以必须有一个可以跨组件通讯的模型,Vue 中有两种方法可以实现:
-
使用 Vue 的实例事件,
-
新建另一个 Vue 实例,当做一个插件引入到我们的 Vue 实例中
先说第一种 Vue 的实例事件现在有四种,这几种方法最后都返回的是 Vue 实例,不能返回一个 promise 让我们链式调用,因此这个方法不行
第二种方法:
我们需要自己来创建一个 Vue 的插件,方法如下:
alert/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
<template src="./index.html"></template>
<script>
export default {
data() {
return {
showAlert: false,
context: '没有标题',
allowClick: false,
okText: '确定',
cancelText: '取消',
};
},
methods: {
show(context, allowClick, okText, cancelText) {
let p = new Promise((resolve, reject) => {
this.showAlert = true;
if (allowClick) {
this.allowClick = allowClick;
} else {
setTimeout(() => {
this.showAlert = false;
resolve({ ok: true });
}, 1000);
return false;
}
this.okText = okText || '确定';
this.cancelText = cancelText || '取消';
this.btnClick = function (state) {
this.showAlert = false;
resolve({ ok: state });
};
});
return p;
},
},
};
</script>
<style lang="less" src="./index.less"></style>
|
alert/index.html
1
2
3
4
5
6
7
8
9
10
11
|
<div class="app_alert" v-show="showAlert">
<div class="content">
<p class="context">
<span>{{context}}</span>
</p>
<div class="btnGroup" v-if="allowClick">
<button @click="btnClick(true)">{{okText}}</button>
<button v-show="allowClick" @click="btnClick(false)">{{cancelText}}</button>
</div>
</div>
</div>
|
alert/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import Vue from 'vue';
import AppAlert from './index.vue';
// 根据模板创建一个Vue的子类,注意这里是子类,而不是一个实例
const Construct = Vue.extend(AppAlert);
// 生成一个实例,并设置他的模板和组件
const AppAlertComponent = new Construct({
template: '<AppAlert/>',
component: AppAlert,
});
// 先挂载组件
const Ele = AppAlertComponent.$mount();
// 把实例插入到body中
document.body.appendChild(Ele.$el);
// Vue规定使用use方法的时候,必须接受一个包含install属性的对象,或者一个function
export default {
install: (Vue) => {
// 把$alert挂在到Vue的属性上
Vue.prototype.$alert = AppAlertComponent;
},
};
|
main.js
1
2
|
import VAlert from '@/common/app_alert/index.js';
Vue.use(VAlert);
|
现在假设我们有一个组件,我们的调用方法如下:
1
2
3
4
5
6
7
|
methods: {
test () {
this.$alert.show('确定要删除吗?').then((res) => {
console.log(res)
})
}
}
|