vue后台管理系统——增删改查列表一键配置

3,726 阅读2分钟

简介

本文主要介绍在vue管理后台项目中简化大量重复的 table 增删改查 ;使用相关配置及可快速完成一个table列表配置及增删改查;本文主要借鉴了Avue的思想进行封装,并基于源码增加了定制化的功能和删除。

前言

由于设计到的大量功能的全面性和完整性,文章会在空余时间针对功能持续更新。相信你在这个过程中对于封装,设计方面肯定跟我一样有种醍醐灌顶的感觉,也欢迎大家在评论区对想添加的功能留言,要是对看到文章的你有所帮助,也不妄花费一番时间了。

注册组件

  1. main.js全局注入Avue组件库
import Avue from './components/avuex/index'
Vue.use(Avue);
  1. components/avuex/index 注册全局组件
import components from './element'
const install = function(Vue){
    //全局注册组件 组件名为组件的name
    components.map(component => {
        Vue.component(component.name, component);
      });
}
export default {
    version:"1.0.0",
    install
}
  1. components/avuex/element 组件入口
//导入所有组件 2020.12.12暂时导入一个
import Crud from './crud/index.vue';
export default [
    Crud
]

一个基础的table

<template>
  <div class="index">
    <mn-crud 
    :data="tableData"
    :option="listOption"> 
    </mn-crud> 
  </div>
</template>

<script type="text/javascript">
export default {
  name: "Index",
  data() {
    return {
      tableData: [{
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          }, {
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          }, {
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          }, {
            date: '2016-05-03',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }],
    };
  },
  computed:{
    listOption(){
      return {
          column: [
            {
              label: '日期',
              prop: 'date',
            },
              {
              label: '姓名',
              prop: 'name',
            },
              {
              label: '地址',
              prop: 'address',
            },
          ]
      }
    }
  },
}
</script>

这样一个简单table列表就已经完成,tableData就是列表数据,listOption就是列表项,是不是方便许多,那么我们一步一步去分析mn-crud这个组件的神秘面纱。

crud核心组件

先贴代码

components/avuex/index

<template>
  <div>
      <el-table :data="list">
          <column :columnOption="tableColumn">
          </column>
      </el-table>  
  </div>
</template>

<script type="text/javascript">
//引入create全局方法
import create from '../../core/create'
import column from './column'

export default create({
  name: "crud",
  props: {
    data:{
      type:Array,
      require:true,
      default:()=>{
        return []
      }
    },
    option: { // 列表配置项
        type: Object,
        required: true,
        default: () => {
          return {};
        }
      }
  },
  components: { column },
  data() {
    return {
        list: [], // 表格展示的数据 
    };
  },
  created(){
    //1.初始化列表数据
    this.dataInit()
    //2.初始化列配置
    this.initTableColumn()
  },
  mounted(){},
  methods: {
    //1.初始化列表数据
    dataInit(){
      this.list = this.data
    },
    //2.初始化列配置
    initTableColumn(){
      this.tableColumn = this.option.column.filter((o) => o.hide !== true)  
    }
  },
})
</script>

<style lang="scss" scoped>
</style>

components/avuex/column

<template>
  <div>
      <template v-for="(column,index) in columnOption">
          <template>
             <el-table-column
              :key="`col_${index}`"
              :prop="column.prop"
              :label="column.label">
             </el-table-column>
          </template>
      </template>
  </div>
</template>

<script type="text/javascript">
export default {
  name: "column",
  props: {
    columnOption: {
      type: Array,
      default: () => {
        return [];
      },
    },
  },
  data() {
    return {};
  },
};
</script>

  • 1.mn-crud从何而来?

上文提到注册全局组件Vue.component(component.name,component); 那么组件名应该是component.name,也就是crud,那么为什么我们使用的组件是mn-crud呢?

注意components/avuex/index中有个create方法,在组件名前加了一个常量名,我这里设置了mn,大家可以任意设置。

import { COMMON_PREFIX_COMPONENT_NAME } from '../global/constant';
import bem from '../utils/bem';
export default function(component){
    component.name = COMMON_PREFIX_COMPONENT_NAME + component.name;
    component.mixins = component.mixins || [];
    component.mixins.push(bem);
    return component; 
}

  • 2.bem方法 一个全局bem命名方法

上一步在mixins引入了bem


const ELEMENT = '__';
const MODS = '--';

const join = (name, el, symbol) => el ? name + symbol + el : name;

const prefix = (name, mods) => {
  if (typeof mods === 'string') {
    return join(name, mods, MODS);
  }

  if (Array.isArray(mods)) {
    return mods.map(item => prefix(name, item));
  }

  const ret = {};
  Object.keys(mods).forEach(key => {
    ret[name + MODS + key] = mods[key];
  });
  return ret;
};

export default {
  methods: {
    b(el, mods) {  
      const { name } = this.$options;
      if (el && typeof el !== 'string') {
        mods = el;
        el = '';
      }
      el = join(name, el, ELEMENT);

      return mods ? [el, prefix(el, mods)] : el;
    }
  }
};


const ELEMENT = '__';
const MODS = '--';

const join = (name, el, symbol) => el ? name + symbol + el : name;

const prefix = (name, mods) => {
  if (typeof mods === 'string') {
    return join(name, mods, MODS);
  }

  if (Array.isArray(mods)) {
    return mods.map(item => prefix(name, item));
  }

  const ret = {};
  Object.keys(mods).forEach(key => {
    ret[name + MODS + key] = mods[key];
  });
  return ret;
};

export default {
  methods: {
    b(el, mods) {  
      const { name } = this.$options;
      if (el && typeof el !== 'string') {
        mods = el;
        el = '';
      }
      el = join(name, el, ELEMENT);

      return mods ? [el, prefix(el, mods)] : el;
    }
  }
};

在全局我们绑定样式便可使用

:class="b()" b('a') b('a', ['b'])渲染出来的class便如下

  • b() // 'mn-crud'
  • b('a') // 'mn-crud__a'
  • b('a', ['b']) // 'mn-crud__a mn-crud__a--b'
  • b(['c', 'd']) // 'mn-crud mn-crud--c mn-crud--d'

时间有限今天先写到这里,后面还有非常多需要完善的地方,基本上就是讲配置的配置加入进来,后面会继续更新的。加入内容会有:

  • 添加page

  • 添加全局table mixins

  • 一键配置增删改查

  • 完善table各种配置

  • 添加列表项字典、校验、重写

  • 等等...

结语

  • 第一次更新时间为:2020/12/12 17:00
  • github Demo地址 mn-avue

第一次只提交了一个非常初始简化的版本,相信你一定能从文章里吸取一定的养分,如果对看到文章的你有一点点帮助的话,点个赞吧,你的支持就是我前行的动力!不积硅步无以至千里!