vue组件封装之Promise到的方式调用
vue组件封装需求:很多场景,如confirm或者弹出的输入框,都需要后续做处理,之前自己简单的传入一个回调函数觉得代码不好维护,遂想到使用Promise对象封装,调用之后返回一个Promise对象,我们就可以用自己熟悉瑐Promise方式做后续的操作了!组件实现思路正常创建一个对象,在对象原型上拓展一个回调方法callbackFn,我们后边操作的时候调用在...
·
vue组件封装
需求:很多场景,如confirm或者弹出的输入框,都需要后续做处理,之前自己简单的传入一个
回调函数觉得代码不好维护,遂想到使用Promise对象封装,调用之后返回一个Promise对象,
我们就可以用自己熟悉瑐Promise方式做后续的操作了!
组件实现思路
- 正常创建一个对象,在对象原型上拓展一个回调方法
callbackFn
,我们后边操作的时候调用 - 在创建对象那里返回一个Promise对象
- 新建一个变量,保存Promise对象的
resolve
和reject
方法 - 创建一个vue对象,挂在到dom并添加到页面
- 我们在用户操作以后根据不同值,调用
callbackFn
的时候传入不同的参数 - 最后我们在
callbackFn
函数中根据不同的传参,触发之前保存的Promise对象的resolve
和reject
方法
下边是代码,我以地区选择插件作为示例
- vue模板代码
<template>
<section class="city-select" :class="{animation: !show}">
<div class="city-select-content">
<h2 class="city-select-title">
请选择地址<i class="icon-close" @click="hide">x</i>
</h2>
<v-distpicker
type="mobile"
@province="changeProive"
@city="changeCity"
@area="changeArea
"></v-distpicker>
</div>
<button class="btn-confirm" @click="confirm">确定</button>
</section>
</template>
<script>
- css
//因为是封装的移动端组件 所以使用rem,不要问我rem是什么 ,我也不知道
<style lang="less">
.city-select{
&{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .5);
}
.city-select-content{
position: absolute;
left: 0;
bottom: 3.0625rem;
width: 100%;
height: 22.25rem;
overflow: scroll;
background: #fff;
}
.btn-confirm{
position: absolute;
bottom: 0;
width: 100%;
height: 3.0625rem;
color: #fff;
font-size: 0.875rem;
background-color: #5556ab;
border-radius: 0;
}
.city-select-title{
height: 2.5rem;
line-height: 2.5rem;
font-size: 1.0rem;
border-bottom: 1px solid #5556ab;
text-indent: 0.625rem;
color: #323232;
}
.icon-close{
float: right;
display: inline-block;
width: 2.5rem;
height: 2.5rem;
font-size: 1.875rem;
line-height: 2rem;
color: #5556ab;
}
}
</style>
- 模板 js部分
<script>
import Distpicker from 'v-distpicker'
export default{
data () {
return {
show: true,//当前组件是否显示
province: '',//省
city: '',//市
area: ''//区
}
},
components: {
'v-distpicker': Distpicker
},
methods: {
changeProive(province) {
//每次省份改变的时候清空 市和区的值
this.province = province
this.city = ''
this.area = ''
},
changeCity(city) {
//每次城市改变的时候清空区的值
this.city = city
this.area = ''
},
changeArea(area) {
//赋值当前用户选择的区域
this.area = area
},
hide() {
//关闭方法,通过this.show 给wrap添加class animation,隐藏当前组件
//调用原型的callBack方法
this.show = false;
this.callBack && this.callBack(false)
},
confirm () {
//确认方法
//拼接用户选择的地址为字符串
let self = this;
if(!self.province) return this.$Toast('请选择地址')
if(!self.city) return this.$Toast('请选择城市')
if(!self.area) return this.$Toast('请选择市区')
let addr= `${self.province.value} ${self.city.value} ${self.area.value} `
self.show = false;
//不为空的话就返回当前地址addr
self.callBack && self.callBack(addr)
}
}
}
</script>
封装方法,实现js调用
/**
* @description 地址选择插件
* 依赖插件 v-distpicker
* 安装 npm install v-distpicker --save
* 挂在到全局
* import cityPicker from '@/components/common/city-selected.js'
* Vue.$cityPicker = Vue.prototype.$cityPicker = window.$cityPicker = cityPicker;
* 调用方式 返回一个Promise对象
* this.$cityPicker()
.then(res=>{
console.log('res', res)
})
*注:文件引用一定要使用import的方式,使用require的话会加载模板失败
*导致创建的对象模板没有 内容
*/
import Vue from 'vue'
import citySelectTem from './city-selected.vue'
let currentMsg = null //保存Promise的resolve和reject方法
let instance = null //创建实例的时候使用
const Constructor = Vue.extend(citySelectTem)
//删除dom节点方法
const removeDom = event => {
event.target.parentNode.removeChild(event.target)
}
function citySelect (option = {}) {
//给当前对象的原型添加callBack方法
Constructor.prototype.callBack = defaultCallBack
//创建并挂在组件
instance = new Constructor().$mount(document.createElement('div'))
//将组建添加到body
document.body.appendChild(instance.$el)
//让当前实例监听animationend事件,就是我们在给元素添加animation的时候会触发
instance.$el.addEventListener('animationend', removeDom, false)
// 弹出层再次隐藏时时销毁组件
return new Promise((resolve, reject) => {
//使用变量保存两个参数,后边调用
currentMsg = { resolve, reject }
})
}
//父元素的callBack方法
function defaultCallBack (action) {
if(!action) currentMsg.reject('cancel')
currentMsg.resolve(action)
}
export default citySelect
总结
都是很简单的知识,原型继承,Promise的使用,没有特别高深的知识,个人也是通过思考和学习发
现要多变通,才能编写出更优雅瑐组件,还有就是有很多很优秀的jquery插件 ,我们可以使用vue
封装使用,当然现在因为自己还是渣渣水平,代码质量不好,大神看到了记得吐槽
更多推荐
已为社区贡献3条内容
所有评论(0)