打包和运行

# 安装依赖

npm install

 

# 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题,或者使用yarn安装也行

npm install --registry=https://registry.npm.taobao.org

 

 

# 启动服务

npm run dev

```

 

# 构建生产环境

npm run build

```

 

## 其它

 

# 代码格式检查

npm run lint

 

# 代码格式检查并自动修复

npm run lint -- --fix

 

一、api使用文档

1.api的使用

utils/request.js对axios进行了二次封装,导出了变量requestrequest封装了几种常用的请求方式(get,post,postForm,put,delete,getFile)

请求方式

请求说明

get

get请求

post

post请求(json格式)

postForm

post请求(formData格式)

put

put请求(json格式)

delete

delete请求

getFile

get请求二次封装导出文件功能,所有的导出文件功能用这个方式即可

另外暴露了整个axios的实例,用于自定义请求(该请求方式可自定义操作,用于后端的各种操作)

用法:

//暴露的request变量,自定义封装的请求方式

import { request } from '@/utils/request'

request.get(url, data)

request.post(url, data)

request.postForm(url, data)

request.put(url, data)

request.delete(url, data)

request.getFile(url, data)

 

//使用axios的实例请求,自定义使用

import request from '@/utils/request'

request({

       url,

       method: 'get',

       params,

       data:,

       headers

    })

2.api文件管理

为了统一管理好接口,根据模块定义一个api.js文件。一个系统有多个模块,每个模块对应多个页面。故一个模块有一个js文件,一个页面中定义一个对象变量存储页面的接口地址。

例如:

// ModuleDistr.js //分销模块,故定义一个js

//例如:分销设置页面里面的所有api(建议每个页面的变量名后缀都是Api和每个接口都需要写注释)

const distrSetApi = {

// 保存菜单

addSettings: (data) => request.post('/activity/admin/distribution/rules/basic/settings', data),

//获取分销规则设置

distributionRules: (data) => request.get('/activity/admin/distribution/rules', data),

 

//保存分销结算设置

addbillingSettings: (data) => request.post('/activity/admin/distribution/rules/billing/settings', data),

 

//切换分销规则开关

updateRulesSwitch: (data) => request.post('/activity/admin/distribution/rules/update/rules/switch', data),

}

//暴露页面变量

export {

    distrSetApi, //分销设置

}

.路由的使用

路由分为本地路由和动态路由(在@/config/config.js中asyncRoutes属性控制)

const config = {

    server: 'http://192.168.0.66:9999', // 少龙 (后端接口地址)

    photoServer: 'http://192.168.0.13:9000/dev6.0/', // 图片服务器地址

    shareUrl: 'http://mdiamonds.legendshop.cn/',//h5域名

    staticServer: 'https://legendshop-front-resource.oss-cn-shenzhen.aliyuncs.com/miniprogram/',//静态服务器地址

    imServer: 'ws://192.168.0.19:2397',//im地址,客服地址(暂时没有用)

    AmapKey: 'b67650d214590281b2ab8e413473553d',//高德地图秘钥

    asyncRoutes: false //true:本地路由,false:后端动态路由

 }

1.本地路由的定义如下

const ModuleGoods = [

    //所有的name、path都和文件夹的名称一样(注意一级路由的path前面需要加一个/)

    {

        path: '/ModuleGoods',

        component: Layout,  //所有需要侧边栏页面的一级路由的component都是layout

        name: 'ModuleGoods',

        meta: {

            title: '商品管理'//页面标题

            icon: 'shangpin' //侧边栏icon

        },

        children: [

            // 商品管理start

            {

                path: 'GoodsManage',

                component: () => import('@/views/ModuleGoods/GoodsManage/index'), // 在vue文件中都需要定义name属性(和文件名称一致)

                name: 'GoodsManage',

                meta: { title: '商品管理' },

                children: [

                    {

                        path: 'addGood',

                        component: () => import('@/views/ModuleGoods/GoodsManage/addGood'),

                        name: 'addGood',

                        meta: { title: '商品添加' , noCache: true},

                        hidden: true //(默认 false),当设置 true 的时候该路由不会在侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1

                    }

                ]

            }

        ]

    }

]

2.动态路由的定义

