• 全局组件设计


    全局组件设计

    不管是React、还是Vue也好,只要是App都需要一些基础的组件,如一些弹出窗:提示框Toast、确认框Confirm、模态框Modal、警告框Alert等等。这些弹出窗在Z轴都是比较高的(z-index高),且都有一个有点透明的黑色背景打底。

    打底背景一般样式(_PopBox.scss)如下。由于很多弹出窗都需要这种背景,且有这么一个功能是,点击黑色背景,就关闭弹出窗。那么我们可以设计一个可以存放弹出内容,且点击打底背景就关闭弹出窗的组件。

    // 变量存在于专门记录全局变量的文件中,参考bootstrap的变量文件
    $pop-z-index: 12 !default;
    $pop-bg-color: rgba(0,0,0,0.7) !default;
    
    // 弹出窗的背景
    .pop-box{
        position: fixed;
        left: 0;
        top: 0;
        height: 100%;
         100%;
        background-color: $pop-bg-color;
        z-index: $pop-z-index;
    }
    

    这里采用Vue的组件作示范

    <template>
        <div class='pop-box' :style='{display: open ? "block" : "none"}'
            @click.stop.self='$emit("close")'>
            <slot></slot>
        </div>
    </tempalte>
    

    使用:用<pop-box>组合成<confirm>组件

    <template>
        <pop-box :open='confirm_open' @close='confirm_close_fn'>
            <div class='pop-confirm'>...</div>
        <pop-box>
    </template>
    

    在设计组件布局中,我采用舞台/话剧布局(乱起名)。我们在看话剧或者舞台剧的时候,一般有如下三要素

    • 舞台
    • 幕帘
    • 背景

    其中幕帘位于最前方,舞台在中间,背景位于最后方。

    这三者对应组件那些部分?

    一般用脚手架生成一个Vue项目的时候,都会有一个App.vue的组件。所有组件都是这个组件的childrenApp = 幕帘 + 舞台 + 背景。在单页面应用中,我们一般都会用到路由vue-router或者react-router。而 router = 舞台 + 背景 ,舞台就是页面组件。除了路由之外,剩下的就是幕帘了,所以,我们的那些弹出窗可以充当幕帘,在我们需要提示或者确认用户的操作,就调出弹出窗,这个操作和幕帘很像很像。

    幕帘(舞台 + 背景)的一个特点是,他们都是独立的。这里没有将舞台背景独立,是由于每个路由代表一个页面,且一般背景用的都是同一个样式,就没有必要拆分出来,如果应用有多个背景,可以拆分出来。这样,不管切换了那个路由,都不会影响弹出窗,它一直存在于App的children中。那么,如果我要在某个路由,某个页面中想调出弹出窗那要怎么办?Vuex或者redux + react-redux

    涉及到多个组件共享一个状态,且无关父子关系,这个时候考虑用Vuex 或者 Redux

    以下使用Vuex

    常量: pop-constant.js

    // pop-constant.js
    export const POP_CONFIRM_OPEN = 'pop-confirm-open'
    

    状态模块module: pop.js

    import * as types from '@/modules/pop-constant'
    
    const state = {
        confirm: {
            open: false,
            text: '',
            cb: null
        }
    }
    
    const mutations = {
        [types.POP_CONFIRM_OPEN] (state, confirm) {
            state.confirm = Object.assign({}, state.confirm, confirm)
        }
    }
    
    const actions = {
        setConfirm ({commit}, confirm) {
            commit(types.POP_CONFIRM_OPEN, confirm)
        }
    }
    
    export default {
        namespaced: true,
        state,
        mutations,
        actions
    }
    

    缓存模块的命名空间maps.js

    import {createNamespacedHelpers} from 'vuex'
    
    // 这里缓存模块`pop.js`命名空间
    export const popMaps = createNamespacedHelpers('pop')
    

    Confirm.vue组件的<script>中

    import {popMaps} from '@/modules/maps'
    
    // 映射pop.js模块的state和actions到组件上
    const popActions = popMaps.mapActions(['setConfirm'])
    const popState = popMaps.mapState(['confirm'])
    
    export default {
        computed: {
            ...popState
        },
        methods: {
            ...popActions,
            closeConfirm (e) {
                this.setConfirm({open: false, cb: null})
            },
            // 要调出confirm就在那个需要调这个的组件中映射setConfirm且创建这个函数
            // 或者使用mixins 全局添加(所有组件都添加了,注意)或者局部添加
            // 像这种高频率的弹出窗(Toast),可以添加到全局mixin中
            // cb中的this要指定Vue实例 在vue组件中可以箭头函数或者bind this.openConfirm('haha', () => {})
            openConfirm (text, cb = null) {
                this.setConfirm({text, open: true, cb})
            },
            submit (res) {
                if (res) {
                    const {cb} = this.confirm
                    cb && cb()
                }
                return this.closeConfirm()
            }
        }
    }
    

    Confirm.vue组件中的<template>

    <template>
        <pop-box :open='confirm.open' @close='closeConfirm'>
            <div class='pop-confirm'>
                <div class='confirm-text'>{{confirm.text}}</div>
                <!-- 下面是确认和取消按钮 -->
                <ul class='confirm-btns'>
                    <li class='btn' @click='submit(false)'>取消</li>
                    <li class='btn' @click='submit(true)'>确认</li>
                </ul>
            </div>  
        </pop-box>
    <template>
    
  • 相关阅读:
    反射+自定义注解,实现获取注解标记的属性
    jeecg导出Excel
    Date类的getYear(),getMonth过时,现在的获取方法
    Mysql的sql语句,Delete 中包含 not in
    EhCache与Redis的比较
    SpringMVC+Bootstrap项目
    按位运算| ^
    按步长检索数据,放缓有问题数据的处理
    DateTime 格式相比较,timestampdiff() 函数的运用
    作用域在函数定义时就已经确定了。而不是在函数调用时确定
  • 原文地址:https://www.cnblogs.com/lantuoxie/p/9044983.html
Copyright © 2020-2023  润新知