plop 生成前端页面

主要配置文件 plopfile.js

const viewGenerator = require('./templates/view/prompt')
const curdGenerator = require('./templates/curd/prompt')
const componentGenerator = require('./templates/component/prompt')
// const mockGenerator = require('./templates/mock/prompt')
const vuexGenerator = require('./templates/vuex/prompt')
// const routerGenerator = require('./templates/router/prompt')

/**************清楚标签*******************/
var fs = require('fs')
let configs = require('./configs')
function transformTemplate() {
  configs.views.map((item) => {
    let filePath = `./src/views/${item.moduleName}/index.vue`
    fs.readFile(filePath, 'utf8', function (err, data) {
      if (err) {
        return console.log(err)
      }
      var result = data.replace(/Template/g, '')
      console.log(result)
      fs.writeFile(filePath, result, 'utf8', function (err) {
        if (err) return console.log(err)
      })
    })
  })
}

/**************清楚标签*******************/

module.exports = (plop) => {
  plop.setGenerator('view', viewGenerator)
  // plop.setGenerator('mock&api', mockGenerator)
  // plop.setGenerator('router', routerGenerator)
  plop.setHelper('properArry', (x1, x2, options) => {
    return JSON.stringify(x1)
  })
  // plop.setHelper('properForm', (x1, x2, options) => {
  //   console.log(x1)
  //   console.log(x2)
  //   console.log(options)
  //   return JSON.stringify(
  //     x1.reduce((prev, next) => {
  //       if (!prev.hasOwnProperty(next.prop)) {
  //         prev[next.prop] = ''
  //       }
  //       return prev
  //     }, {})
  //   )
  // })
  plop.setHelper('ifInput', function (x1, x2, options) {
    if (x2.type == 'input') {
      return options.fn(this)
    } else {
      return options.inverse(this)
    }
  })

  plop.setHelper('ifSelect', function (x1, x2, options) {
    if (x2.type == 'select') {
      return options.fn(this)
    } else {
      return options.inverse(this)
    }
  })

  plop.setHelper('ifDate', function (x1, x2, options) {
    if (x2.type == 'date') {
      return options.fn(this)
    } else {
      return options.inverse(this)
    }
  })
  plop.setHelper('ifSwitch', function (x1, x2, options) {
    if (x2.type == 'switch') {
      return options.fn(this)
    } else {
      return options.inverse(this)
    }
  })
  setTimeout(() => {
    transformTemplate()
  }, 2000)

  // plop.setGenerator('curd', curdGenerator)
  // plop.setGenerator('component', componentGenerator)
  // plop.setGenerator('mock&api', mockGenerator)
  // plop.setGenerator('vuex', vuexGenerator)
}

//prompt.js