动态路由在平台管理系统(系统设置→菜单权限→平台菜单)平台菜单这个页面设置。

菜单字段

菜单说明

类型

分为菜单类型和按钮类型。菜单类型定义的是菜单路径按钮类型主要定义按钮权限

菜单名称

页面标题:设置该路由在侧边栏和面包屑中展示的名字

链接地址

对应的是path和name字段(因为name和path是一样的)

组件地址

页面对应的文件路径。注意(一级路由固定是layout,拥有三级路由以上的父级路由的固定是ParentView。意思是最后一级是文件路径,除了一级和最后一级以外,都是ParentView

例如下图:

 

权限编码

页面的权限编码

显示侧边栏

菜单类型的选项,菜单是否显示在侧边栏。

 

三、页面编写

页面类型

编写说明

表格页面

已经写好了公共样式直接拷贝现有就行了

表单提交页面

表单提交页外层需要定义一个class=‘sumbit__warp’属性,用户该页面撑满当前页面。有提交按钮需要引入<sumbitBottom>组件,作用把提交按钮一直置于底部,当表单过长时,就不需要滑动到底部了。

1.表格搜索和弹窗表单新增的混入使用

mixins/pages/commom.js(处理表格搜索)和cud.js(处理弹窗表单操作)中混入了表格请求的方法

第一 导入混入结构

import common from '@/mixins/pages/commom' //表格混入

import cud from '@/mixins/pages/cud.js' //表单混入

data() { 

        return {

            date: '',

            url: {

                getData: '/shop/admin/grass/lable/page'//获取分页列表请求路径

                delete'/shop/admin/grass/lable',//删除数据接口

                update: '/shop/admin/grass/lable',//编辑数据接口

                create: '/shop/admin/grass/lable',//新增数据接口

                getExcel: "/product/admin/count/search/page/excel" //导出数据接口

            },

            //弹窗表单校验

            dialogForm: {

                formData: {  //弹窗表单需要默认值需要定义,不需要默认值的可以不写

                    recommendFlag: 1,

                    status: 1

                },

                formRule: {//弹窗表单校验定义,

                    name: [{ required: true, message: '请输入标题', trigger: 'blur' }],

                }

            }

        }

 }

第二,搜索字段定义

<div class="search">

     <el-form :inline="true" :model="searchFilters" size="small">

             <el-form-item label="举报类型">

                 <!-- 例如后台需要的搜索参数是name,只需要 v-model="searchFilters.name"就行了  -->

                 <el-input v-model="searchFilters.name" placeholder="请输入" />

             </el-form-item>

             <el-form-item label="状态">

                 <el-select v-model="searchFilters.status" placeholder="请选择" clearable>

                     <el-option label="上线" :value="1" />

                     <el-option label="下线" :value="0" />

                 </el-select>

             </el-form-item>

             <el-form-item class="mb-20">

                 <el-button size="small" @click.stop="dbnSearch">搜索</el-button>

                 <el-button size="small" @click.stop="dbnResetSearch">重置</el-button>

             </el-form-item>

     </el-form>

</div>

第三,表格渲染

<!--表格-->   

<div class="table mt-20">

               <!-- 多选要添加 @selection-change="handleSelectionChange"  方法-->

               <!-- selectable 属性封装了禁止选择 -->

               <!-- 禁止表格多选选择框,配合data里的fillerOption属性使用 -->

               <!--例如 fillerOption: { //禁止状态 fillerOption:{status:'1,-1,-2'}} -->

                    

               <el-table

                   ref="multipleTable"

                   v-loading="tableListLoading"

                   :data="tableList"

                   :selectable="selectable"

                   tooltip-effect="dark"

                   class="w-100"

                   @selection-change="handleSelectionChange"

               >

                    

                   <!-- 如果有多选功能需要加上属性reserve-selection,能记录分页后选中的数据 -->

                   <el-table-column type="selection" width="55" reserve-selection />

                   <el-table-column prop="name" label="举报类型" align="center" />

               </el-table>

               <el-row type="flex" justify="space-between" class="mt-20">

                   <el-col>

                       <el-button size="mini" class="allCheck">

                           <!-- 全选功能封装-->

                           <el-checkbox v-model="checkAll" label="全选" size="small" @change="selAll()" />

                       </el-button>

                   </el-col>

                   <!-- //分页组件封装(直接使用) -->

                   <pagination :current-page="page.curPage" :total="tableTotal" @size-change="pageSizeChange" @current-change="currentPageChange" />

               </el-row>

</div>

第四、表单新增编辑

    <!-- 表单新增-编辑 -->

    <el-dialog :title="dialogForm.title" custom-class="dialog-form" width="420px" :visible.sync="dialogForm.isVisible">

            <el-form ref="myForm" :model="dialogForm.formData" :rules="dialogForm.formRule" label-width="95px" label-position="right" size="small">

              <!-- 只需要把后端需要的参数放进dialogForm.formData属性里就能动态修改了

               注意:prop属性不能丢,为了能保存默认值和关闭弹窗的时候清空数据,因为用的是element的form组件清除的表单 -->

                <el-form-item label="举报类型" prop="name">

                    <el-input v-model="dialogForm.formData.name" maxlength="20" show-word-limit placeholder="举报类型" />

                </el-form-item>

                <el-form-item label="状态" prop="status">

                    <el-radio-group v-model="dialogForm.formData.status">

                        <el-radio :label="1">上线</el-radio>

                        <el-radio :label="0">下线</el-radio>

                    </el-radio-group>

                </el-form-item>

            </el-form>

            <!-- //以下两个按钮都是固定的值,直接拷贝即可 -->

            <div slot="footer" class="dialog-footer">

                <el-button size="small" @click.stop="dialogForm.isVisible = false">取 消</el-button>

                <el-button size="small" type="primary" @click.stop="debounceSubmit('myForm')">确 定</el-button>

            </div>

    </el-dialog>

 

<!-- 新增编辑删除导出都是固定方法,直接拷贝就行

    新增 handleCreate()

    编辑 handleEdit(scope.row, scope.column, scope.$index)

    删除 handleDel(scope.row, scope.column, scope.$index)

    导出 getExcel()

 -->

    <el-button style="height: 32px" type="primary" size="small" @click="handleCreate">新增</el-button>

    <el-button style="height: 32px" type="primary" size="small" @click="getExcel">导出</el-button>

    <el-link :underline="false" type="primary" @click.stop="handleEdit(scope.row, scope.column, scope.$index)">

          编辑

    </el-link>

    <el-link

        :underline="false"

        type="primary"

        @click.stop="handleDel(scope.row, scope.column, scope.$index)">

        删除

    </el-link>

2.统一使用的组件

组件名称

组件作用

dialogAudit

平台所有的审核都使用这个组件,可以搜索组件名称参考使用

dialogViewLinks

平台商家端的查看链接,暂时统一用这个组件。后面需要写死一个页面中转跳转路径。所有的跳转都需要经过此页面。再由这个页面跳转到相应的页面

selectCascader

多级联动地址选择器

selectLoad

下拉选择框支持上拉加载和远程搜索

sumbitBottom

底部按钮组件,作用是始终显示在底部

四、页面编写常见问题

***原型和需求文档一定要看,但是画页面不一定要和原型一模一样,高保真才是页面的最终实现。建议着手前先和前端或产品沟通,避免重复劳动***

1、正常情况下对于输入信息的地方(输入框、选择框等)都需要做边界处理(比如限制字数),原型一般标有,没有则原型--->需求文档-→产品同事

2、页面编写记得加上头部注释(至少说明页面名称和作者)

 

3、列表页面搜索头部(输入框、选择框、日期等)一般加清除按钮clearable,特殊需求除外

 

4、组件尺寸一般使用small,建议直接改el-form 中 size="small"属性,特殊需求除外

 

5、详情中的返回、取消按钮建议用go(-1)或back()返回,因为有时跳转进的入口有可能多个

 

6、普通金额使用全局过滤(priceFilter,保留两位,向下取整)即可,如果有特殊需求,则需要考虑是否需要四舍五入

 

7、表格和表单数据展示一般不要留空

 

8、表格验证可以参考这个页面seckillGoodsTable.vue

9、对于嵌套表单,A表单嵌套B表单,点击A表单要验证B表单的内容,可以这么写