plop 生成前端页面
<p>主要配置文件 plopfile.js</p>
<pre><code class="language-javascript">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)
}
</code></pre>
<p><img src="https://www.showdoc.com.cn/server/api/attachment/visitfile/sign/b9b9e4d69d0d3b5fee8fbdfce395bf05" alt="" /></p>
<p>//prompt.js</p>
<pre><code class="language-javascript">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]
},
}
</code></pre>
<p>//生成的 页面的模板</p>
<ol>
<li>views/index.hbs</li>
</ol>
<pre><code class="language-javascript">
<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>
</code></pre>
<p>2: 路由文件配置数据
router/index.hbs</p>
<pre><code class="language-javascript">
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;</code></pre>
<p>3: mock/index.hbs mock 数据模板</p>
<pre><code class="language-javascript">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: '模拟删除成功',
}
},
},
]
</code></pre>