调用式组件
调用式组件这个名词应该不是官方的,因为在网上找了一大圈都没有发现这种组件的官方称呼,但是在很多开源的VueUI中都有这种组件存在,而且是一种很关键的组件。
例如Element UI 中的 Alert MessageBox Message Toast 等等等。
举个例子就很容易明白什么是调用式
new Vue({
methods: {
handleClick () {
this.$alert('这是一个alert')
}
}
})
看完之后就发现超简单吧。
为什么要专门说它
emmm 因为在平常开发中写一个alert感觉怪怪的,但好像又没有什么问题!!!
那还是举个例子
<html>
<body>
<div id="app">
<div class="alert" v-if="isAlertOne"></div>
<div class="alert" v-if="isAlertTwo"></div>
<div class="alert" v-if="isAlertThree"></div>
</div>
<script>
new Vue({
data () {
return {
isAlertOne: false,
isAlertTwo: false,
isAlertThree: false,
}
}
})
</script>
</body>
</html>
平时开发的情形基本就如上述一样,通过data里面的数据控制,如果有多个alert那就要写特别特别多的列在一起,而data中要维护各种判断条件。如果alert中有一些其他的变量,那维护的东西就更乱了
稍微优化一点的是吧alert抽成组件,但还是避免不了的要把用到的alert组件都罗列到html中。
虽然可以实现alert的功能,但是有点反人类的感觉。
正常的逻辑是alert是什么样的,我调用的时候生成,关闭的时候就移除了。
如何开发调用式的组件
既然上面说到了种类组件要手动调用,而不是维护一大堆状态
看了下 element 源码,也自己实现了一个alert,放在了GIthub上。
// https://github.com/HaoYS/SongUI/blob/master/packages/alert/index.js
import Alert from './src/main.js'
Alert.install = function (Vue) {
if(Vue.prototype.$alert) return
Vue.prototype.$alert = Alert
}
export default Alert
// https://github.com/HaoYS/SongUI/blob/master/packages/alert/src/main.js
import Vue from 'vue'
import Main from './main.vue'
const Alert = function (message, title, opt) {
let Constructor = Vue.extend(Main)
let alert = new Constructor({
propsData: Object.assign({
message, title
}, opt)
})
alert.$mount()
document.body.appendChild(alert.$el)
}
export default Alert
<template>
<div class="alert" ref="wrapper">
<div class="content">
<div class="title">
<span>{{title}}</span>
</div>
<div class="msg">
<p>{{message}}</p>
</div>
<div class="button-group">
<song-button @click="handleCancel">{{cancelButtonText}}</song-button>
<song-button @click="handleConfirm">{{confirmButtonText}}</song-button>
</div>
</div>
</div>
</template>
<script>
import SongButton from '../../button/src/main.vue'
//构造组件的选项
export default {
name: 'SongUIAlert',
components: {SongButton},
props: {
title: {
type: String,
required: true
},
message: {
type: String,
required: true
},
callback: {
type: Function
},
cancelButtonText: {
type: String,
default: '取消'
},
confirmButtonText: {
type: String,
default: '确定'
}
},
methods: {
handleCancel () {
this.callback && this.callback('cancel')
this.$el.remove()
},
handleConfirm () {
this.callback && this.callback('confirm')
this.$el.remove()
}
}
}
</script>
通过上面的方法可以看到,比较规范的组件开发是通过在install方法中实现创建一个新的Vue组件实例。
而使用方法就是简单的
import Vue from 'vue'
import SongUI, { Button, Toast, Alert } from '../src/index'
// Vue.use(Button)
// Vue.use(Toast)
// Vue.use(Alert)
Vue.use(SongUI)
window.vm = new Vue({
el: '#app',
data() {
return {
msg: 'msg'
}
},
methods: {
handleAlert () {
this.$alert('这是一个msg', '这是一个title', {
callback: action => {
console.log(action)
}
})
}
}
})