uniapp实现自定义弹窗组件,支持富文本传入内容

发布于:2024-08-18 ⋅ 阅读:(86) ⋅ 点赞:(0)

1.首先安装vuex 
通过此命令安装 ​​npm install vuex --save​

 创建initModal.js

import Vuex from 'vuex'
// 自定义弹窗
export default function initModal (v) {
  // 挂在store到全局Vue原型上
  v.prototype.$modalStore = new Vuex.Store({
    state: {
      show: false,
      title: '标题',
      content: '内容',
      isRichText: false,
      showCancel: true,
      cancelText: '取消',
      cancelColor: '#333333',
      cancelBackgroundColor: 'rgba(236, 236, 236, 0.39)',
      confirmText: '确定',
      confirmColor: '#333333',
      confirmBackgroundColor: '#FFBB24',
      success: null
    },
    mutations: {
      hideModal (state) {
        // 小程序导航条页面控制
        // #ifndef H5
        if (state.hideTabBar) {
          wx.showTabBar()
        }
        // #endif
        state.show = false
      },
      showModal (state, data) {
        state = Object.assign(state, data)
        console.log(state)
        state.show = true
      },
      success (state, res) {
        let cb = state.success
        let resObj = {
          cancel: false,
          confirm: false
        }
        res == 'confirm' ? (resObj.confirm = true) : (resObj.cancel = true)
        cb && cb(resObj)
      }
    }
  })
  v.prototype.$showModal = function (option) {
    if (typeof option === 'object') {
      // #ifndef H5
      if (option.hideTabBar) {
        wx.hideTabBar()
      }
      // #endif

      v.prototype.$modalStore.commit('showModal', option)
    } else {
      throw '配置项必须为对象传入的值为:' + typeof option
    }
  }
}

3.showModal.vue
组件实现,我做了个判断,如果传入的cancelText是空字符串,则只显示确认键。 

<template>
  <!-- 自定义弹窗 -->
  <view class="_showModal" v-show="show">
    <view class="_shade"></view>
    <view class="_modalBox">
      <view class="_modal">
        <slot name="title">
          <view class="title" v-show="title">{{ title }}</view>
        </slot>
        <slot name="content">
          <view class="content" v-if="isRichText">
            <rich-text :nodes="content"></rich-text>
          </view>

          <view class="content" v-else>{{ content }}</view>
        </slot>
        <slot name="btn">
          <view class="btnbox">
            <view
              v-if="cancelText"
              class="btn"
              :style="{ color: cancelColor, background: cancelBackgroundColor }"
              @click.stop="clickBtn('cancel')"
              >{{ cancelText }}</view
            >
            <view
              class="btn"
              :style="{
                color: confirmColor,
                background: confirmBackgroundColor
              }"
              @click.stop="clickBtn('confirm')"
              >{{ confirmText }}</view
            >
          </view>
        </slot>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'show-modal',
  computed: {
    show () {
      return this.$modalStore.state.show
    },
    title () {
      return this.$modalStore.state.title
    },
    content () {
      return this.$modalStore.state.content
    },
    isRichText () {
      return this.$modalStore.state.isRichText
    },
    showCancel () {
      return this.$modalStore.state.showCancel
    },
    cancelText () {
      return this.$modalStore.state.cancelText
    },
    cancelColor () {
      return this.$modalStore.state.cancelColor
    },
    cancelBackgroundColor () {
      return this.$modalStore.state.cancelBackgroundColor
    },
    confirmText () {
      return this.$modalStore.state.confirmText
    },
    confirmColor () {
      return this.$modalStore.state.confirmColor
    },
    confirmBackgroundColor () {
      return this.$modalStore.state.confirmBackgroundColor
    }
  },
  methods: {
    closeModal () {
      this.$modalStore.commit('hideModal')
    },
    clickBtn (res) {
      this.$modalStore.commit('hideModal')
      this.$modalStore.commit('success', res)
    }
  },
  beforeDestroy () {
    this.$modalStore.commit('hideModal')
  },
  data () {
    return {}
  }
}
</script>

<style lang="scss" scoped>
._showModal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 10000;
  ._shade {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    background: #000;
    opacity: 0.6;
    z-index: 11000;
  }
  ._modalBox {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 12000;
    display: flex;
    justify-content: center;
    align-items: center;
    ._modal {
      flex: none;
      width: 345px;
      //   min-height: 256px;
      background: #fff;
      border-radius: 12px;
      .title {
        text-align: center;
        font-size: 18px;
        font-family: Source Han Sans CN;
        font-weight: bold;
        color: #333333;
        margin-top: 20px;
      }
      .content {
        min-height: 60px;
        width: 284px;
        margin: 20px auto;
        margin-bottom: 30px;
        font-size: 32rpx;
        font-family: Source Han Sans CN;
        font-weight: 500;
        color: #333333;
        display: flex;
        justify-content: center;
        align-items: center;
        letter-spacing: 2px;
        line-height: 40rpx;
      }
      .btnbox {
        display: flex;
        justify-content: center;
        // padding-top: 10px;
        flex-direction: row;
        .btn {
          width: 100px;
          height: 40px;
          border-radius: 12px;
          display: flex;
          justify-content: center;
          align-items: center;
          font-family: Source Han Sans CN;
          font-weight: 500;
          font-size: 16px;
          margin: -5px 30px 20px 30px;
        }
      }
    }
  }
}
</style>

4、在main.js挂载vuex和showModal 

import Vuex from 'vuex'
import initModal from '@/utils/initModal.js'
import ShowModal from '@/components/showModal.vue'

initModal(Vue)

Vue.use(Vuex)
Vue.component('ShowModal', ShowModal)

5.使用方式  、 在h5 会报错 所有 还是引入一下 小程序正常

 <ShowModal></ShowModal>

import ShowModal from '@/components/showModal'

  components: {
    ShowModal
  },

   confirmBill () {
      this.$showModal({
        title: '提示',
        content: `
        <div style="font-size:14px">
        确认该订单吗?
           <br/> 
           应付账单
          <span style="color:red">¥607.5</span>
          <br/> 
          还款日期:2024-05-02 14:26:52
        </div>
           `,
        isRichText: true,
        cancelText: '取消', //传入空值表示只显示确认按钮,此代码不能省略
        confirmText: '确认',
        success (res) {
          if (res.confirm) {
            console.log('用户点击确定')
          } else if (res.cancel) {
            console.log('用户点击取消')
          }
        }
      })
    }


网站公告

今日签到

点亮在社区的每一天
去签到