当前位置: 首页 > news >正文

plpo vue实战版教程

vue实战版教程

  • 什么是plpo
  • 安装
    • 1.将plop添加到您的项目
    • 2.全局安装plop(可选,但建议使用方便)
    • 3.在项目根目录下创建一个 plopfile.js
  • vue 实战(后台管理系统 - 增删改查)
    • 所需文件
    • 文件介绍
      • 创建配置文件 plopfile.js
      • 创建模板和脚本命令文件
        • 模板创建逻辑
        • 根据自己的需求创建view模板文件
          • view --list 文件夹
          • view --detail/drawer文件夹
          • view --detail/modal文件夹 同理(不做描述了)
    • 运行创建项目
      • 效果展示

什么是plpo

它是一个命令行工具,专门用于构建生成器,这些生成器可以帮助开发者快速生成代码模板,特别是对于大型的后台管理系统,页面很多相似的内容,重复率很高的项目,我们可以设立一个模板(列表、详情、路由等)(vue、js、css文件等’),一次构建重复创建。

安装

1.将plop添加到您的项目

 npm install --save-dev plop
  • ps: 如果你没有全局安装plop,你需要在设置一个 npm 脚本命令来为你运行polp:
//package.json
{...,"scripts":{"plop":"plop"},...
}

2.全局安装plop(可选,但建议使用方便)

npm install -g plop

3.在项目根目录下创建一个 plopfile.js

创建一个基本的生成器

// plop 的入口文件 plopfile.js
// 需要导出一个函数,函数接收一个plop对象,用于创建生成器任务
module.exports = plop => {// setGenerator可以设置一个生成器,每个生成器都可用于生成特定的文件// 接收两个参数,生成器的名称和配置选项plop.setGenerator('component', {// 生成器的描述description: 'create a component',// 发起命令行询问(将来生成器工作时发起的询问,它是一个数组,每个对象都是一次询问)prompts: [{// 类型type: 'input',// 接收变量的参数name: 'name',// 询问提示信息message: 'component name',// 默认值default: 'MyComponent'}],// 完成命令行后执行的操作,每个对象都是动作对象actions: [{// 动作类型type: 'add',// 生成文件的输出路径path: 'src/views/${name}/list/index.vue',// template 模板的文件路径,目录下的文件遵循hbs的语法规则templateFile: 'plopTemplate/view/list/index.vue'}]})
}
  • actions 之 path
path中的{{name}}是一种变量书写形式,它对应的就是prompts对象数组中的name接收的值
假如 name='Test1',那这里的path就相当于src/views/Test1/list/index.vue
  • actions 之 templateFile

templateFile 就是该文件的模板文件路径
在这里插入图片描述
我们在模板中同样可以使用{{变量名称}},的方式来传入我们在prompts中接收的变量

在这里插入图片描述
多个动作
同样的,如果我们希望生成多个文件,就可以配置多个动作对象和对应的模板即可即可,如

  actions: [{type: "add",path: `src/views/${name}/list/index.vue`,templateFile: "plopTemplate/view/list/index.vue",}, {type: "add",path: `src/views/${name}/detail/index.vue`,templateFile: "plopTemplate/view/detail/index.vue",}]

vue 实战(后台管理系统 - 增删改查)

所需文件

在这里插入图片描述

文件介绍

在项目跟目录下,创建配置文件 plopfile.js,内容如下:

创建配置文件 plopfile.js

const viewGenerator = require("./plopTemplate/prompt");
module.exports = (plop) => {plop.setGenerator("create", viewGenerator);
};

plopfile.js 中导出一个函数,该函数接受 plop 对象作为它的第一个参数;
plop 对象公开包含 setGenerator(name, config)函数的 plop api 对象。

创建模板和脚本命令文件

在项目根目录下新建文件夹(如plopTemplates),放置模板(view/list view/detail文件)和脚本命令(prompt.js)文件

模板创建逻辑

prompt.js脚本命名如下,提示语和创建动作
1.手动输入页面名称
2.是否添加增改组件
3.选择是(选择添加抽屉or弹窗)
4.是否添加路由