let configs = require('../../configs')
function createArray(arr, type) {
  return arr
    .filter((a) => a.parentId)
    .map((item) => {
      return {
        type: 'add',
        path: `src/views/${item.moduleName}/${type}.vue`,
        templateFile: `./templates/view/${type}.hbs`,
        skipIfExists: true,
        data: {
          name: item.moduleName,
          formItems: item.formItems ? item.formItems : [],
          columns: item.columns ? item.columns : [],
        },
      }
    })
}
function fillArray(arr) {
  return arr.reduce((prev, next) => {
    let obj = {}
    if (!next.parentId) {
      prev.push({
        path: next.path,
        title: next.title,
        id: next.id,
        name: next.moduleName,
        parentId: null,
        children: [],
        component: 'Layout',
      })
    } else {
      let index = prev.findIndex((item) => item.id === next.parentId)
      if (index > -1) {
        prev[index]['children'].push({
          path: next.path,
          title: next.title,
          id: next.id,
          name: next.moduleName,
          parentId: next.parentId,
          component: next.component,
        })
      }
    }
    return prev
  }, [])
}
module.exports = {
  description: '创建view',
  prompts: [],
  actions: () => {
    //生成列表页
    let index = createArray(configs.views, 'index')
    // let index = configs.views
    //   .filter((a) => a.parentId)
    //   .map((item) => {
    //     return {
    //       type: 'add',
    //       path: `src/views/${item.moduleName}/index.vue`,
    //       templateFile: './templates/view/index.hbs',
    //       skipIfExists: true,
    //       data: {
    //         name: item.moduleName,
    //         formItems: item.formItems ? item.formItems : [],
    //         columns: item.columns ? item.columns : [],
    //       },
    //     }
    //   })
    ////生成编辑页
    // let edit = configs.views
    //   .filter((a) => a.parentId)
    //   .map((item) => {
    //     return {
    //       type: 'add',
    //       path: `src/views/${item.moduleName}/edit.vue`,
    //       templateFile: './templates/view/edit.hbs',
    //       skipIfExists: true,
    //       data: {
    //         name: item.moduleName,
    //       },
    //     }
    //   })
    let edit = createArray(configs.views, 'edit')

    //生成路由配置文件
    let createRoute = {
      type: 'add',
      path: `src/router/routerTest/index.js`,
      templateFile: './templates/router/index.hbs',
      skipIfExists: true,
      data: {
        routers: fillArray(configs.views),
      },
    }

    //生成 mock api 文件

    let controller = configs.views.map((item) => {
      return {
        type: 'add',
        path: `mock/controller/${item.moduleName}.js`,
        templateFile: './templates/mock/index.hbs',
        data: {
          name: item.moduleName,
          columns: item.columns,
          form: item.formItems,
        },
      }
    })
    let api = configs.views.map((item) => {
      return {
        type: 'add',
        path: `src/api/testApi/${item.moduleName}.js`,
        templateFile: './templates/api/index.hbs',
        data: { name: item.moduleName },
      }
    })

    return [...index, ...edit, createRoute, ...controller, ...api]
  },
}

//生成的 页面的模板

  1. views/index.hbs

