zoukankan      html  css  js  c++  java
  • 全局组件设计

    全局组件设计

    不管是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>
    
  • 相关阅读:
    EntityFramework优缺点
    领导者与管理者的区别
    七个对我最好的职业建议(精简版)
    The best career advice I’ve received
    Difference between Stored Procedure and Function in SQL Server
    2015年上半年一次通过 信息系统项目管理师
    Difference between WCF and Web API and WCF REST and Web Service
    What’s the difference between data mining and data warehousing?
    What is the difference between a Clustered and Non Clustered Index?
    用new创建函数的过程发生了什么
  • 原文地址:https://www.cnblogs.com/lantuoxie/p/9044983.html
Copyright © 2011-2022 走看看