module.exports = {description: "新建一个模块",prompts: [{type: "input",name: "name",message: "页面名称:",validate(name) {if (!name) {return "请输入页面名称";}return true;},},{type: "confirm",name: "hasDetail",message: "你想要给新页面添加详情组件(抽屉/弹窗)吗?",},{type: "confirm",name: "hasDrawer",message: "你想要给模块添加详情抽屉吗?",when: function (answer) {// 当hasDetail为true的时候才会到达这步return answer.hasDetail; // 只有我return true才会这个confirm},},{type: "confirm",name: "hasModal",message: "你想要给模块添加详情弹窗吗?",when: function (answer) {return !answer.hasDrawer && answer.hasDetail;},},{type: "confirm",name: "hasRoute",message: "你想要给模块增加路由吗?(在route下创建为name的路径)",},],actions: (data) => {const { hasDrawer, hasModal, hasRoute, name } = data;let listActions = [];const baseActions = [{type: "add",path: `src/views/${name}/list/index.vue`,templateFile: "plopTemplate/view/list/index.vue",},{type: "add",path: `src/views/${name}/list/index.less`,templateFile: "plopTemplate/view/list/index.less",},{type: "add",path: `src/views/${name}/list/columns.js`,templateFile: "plopTemplate/view/list/columns.js",},];listActions = listActions.concat(baseActions);const drawerActions = [{type: "add",path: `src/views/${name}/detail/drawer/index.vue`,templateFile: "plopTemplate/view/detail/drawer/index.vue",},{type: "add",path: `src/views/${name}/detail/drawer/index.less`,templateFile: "plopTemplate/view/detail/drawer/index.less",},];const modalActions = [{type: "add",path: `src/views/${name}/detail/modal/index.vue`,templateFile: "plopTemplate/view/detail/modal/index.vue",},{type: "add",path: `src/views/${name}/detail/modal/index.less`,templateFile: "plopTemplate/view/detail/modal/index.less",},];const routeAction = [{type: "add",path: `src/router/routes/${name}.js`,templateFile: "plopTemplate/route/index.js",},];if (hasDrawer) {listActions = listActions.concat(drawerActions);}if (hasModal) {listActions = listActions.concat(modalActions);}if (hasRoute) {listActions = listActions.concat(routeAction);}return listActions;},
};
根据自己的需求创建view模板文件

下面只做于逻辑参考

view --list 文件夹
  • index.vue
<!-- eslint-disable -->
<template><div class="{{name}}Container"><divstyle="padding: 10px 0"class="search"><div class="search_form"><a-inputstyle="width: 200px"placeholder="请输入用户名"suffix-icon="el-icon-search"v-model="query.username"></a-input></div><div class="search_btns"><a-buttonclass="btn"type="primary"@click="getList(query)">搜索</a-button><a-buttonclass="btn"type="warning"@click="getList">重置</a-button></div></div><div class="btns">{{#if hasDetail}}<a-button@click="handleAdd"class="float-left"type="primary">新增</a-button>{{/if}}<div class="btns_right"><a-buttontype="primary"@click="handleImport">导入</a-button><a-buttontype="primary"@click="handleExport">导出</a-button></div></div><a-tablebordered:data-source="dataSource":columns="columns"><templateslot="action"slot-scope="text, record">{{#if hasDetail}}<a @click="handleDetail(record)">编辑</a>{{/if}}<astyle="color: red; margin-left: 10px"@click="handleDel(record)">删除</a></template></a-table>{{#if hasModal}}<modal-comv-model="detailVisible":detailData="detailData"></modal-com>{{/if}}{{#if hasDrawer}}<drawer-comv-model="detailVisible":detailData="detailData"></drawer-com>{{/if}}</div>
</template>
<script>
import getColumns from "./columns";
{{#if hasDrawer}}
import drawerCom from "../detail/drawer/index.vue";
{{/if}}
{{#if hasModal}}
import modalCom from "../detail/modal/index.vue";
{{/if}}
export default {name:"{{name}}",components: {{{#if hasDrawer}}drawerCom,{{/if}}{{#if hasModal}}modalCom,{{/if}}},data() {return{columns: getColumns.call(this),dataSource: [{ id:1,name: "李荣浩", age: 18, sex: "男" },{ id:2,name: "李菲儿", age: 20, sex: "女" },{ id:3,name: "李小龙", age: 26, sex: "男" },],detailVisible: false,detailData: {},query:{username:''}}},mounted() {this.getList();},methods: {// 请求数据getList(query={}){//请求逻辑},// 导入handleImport() {},// 导出handleExport() {},// 跳转添加handleAdd() {this.detailVisible = true;this.detailData={}},// 跳转详情handleDetail(record) {this.detailVisible = true;this.detailData=record},// 删除handleDel(record) {this.$confirm({title: "系统提示",content: "确定要删除该条数据吗",onOk: async () => {try {//删除逻辑} catch (e) {console.log(e);}},});},},
}
</script>
<style lang="less">
@import "./index.less";
</style>
  • columns.js
const getColumns = function () {return [{title: "序号",dataIndex: "index",customRender: (text, record, index) => index + 1,fixed: "left",},{title: "姓名",dataIndex: "name",},{title: "年龄",dataIndex: "age",},{title: "性别",dataIndex: "sex",},{title: "操作",width: 120,scopedSlots: {customRender: "action",},fixed: "right",},];
};export default getColumns;
  • index.less
.{{name}}Container {margin: 10px;.search {float: left;&_form {float: left;}&_btns {float: left;.ant-btn {margin-left: 10px;}}}.btns {height: 60px;display: flex;width: 100%;justify-content: space-between;position: relative;&_right {position: absolute;right: 0;}.ant-btn {margin: 10px 10px 10px 0px;}}
}
view --detail/drawer文件夹
  • index.vue
<template><a-drawerwidth="500"placement="right":visible="visible"@close="handleCancel":z-index="2024":title="title"><div class="{{name}}Detail"><a-form:form="form"class="fields"><a-form-itemlabel="姓名"class="fields-item"><a-inputv-decorator="['name', { rules: [{ required: true, message: '请填写姓名!' }] }]"/></a-form-item><a-form-itemlabel="年龄"class="fields-item"><a-input v-decorator="['age', { rules: [{ required: true, message: '请填写年龄!' }] }]" /></a-form-item><a-form-itemlabel="性别"class="fields-item"><a-radio-groupv-decorator="['sex', { rules: [{ required: true, message: '请选择性别!' }] }]"><a-radio value="男"></a-radio><a-radio value="女"></a-radio></a-radio-group></a-form-item></a-form></div><div class="button-wrap"><a-buttontype="plain"class="mg-r_2"@click="handleCancel">取消</a-button><a-buttontype="primary":loading="loading"@click="onSave">保存</a-button></div></a-drawer>
</template><script>
export default {name: "{{name}}Detail",props: {value: {type: Boolean,default: false,},detailData: {type: Object,default: () => {},},},model: {prop: "value",event: "change",},computed: {visible: {get() {return this.value;},set(val) {this.$emit("change", val);},},title() {return this.detailData?.id ? "编辑" : "新增";},},watch: {visible(newVal) {if (newVal) {if (this.detailData.id) {const { age, sex, name } = this.detailData;this.$nextTick(() => {this.form.setFieldsValue({age,sex,name,});});} else {this.form.resetFields();}}},},data() {return {loading: false,form: this.$form.createForm(this),};},methods: {handleCancel() {this.$emit("change", false);},onSave() {this.form.validateFields(async (err, values) => {if (!err) {// 保存逻辑}});},},
};
</script><style lang="less">
@import "./index.less";
</style>
  • index.less
.{{name}}Detail{position: relative;.fields {&-item {display: flex;width: 100%;.ant-form-item-control-wrapper {flex: 1;}}}}
.button-wrap {width: calc(100% - 60px);display: flex;justify-content: center;align-items: center;position: absolute;bottom: 20px;
}
view --detail/modal文件夹 同理(不做描述了)

运行创建项目

pnpm run plop view

在这里插入图片描述

效果展示

在这里插入图片描述

  • 抽屉详情
    在这里插入图片描述

在这里插入图片描述

  • 弹窗详情
    在这里插入图片描述

在这里插入图片描述

  • 无详情
    在这里插入图片描述

在这里插入图片描述


http://www.mrgr.cn/news/48515.html

相关文章:

  • OAuth2.1的code_challenge和code_vertifier理解
  • 五子棋项目自动化测试
  • 电脑无线网wifi和有线网同时使用(内网+外网同时使用)
  • 【Linux 从基础到进阶】防止数据泄露的策略与工具
  • 【WebGIS】Cesium:天地图加载
  • 每日OJ题_牛客_比那名居的桃子_滑动窗口/前缀和_C++_Java
  • C语言—双链表
  • 科大讯飞嵌入式面试题及参考答案
  • c++ 多线程全局变量安全操作------原子操作
  • 网工内推 | 初级网工,Base北京,IE认证优先,最高14K+餐补
  • Feign的使用
  • 【专题】智启未来:新质生产力引擎驱动下的智能制造行业革新报告合集PDF分享(附原数据表)
  • 邮件营销案例成功技巧:如何打动目标客户?
  • 18063 圈中的游戏
  • 探索极简计算的新边界:从Uxn虚拟机看未来编程生态
  • 儿童画画在线支付预约报名表单在线制作小程序源码系统 带完整的安装代码包以及搭建部署教程
  • 思迅商云8四级分类
  • 哪个牌子的护眼灯防蓝光效果好?五款市场上评价较高的护眼台灯
  • xtu oj 彩球
  • 自监督学习:引领机器学习的新革命