<template>
  <div class="{{ dashCase name }}-container">
       <!-- 查询表单 -->
      <el-form :inline="true" ref="form"  :model="form">
           {{#each formItems}}  
            <el-form-item label="{{label}}" prop="{{prop}}">
       {{#ifInput  ...}}
          <el-input
                v-model="form.{{prop}}"
                placeholder="请输入{{label}}"
            ></el-input> 
       {{else}}
          {{#ifSelect  ...}}
                <el-select v-model="form.{{prop}}" placeholder="请选择">
                    <el-option
                    v-for="item in [
                      { label: '待结算', value: 0 },
                      { label: '已结算', value: 1 },
                    ]"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
          {{else}}
          {{#ifDate}}
               <el-date-picker type="date" placeholder="选择{{label}}" v-model="form.{{prop}}"  style="width: 100%;"></el-date-picker>
          {{else}}
          {{#ifSwitch}}
                       <el-switch v-model="form.{{prop}}"></el-switch>
          {{else}}
          {{/ifSwitch}}
          {{/ifDate}}
          {{/ifSelect}}
        {{/ifInput}} 
             </el-form-item>
          {{/each}}
             <el-form-item>
                  <el-button type="primary" icon="el-icon-search" @click="search">
                    查询
                  </el-button>
                  <el-button plain @click="reset" icon="el-icon-refresh">
                    重置
                  </el-button>
            </el-form-item>
      </el-form>
      <!-- 查询表单 -->
      <!-- 列表组件 -->
      <DyTable
        ref="myDyTable"
        :tableListeners="tableListeners"
        :tableConfig="tableConfig"
        :columns="columns"
        :url="url"
      >
       <template v-slot:control="{ row }">
          <el-button type="text" @click.stop="handlerControl('edit', row)">
             修改
          </el-button>
          <el-button
            type="text"
            class="danger Line"
            @click.stop="deleteCost(row)"
          >
            删除
          </el-button>
        </template>
      </DyTable>
    </div>
</template>

<scriptTemplate>
  import {getList,doEdit,doDelete} from '@/api/testApi/{{properCase name}}.js'
  export default {
    name:'{{ properCase name }}',
    components: {},

    data() {
      return {
        form:{
          {{#each formItems}}
               {{#if prop}}
                 '{{prop}}':'',
              {{/if}}
          {{/each}}
        },
        url:'/{{ properCase name }}/getList',//获取表格数据
        columns:[{{#each columns}}
            {
              {{#if type}}
                 type:'{{type}}',
              {{/if}}
              {{#if label}}
                 label:'{{label}}',
              {{/if}}
               {{#if prop}}
                 prop:'{{prop}}',
              {{/if}}
                {{#if slot}}
                 slot:'{{slot}}',
              {{/if}}
               {{#if action}}
                 action:'{{action}}'
              {{/if}}
            },
        {{/each}}],
        tableConfig: {
          // Dytable配置
          'key': 'myDyTable',
          'row-key': 'id',
       },
      tableListeners: {
        // Dytable监听事件
        'select': (selection, row) => {
         },
        'select-all': (selection) => {
         },
        'row-click': (row, column, event) => {
         },
        },
      }
    },
    created() {},
    mounted() {},
    methods: {
      //重置
      reset() {
          this.$refs['form'].resetFields();
          this.search();
       },
      //删除
      deleteCost(row){
        this.$baseConfirm(
        '确定删除吗?',
        '提示',
        () => {
          try {
            doDelete({id:row.id}).then(res=>{
               this.$refs.myDyTable.deleteOne(row)
               return this.$message.success('删除成功')
            })
          } catch (error) {
            return this.$message.error(error)
          }
        },
        () => {}
        )
      },
      //表单查询
      search(){
          const parames={...this.form}
          this.$refs.myDyTable.fetchTable(parames)
        }
      },
      handlerControl(type,row={}){
         if(type==='add'){ //新增
           this.$router.push({
             path:'{{ properCase name }}/edit',
           })
         }else{//编辑
           this.$router.push({
             path:'{{ properCase name }}/edit',
             query:{
               id:row.id
             }
           })
         }
      }
  }
</scriptTemplate>

2: 路由文件配置数据
router/index.hbs


 const list= [
{{#each routers }}
   {
      name: '{{name}}',
      id: '{{id}}',
      path: '{{path}}',
      component: '{{component}}',
      parentId: '{{parentId}}',
      meta: {
       title: '{{title}}',
       icon: 'archive-line',
      },
      children:[
        {{#each children}}

          {
              name: '{{name}}',
              id: '{{id}}',
              path: '{{path}}',
              component: '{{component}}',
              parentId: '{{parentId}}',
              meta: {
                title: '{{title}}',
                icon: 'archive-line',
              },
          },

        {{/each}}

      ]
   },
{{/each}}
]
export default list;

3: mock/index.hbs mock 数据模板

const { mock } = require('mockjs')
const List = []
const count = 50;
let  props={};
{{#each columns}}
  {{#if prop}}
   {{#if mock}}
        props['{{prop}}']='{{mock}}'
   {{/if}}
  {{/if}}
{{/each}}
for (let i = 0; i < count; i++) {
  List.push(mock(props))
}
module.exports = [
  {
    url: '/{{name}}/getList',
    type: 'get',
    response: (config) => {
      const { name,password, pageNo = 1, pageSize = 20 } = config.query
      let mockList = List.filter((item) => {
        return !(name && item.name.indexOf(name) < 0 || password && item.password.indexOf(password) < 0)
      })
      const list = mockList.filter(
        (item, index) =>
          index < pageSize * pageNo && index >= pageSize * (pageNo - 1)
      )
      return {
        code: 200,
        msg: 'success',
        data: { list, ...{ total: mockList.length } },
      }
    },
  },
  {
    url: '/{{name}}/doEdit',
    type: 'post',
    response: () => {
      return {
        code: 200,
        msg: '模拟保存成功',
      }
    },
  },
  {
    url: '/{{name}}/doDelete',
    type: 'post',
    response: () => {
      return {
        code: 200,
        msg: '模拟删除成功',
      }
    },
  },
]