vue组件封装之Promise到的方式调用

vue组件封装

 需求:很多场景,如confirm或者弹出的输入框,都需要后续做处理,之前自己简单的传入一个  
 回调函数觉得代码不好维护,遂想到使用Promise对象封装,调用之后返回一个Promise对象,  
 我们就可以用自己熟悉瑐Promise方式做后续的操作了!

组件实现思路

  • 正常创建一个对象,在对象原型上拓展一个回调方法callbackFn,我们后边操作的时候调用
  • 在创建对象那里返回一个Promise对象
  • 新建一个变量,保存Promise对象的resolvereject方法
  • 创建一个vue对象,挂在到dom并添加到页面
  • 我们在用户操作以后根据不同值,调用callbackFn的时候传入不同的参数
  • 最后我们在callbackFn函数中根据不同的传参,触发之前保存的Promise对象的resolvereject方法

下边是代码,我以地区选择插件作为示例

  • 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  
封装使用,当然现在因为自己还是渣渣水平,代码质量不好,大神看到了记得吐槽
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue2中,使用axios封装Promise.all的步骤如下: 首先,可以封装一个Promise函数,该函数接受三个参数jsonData、config和index,通过返回一个新的Promise对象,可以用来处理上传请求。在该Promise对象中,使用axios进行上传请求,并通过then方法处理请求成功的情况,如果返回码为0,则将返回的数据传递到下一个Promise中。如果请求失败,则使用catch方法将错误信息和配置项传递给下一个Promise。 第二步,使用async和await再次封装Promise函数,并返回该Promise的值。通过在该函数中调用上一步封装Promise函数,并使用await关键字等待该Promise的结果,然后返回结果。 第四步,使用Promise.all获取所有方法正常执行后的结果集。在该步骤中,可以将封装好的Promise函数放入一个数组中,然后使用Promise.all方法来执行这些Promise函数,并使用then方法处理正常执行后的结果集。如果有任何一个Promise函数出现异常,则使用catch方法来处理异常情况。 综上所述,以上是使用axios封装Promise.all的步骤。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [vue中循环遍历axios问题,使用promise.all解决,promise.all异常解决](https://blog.csdn.net/Uookic/article/details/118409301)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值