今天带着大家开发个简单的Vue消息框插件,需求如下:
请使用Vue实现一个自定义 alert 弹框组件。要求:
1、弹框组件可打开和关闭 。
2、 将弹框组件扩展为 Vue 插件,通过 API 的方式进行调用,插件API的调用规则为 vm.$alert('提示消息') 。
3. 开发环境使用普通的 HTML 页面,直接通过 script 标签引用 vue.js 即可。
熟悉Vue的开发者,应该能够看出来这里的需求其实可以拆分成两个,第一个需求是完成一个弹窗组件,并且这个组件能够打开和关闭,第二个需求是将这个组件扩展为插件。
这道题目要求在开发环境中使用普通的 HTML 页面,直接通过 script 标签引用 vue.js 即可,开发一个弹窗组件代码如下:
// 用Vue.extend生成组件构造函数
let AlertConstructor =Vue.extend({
template: '<div class="dialog-content" v-show="xian">{{msg}}</div>',
data:function(){
return {
xian:false,
msg:"自定义信息"
}
},
methods: {
show:function(msg){
this.xian = true
this.msg = msg;
},
hide:function(){
this.xian = false
}
}
})
// 组件实例化,生成dom但是不渲染;
let instance = new AlertConstructor().$mount();
上面代码首先用Vue.extend方法生成一个组件,或者叫组件构造器,然后将其实例化,但是组件在实例化的时候通常会传递一个el来挂载Vnode。
但是我们在生成这个组件实例时不想其渲染到页面,我们需要用dom操作的方式将其插入页面,所以在其实例化时没有传递el参数,而是调用$mount方法,这个方法可以传递一个参数,参数为要挂载的el,也可以不传递参数,不传递参数时只生成dom但是不渲染。
下面就将考虑如何将这个组件扩展成插件,我们来看一下vue的官方文档的示例代码:
// 调用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)
new Vue({
//... options
})
Vue.use(MyPlugin, { someOption: true })
通过上面的代码我们可以看出,如果在Vue中使用插件需要用Vue.use方法加载插件,加载插件的原理就是调用插件的install方法,可以看出插件的形式为一个对象,这个对象上有一个install方法,而install方法的第一个参数为Vue构造函数,由此得出我们封装插件的逻辑应该都在install方法中。
看一下官方封装插件的示例伪代码:
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () {
// 逻辑...
}
// 2. 添加全局资源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
...
})
// 3. 注入组件
Vue.mixin({
created: function () {
// 逻辑...
}
...
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
// 逻辑...
}
}
按照上面代码,实现将组件扩展为插件的代码如下:
var MyAlert = {
install: function (Vue, options) {
let AlertConstructor = Vue.extend({
template: '<div class="dialog-content" v-show="xian">{{msg}}</div>',
data: function () {
return {
xian: false,
msg: "自定义信息"
}
},
methods: {
show: function (msg) {
this.xian = true
this.msg = msg;
},
hide: function () {
this.xian = false
}
}
})
// 组件实例化,生成dom但是不渲染;
let instance = new AlertConstructor().$mount();
// 在组件原型上添加$show显示方法
Vue.prototype.$show = function (msg) {
instance.show(msg)
};
// 在组件原型上添加$hide隐藏方法
Vue.prototype.$hide = function (msg) {
instance.show(msg)
};
// 将生成的组件实例dom插入body中。
document.body.appendChild(instance.$el);
}
}
完整测试代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 1. 导入Vue的包 -->
<script src="./lib/vue-2.4.0.js"></script>
<style>
/* 组件样式 */
.dialog-content {
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%);
transform: translateX(-50%);
}
.none {
display: none
}
</style>
</head>
<body>
<div id="app">
<p>hello world</p>
</div>
<script>
// =================开发插件开始================================
var MyAlert = {
install: function (Vue, options) {
let AlertConstructor = Vue.extend({
template: '<div class="dialog-content" v-show="xian">{{msg}}</div>',
data: function () {
return {
xian: false,
msg: "自定义信息"
}
},
methods: {
show: function (msg) {
this.xian = true
this.msg = msg;
},
hide: function () {
this.xian = false
}
}
})
// 组件实例化,生成dom但是不渲染;
let instance = new AlertConstructor().$mount();
// 在组件原型上添加$show显示方法
Vue.prototype.$show = function (msg) {
instance.show(msg)
};
// 在组件原型上添加$hide隐藏方法
Vue.prototype.$hide = function (msg) {
instance.show(msg)
};
// 将生成的组件实例dom插入body中。
document.body.appendChild(instance.$el);
}
}
///========================开发插件结束======================================/
Vue.use(MyAlert);
new Vue({
el: "#app",
mounted () {
//注册插件后可以使用$show方法开启消息框并传递参数
this.$show("123");
setTimeout(()=>{
//调用hide方法关闭弹窗
this.$hide()
},2000)
}
})
</script>
</body>
</html>
下面我们来总结一下开发Vue插件的思路:
1、首先定义一个插件对象,对象必须有一个install方法。
2、在insall方法中通过参数访问Vue构造函数,直接在其原型上添加方法。
3、定义一个组件类,并且实现两个方法,关闭和显示
4、将组件类实例化,并且调用$mount生成dom
5、将组件实例化生成的dom插入到body。
组件开发完成后,要想调用组件,只需要用Vue.use方法调用一下即可。