ABP实践(4)-abp前端vue框架之简单商品增删改查(帮助刚入门的新手快速了解怎么才能加入自己的功能并运行起来)
wuyubing 人气:2提示:如有不明白的地方请先查看前3篇ABP实践系列的文章
1,下载及启动abp项目前后端分离(netcore+vue)
2,修改abp数据库为mysql
3,商品系列api接口(本文主要依赖在这个商品列表接口)
以下正文开始:
1.打开vue项目(这里是用vscode工具)在views文件夹下创建goods文件夹然后创建商品列表goods.vue文件,商品创建create-goods.vue,编辑商品edit-goods.vue
goods.vue文件里的代码如下:
<template> <div> <Card dis-hover> <div class="page-body"> <Form ref="queryForm" :label-width="100" label-position="left" inline> <Row :gutter="16"> <Col span="8"> <FormItem :label="L('Keyword')+':'" style="width:100%"> <Input v-model="pagerequest.keyword" :placeholder="L('GoodsName')"></Input> </FormItem> </Col> <Col span="8"> </Col> </Row> <Row> <Button @click="create" icon="android-add" type="primary" size="large">{{L('Add')}}</Button> <Button icon="ios-search" type="primary" size="large" @click="getpage" class="toolbar-btn">{{L('Find')}}</Button> </Row> </Form> <div class="margin-top-10"> <Table :loading="loading" :columns="columns" :no-data-text="L('NoDatas')" border :data="list"> </Table> <Page show-sizer class-name="fengpage" :total="totalCount" class="margin-top-10" @on-change="pageChange" @on-page-size-change="pagesizeChange" :page-size="pageSize" :current="currentPage"></Page> </div> </div> </Card> <create-goods v-model="createModalShow" @save-success="getpage"></create-goods> <edit-goods v-model="editModalShow" @save-success="getpage"></edit-goods> </div> </template> <script lang="ts"> import { Component, Vue,Inject, Prop,Watch } from 'vue-property-decorator'; import Util from '@/lib/util' import AbpBase from '@/lib/abpbase' import PageRequest from '@/store/entities/page-request' import CreateGoods from './create-goods.vue' import EditGoods from './edit-goods.vue' class PageGoodsRequest extends PageRequest{ keyword:string=''; isActive:boolean=null; } @Component({ components:{CreateGoods,EditGoods} }) export default class Goodss extends AbpBase{ edit(){ this.editModalShow=true; } pagerequest:PageGoodsRequest=new PageGoodsRequest(); createModalShow:boolean=false; editModalShow:boolean=false; get list(){ return this.$store.state.goods.list; }; get loading(){ return this.$store.state.goods.loading; } create(){ this.createModalShow=true; } isActiveChange(val:string){ if(val==='Actived'){ this.pagerequest.isActive=true; }else if(val==='NoActive'){ this.pagerequest.isActive=false; }else{ this.pagerequest.isActive=null; } } pageChange(page:number){ this.$store.commit('goods/setCurrentPage',page); this.getpage(); } pagesizeChange(pagesize:number){ this.$store.commit('goods/setPageSize',pagesize); this.getpage(); } async getpage(){ this.pagerequest.maxResultCount=this.pageSize; this.pagerequest.skipCount=(this.currentPage-1)*this.pageSize; await this.$store.dispatch({ type:'goods/getAll', data:this.pagerequest }) } get pageSize(){ return this.$store.state.goods.pageSize; } get totalCount(){ return this.$store.state.goods.totalCount; } get currentPage(){ return this.$store.state.goods.currentPage; } columns=[{ title:this.L('GoodsName'), key:'goodsName' },{ title:this.L('Price'), key:'price' },{ title:this.L('Describe'), key:'describe' },{ title:this.L('Actions'), key:'Actions', width:150, render:(h:any,params:any)=>{ return h('div',[ h('Button',{ props:{ type:'primary', size:'small' }, style:{ marginRight:'5px' }, on:{ click:()=>{ this.$store.commit('goods/edit',params.row); this.edit(); } } },this.L('Edit')), h('Button',{ props:{ type:'error', size:'small' }, on:{ click:async ()=>{ this.$Modal.confirm({ title:this.L('Tips'), content:this.L('DeleteGoodsConfirm'), okText:this.L('Yes'), cancelText:this.L('No'), onOk:async()=>{ await this.$store.dispatch({ type:'goodshttps://img.qb5200.com/download-x/delete', data:params.row }) await this.getpage(); } }) } } },this.L('Delete')) ]) } }] async created(){ this.getpage(); } } </script>
create-goods.vue代码:
<template> <div> <Modal :title="L('CreateNewGoods')" :value="value" @on-ok="save" @on-visible-change="visibleChange" > <Form ref="goodsForm" label-position="top" :rules="goodsRule" :model="goods"> <FormItem :label="L('GoodsName')" prop="goodsName"> <Input v-model="goods.goodsName" :maxlength="32" :minlength="2"></Input> </FormItem> <FormItem :label="L('Price')" prop="price"> <Input v-model="goods.price" :maxlength="32" :minlength="2"></Input> </FormItem> <FormItem :label="L('Describe')" prop="describe"> <Input v-model="goods.describe" :maxlength="1024"></Input> </FormItem> <FormItem :label="L('Qty')" prop="surplusQty"> <Input v-model="goods.surplusQty" :maxlength="18"></Input> </FormItem> </Form> <div slot="footer"> <Button @click="cancel">{{L('Cancel')}}</Button> <Button @click="save" type="primary">{{L('OK')}}</Button> </div> </Modal> </div> </template> <script lang="ts"> import { Component, Vue,Inject, Prop,Watch } from 'vue-property-decorator'; import Util from '../../../lib/util' import AbpBase from '../../../lib/abpbase' import Goods from '@/store/entities/goods'; @Component export default class CreateGoods extends AbpBase{ @Prop({type:Boolean,default:false}) value:boolean; goods:Goods=new Goods(); save(){ (this.$refs.goodsForm as any).validate(async (valid:boolean)=>{ if(valid){ await this.$store.dispatch({ type:'goods/create', data:this.goods }); (this.$refs.goodsForm as any).resetFields(); this.$emit('save-success'); this.$emit('input',false); } }) } cancel(){ (this.$refs.goodsForm as any).resetFields(); this.$emit('input',false); } visibleChange(value:boolean){ if(!value){ this.$emit('input',value); } } goodsRule={ goodsName:[{required: true,message:this.L('FieldIsRequired',undefined,this.L('GoodsName')),trigger: 'blur'}], // tenancyName:[{required:true,message:this.L('FieldIsRequired',undefined,this.L('TenancyName')),trigger: 'blur'}], // adminEmailAddress:[{required:true,message:this.L('FieldIsRequired',undefined,this.L('AdminEmailAddress')),trigger: 'blur'},{type: 'email'}] } } </script>
edit-goods.vue代码:
<template> <div> <Modal :title="L('EditGoods')" :value="value" @on-ok="save" @on-visible-change="visibleChange" > <Form ref="goodsForm" label-position="top" :rules="goodsRule" :model="goods"> <FormItem :label="L('GoodsName')" prop="goodsName"> <Input v-model="goods.goodsName" :maxlength="32" :minlength="2"></Input> </FormItem> <FormItem :label="L('Price')" prop="price"> <Input v-model="goods.price" :maxlength="32" :minlength="2"></Input> </FormItem> <FormItem :label="L('Describe')" prop="describe"> <Input v-model="goods.describe" :maxlength="1024"></Input> </FormItem> <FormItem :label="L('Qty')" prop="surplusQty"> <Input v-model="goods.surplusQty" :maxlength="18"></Input> </FormItem> </Form> <div slot="footer"> <Button @click="cancel">{{L('Cancel')}}</Button> <Button @click="save" type="primary">{{L('OK')}}</Button> </div> </Modal> </div> </template> <script lang="ts"> import { Component, Vue,Inject, Prop,Watch } from 'vue-property-decorator'; import Util from '../../../lib/util' import AbpBase from '../../../lib/abpbase' import Goods from '@/store/entities/goods'; @Component export default class EditGoods extends AbpBase{ @Prop({type:Boolean,default:false}) value:boolean; goods:Goods=new Goods(); save(){ (this.$refs.goodsForm as any).validate(async (valid:boolean)=>{ if(valid){ await this.$store.dispatch({ type:'goods/update', data:this.goods }); (this.$refs.goodsForm as any).resetFields(); this.$emit('save-success'); this.$emit('input',false); } }) } cancel(){ (this.$refs.goodsForm as any).resetFields(); this.$emit('input',false); } visibleChange(value:boolean){ if(!value){ this.$emit('input',value); }else{ this.goods=Util.extend(true,{},this.$store.state.goods.editGoods); } } goodsRule={ // name:[{required: true,message:this.L('FieldIsRequired',undefined,this.L('TenantName')),trigger: 'blur'}], // tenancyName:[{required:true,message:this.L('FieldIsRequired',undefined,this.L('TenancyName')),trigger: 'blur'}] } } </script>
2.在store>entities目录下创建一个实体goods.ts
代码如下:
import Entity from './entity' export default class Goods extends Entity<string>{ goodsName:string; price:number; describe:string; surplusQty:number; }
3.在store>modules下创建商品相关的请求服务器方法goods.ts
代码如下:
import {Store,Module,ActionContext} from 'vuex' import ListModule from './list-module' import ListState from './list-state' import Goods from '../entities/goods' import Ajax from '../../lib/ajax' import PageResult from '@/store/entities/page-result'; import ListMutations from './list-mutations' interface GoodsState extends ListState<Goods>{ editGoods:Goods; } class GoodsModule extends ListModule<GoodsState,any,Goods>{ state={ totalCount:0, currentPage:1, pageSize:10, list: new Array<Goods>(), loading:false, editGoods:new Goods() } actions={ async getAll(context:ActionContext<GoodsState,any>,payload:any){ context.state.loading=true; let reponse=await Ajax.get('/api/services/app/Goods/GetAll',{params:payload.data}); context.state.loading=false; let page=reponse.data.result as PageResult<Goods>; context.state.totalCount=page.totalCount; context.state.list=page.items; }, async create(context:ActionContext<GoodsState,any>,payload:any){ await Ajax.post('/api/services/app/Goods/Create',payload.data); }, async update(context:ActionContext<GoodsState,any>,payload:any){ await Ajax.put('/api/services/app/Goods/Update',payload.data); }, async delete(context:ActionContext<GoodsState,any>,payload:any){ await Ajax.delete('/api/services/app/Goods/Delete?Id='+payload.data.id); }, async get(context:ActionContext<GoodsState,any>,payload:any){ let reponse=await Ajax.get('/api/services/app/Goods/Get?Id='+payload.id); return reponse.data.result as Goods; } }; mutations={ setCurrentPage(state:GoodsState,page:number){ state.currentPage=page; }, setPageSize(state:GoodsState,pagesize:number){ state.pageSize=pagesize; }, edit(state:GoodsState,goods:Goods){ state.editGoods=goods; } } } const goodsModule=new GoodsModule(); export default goodsModule;
4.在store的index.ts文件里引入goods模块
5.在路由文件里添加商品router文件夹下的router.ts
6.大功告成可以运行看下结果yarn serve启动项目(不知道怎么启动项目的请回到第一篇文章重新回顾)
注意:是不是发现到处都是英文,可能有人就想直接去改代码里的名称了直接改为中文这样是可以的但是你发现你切换语言之后他不会变一直都是固定的,所以这里需要在后台配置文件对应的语言crazy-zh-Hans.xml里增加配置.
我们去配置两个尝试一下(后台改动配置重新启动,前端只需要刷新就生效了)
再来看看结果
下一篇讲一下abp框架的权限相关创建.
对你有帮助的话点个推荐,大神请直接忽视或者指点一二
加载全部内容