项目优化---业务实践封装三

78 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

这是项目优化最后一章,对于组件流转控制和公共工具库的封装,简单记录下
组件流程控制,主要集中在hooks里

原页面使用方式:

index.vue

  <el-button v-if="state.status == 'showBtn'" type="primary" @click="show">开始回避确认</el-button>
  <div class="text" v-if="state.status == 'showContent'"></div>
const props = defineProps({
  data: String,
  index: String,
  callbackFun: Function,
});

const state = reactive({
    status:props.data.contentStatus,
    dialogVisible: false,
    list:[]
});

watch(()=>props.data.contentStatus,(newVal)=>{
  state.status = newVal
})

const show = () => {
    state.dialogVisible = true;
    state.status = "showContent";
    // 通知显示下一下按钮
    props.callbackFun(props.index + 1)
};

上述代码,主要是每个组件内部,接收页面状态(来着上一环节发送的通知),进行对应显示,操作完成后,通知下一环节

运行没毛病,只是代码写的有点多,对于我这种爆脾气,搞这么麻烦,就来气
想想,怎么优化呢?

还是要做封装,页面使用其实只需要状态控制

那我们来新设计一下

1、暴露一个对象 Control ,里面有showBtn、showContent,控制区域显隐
2、暴露一个Next方法,来控制进入下个环节(组件)
3、暴露一个executeControl,由组件内部根据情况自己调用,来控制Control里面的状态

Control

    /**
     * 状态控制器
     */
    const Control = reactive({
        showBtn: false,
        showContent: false
    });
    
<el-button v-if="Control.showBtn" type="primary" @click="show">修改</el-button>
<div class="text" v-if="Control.showContent"></div>
 
import { useMonitor } from "../hooks";
const { Control } = useMonitor()

看着一两句搞定,有点意思,但是这个怎么实现呢

Next

/**
 * 执行控制器-下一环节
 */
const Next = (cb) => {
  // 通知显示下一下按钮
  initialValue.callbackFun(initialValue.index + 1)
  console.debug(`>> 进入环节${initialValue.index + 1} << `);
  executeControl('showBtn',false)
  cb && cb()
}

executeControl

/**
 * 执行控制器
 */
const executeControl = (key, value = true) => {
  Control[key] = value
}

上全代码


import { ref, reactive, watch } from "vue";

export default function (initialValue) {
    /**
     * 状态控制器
     */
    const Control = reactive({
        showBtn: false,
        showContent: false
    });
    /**
     * 执行控制器
     */
    const executeControl = (key, value = true) => {
        Control[key] = value
    }
    /**
     * 执行控制器-下一环节
     */
    const Next = (cb) => {
      // 通知显示下一下按钮
      initialValue.callbackFun(initialValue.index + 1)
      console.debug(`>> 进入环节${initialValue.index + 1} << `);
      executeControl('showBtn',false)
      cb && cb()
    }
    /**
     * 监听页面状态
     */
    watch(() => initialValue.data.contentStatus, (key) => {
        console.debug(`当前页面【${initialValue.index}】 通知:>> `, key);
        executeControl(key)
    })
    return {
        Control,
        executeControl,
        Next
    };
}

使用方式

<el-button v-if="Control.showBtn" type="primary" @click="show">修改</el-button> 
<div class="text" v-if="Control.showContent">
   <el-button v-if="Control.showBtn" type="primary" @click="saveHandel">确认</el-button> 
</div> 

import { useMonitor } from "../hooks"; 
const props = defineProps({
  data: String,
  index: String,
  callbackFun: Function,
});
const { Control, Next } = useMonitor(props)

// 确认
const saveHandel =()=>{
...
// 确认完成后,进行下一环节
Next()
}

工具库部分(utils.js):

1、字典的提取

  /**
   * 审查-字段状态
   */
  export const DIC_WITH=[
    {
      value: "1",
      label: "符合",
    },
    {
      value: "2",
      label: "不符合",
    },
  ]

2、提前集合对象内字段,拼装成list

  /**
 * 提前集合对象内字段,拼装成list
 * @param {*} list 
 * @param {*} field 
 * @returns 
 */
export const getExtEle = (list, field) => {
  return list.reduce((prev, next) => prev.concat(next[field]), [])
}

3、转换成字典结构数据

/**
 * @description: 字段转换
 * @param {*} list 来源字典列表 Array
 * @param {*} label 转换 label 对象
 * @param {*} value 转换 value 对象
 * @return {*} 转换后list
 */
 export const formatDict = (list=[], {label='label' , value='value'}) => {
  return list?.map((item)=>{
    item.label = item[label];
    item.value = item[value];
    return item
  })
}

4、获取评标室信息

/**
   * 获取评标室信息
   * @param {*} field 属性名称
   * @returns 
   */
 export const getRoom =(field)=>{
    const room = utils.getlocalStorage('room-info') || {}
    return field ? room[field] : room
  }