Vue-admin 模板项目
杂牌技巧
配置页面不需要登录
permission.js 里面的:
const whiteList = [‘/login’] // 不重定向白名单
配置页面不需要菜单和顶部
配在route里面的顶部即可。
路由跳转写法:
this. r o u t e r . p u s h ( n a m e : " p a t i e n t I n f o " , q u e r y : w a r d : w a r d I d ) ; t h i s . router.push({ name: "patientInfo", query: { ward: wardId} }); this. router.push(name:"patientInfo",query:ward:wardId);this.router.push({ path: ‘/userCity’, query: { cityName: this.cityName }})
获取方式:
提示:{{this.$route.params.alert}}
提示:{{this.$route.query.alert}}
参考:[https://www.cnblogs.com/toonezhr/p/10325457.html](https://www.cnblogs.com/toonezhr/p/10325457.html)几秒后执行的写法:
setTimeout(function() {
that.activeName = ‘first’
}, 500)
参考:链接
网页https访问注意:
编译的时候,prod.env.js 文件按如下设置,访问的时候直接用https的地址访问
module.exports = {
NODE_ENV: '"production"',
TIME_OUT: '"60000"',
BASE_API: '"https://zhanshen888.mynatapp.cc/"',
}
post请求里面参数不合法
试试params修改为data
insert(data) {
return request({
url: '/lwPortalConfig/insert',
method: 'post',
data
})
},
常规开发
Step1、创建表结构
通常,在后端项目下的pdm文件夹里面打开pdm文件,编辑好表信息。
拷贝建表语法到指定数据库,执行。
Step2、生成代码
使用的是自定义的代码生成器,可以生成配套的后端和前端代码。
进入该目录,打开cmd,输入rapid-gen.bat
执行 gen + 表名,生成具体代码
Step3、后端代码开发
后端主要是web + service + mapper + entity + mapper.xml,五个文件。
正常目录没有特殊要求的话,导入进来接口就能用了。
通常要改的是分页语法:
<select id="findListPage" resultType="lyOrgDict">
select
t.*
from
ly_org_dict t
where 1=1
<if test="query != null and query != ''">
AND (INSTR(t.ORG_NAME , #{query})>0 OR INSTR(t.ORG_ID , #{query})>0)
</if>
<if test="model.validFlag != null and model.validFlag != ''">
and t.VALID_FLAG = #{model.validFlag}
</if>
</select>
然后是关联查询:
select
t.*,
(SELECT o.NICK_NAME FROM lw_user_info o WHERE o.USER_ID = T.USER_ID) nickName,
(SELECT o.ORG_NAME FROM ly_org_dict o WHERE o.ORG_ID = T.ORDER_ORG) orgName,
(SELECT o.PRO_PRICE FROM ly_product_dict o WHERE o.PRO_ID = T.PRO_ID) proPrice,
(SELECT o.OBJ_NAME FROM ly_server_object o WHERE o.OBJ_ID = T.OBJ_ID) objName
from
ly_order_record t
where 1=1
Step4、前端代码开发
4.1、前置检查
先确认一下vue文件里面的api目录是否正常,配置一下路由指向这个vue文件。
然后,可以运行起来程序,确认一下页面访问是否正常。
打开页面代码,先格式化一下!
4.2、处理表格列
代码生成器生成的,所有字段都会作为列,这里去掉不要的。
同时可以往数据库插入一条合理的数据,看是否要调整宽度。
如果是图片类型的话,写法要变化一下。
<img v-if="scope.row.itemImg" :src="fileBefore + scope.row.itemImg" style="width: 50px;height: 50px;">
如果某列是一个字典,需要翻译,则按如下处理:
<el-tag :type="scope.row.itemType | statusFilter" slot-scope="scope">
{{ scope.row.itemType | commonFilter(orderStatusObj) }}
</el-tag>
orderStatusObj: { //状态类型
'1': '荣誉资质',
'2': '设备展示',
'3': '合作客户',
},
4.3、处理搜索条件
默认搜索条件是query模糊搜索和validFlag下拉搜索。
query搜索需要改一下后端的page语法,看具体根据什么字段模糊搜索。
后端语法里面是否根据排序号和时间排序按需调整。
范例参考如下:
<select id="findListPage" resultType="oaInfoConfig">
select
t.*
from
oa_info_config t
where 1=1
<if test="query != null and query != ''">
AND INSTR(t.ITEM_NAME , #{query})>0
</if>
<if test="model.validFlag != null and model.validFlag != ''">
and t.VALID_FLAG = #{model.validFlag}
</if>
<if test="model.itemType != null and model.itemType != ''">
and t.ITEM_TYPE = #{model.itemType}
</if>
order by t.SORT_NO
</select>
如果要根据某个字典进行过滤,代码接4.1继续:
<el-select v-model="listQuery.itemType" placeholder="产品类型" clearable class="filter-item"
style="width: 150px"
@change="handleFilter">
<el-option v-for="(value, key) in orderStatusObj" :key="key" :label="value" :value="key"/>
</el-select>
4.4、处理表单信息
部分参考代码如下:
<el-row :gutter="20" v-if="dialogStatus === 'update'">
<el-col :span="12">
<el-form-item label="项目ID" label-width="105px" prop="itemId">
<el-input v-model="temp.itemId" :disabled="dialogStatus === 'update'"/>
</el-form-item>
</el-col>
</el-row><el-row :gutter="20">
<el-col :span="12">
<el-form-item label="项目名称" label-width="105px" prop="itemName">
<el-input v-model="temp.itemName"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目类型" label-width="105px" prop="itemType">
<el-select v-model="temp.itemType" clearable class="filter-item" style="width: 150px">
<el-option v-for="(value, key) in orderStatusObj" :key="key" :label="value+'('+key+')'" :value="key"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
去掉一些不需要校验的rules
排序号规则要调整一下,输入框也要加上number:
<el-form-item label="排序号" label-width="105px" prop="sortNo">
<el-input v-model.number="temp.sortNo" auto-complete="off"/>
</el-form-item>
sortNo: [
{
type: 'number', required: false, message: '排序号必须为整数值', transform(value) {
if (value === '' || value === null) {
return 0
}
if (_.isInteger(value)) {
return value
} else {
return false
}
}
}
]
4.5、字典如果是列表的情况
注意,字典来源可能不是写死的,而是另外一张表,那就是需要先获取列表数据,赋值给一个数组属性,其涉及的全套代码具体如下:
<el-select v-model="listQuery.orgCode" placeholder="所属商家" :disabled="isOrg" clearable class="filter-item"
style="width: 150px" @change="handleFilter">
<el-option v-for="{orgCode, orgName} in orgs" :key="orgCode" :label="orgName"
:value="orgCode"/>
</el-select>
<el-table-column label="所属商家" align="center" style="width: 10%">
<template slot-scope="scope">
<span>{{ scope.row.orgCode | orgFilter(orgs) }}</span>
</template>
</el-table-column>
<el-col :span="12">
<el-form-item label="所属商家" label-width="105px" prop="orgCode">
<el-select v-model="temp.orgCode" clearable class="filter-item" style="width: 150px" :disabled="isOrg" >
<el-option v-for="{orgCode, orgName} in orgs" :key="orgCode" :label="orgName"
:value="orgCode"/>
</el-select>
</el-form-item>
</el-col>
this.$http.all([SyCategoriesApi.getPage(this.listQuery), SyOrgDictApi.getList({validFlag: '1'})])
.then(this.$http.spread(function (perms, two) {
if(that.orgCode){
that.orgs = two.filter(item => item.orgCode === that.orgCode)
}else{
that.orgs = two
}
that.list = perms.rows
that.total = perms.total
that.listLoading = false
}));
4.6、文件上传处理
文件有两种方案,一种是数据库存绝对路径,一种是存相对路径,具体代码如下。
存相对路径的好处是,如果后期修改域名,数据库的图片地址不需要全部修改。
当然,有条件的还是使用OSS去存储。
//方案一:存绝对路径
uploadUrl: process.env.BASE_API + 'uploadOneImg',
//方案二:存相对路径
uploadUrl: process.env.BASE_API + 'uploadOneImg?handleFlag=only',
fileBefore: process.env.BASE_API + 'oa/',
涉及文件上传的,CSS样式要加上:
<style scoped>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
表单部分的代码如下:
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="展示图片" label-width="120px" prop="itemImg">
<el-upload
with-credentials
enctype="multipart/form-data"
:show-file-list="false"
:on-error="uploadError"
:on-success="uploadSuccess"
:before-upload="beforeUpload"
:action="uploadUrl"
class="avatar-uploader">
<img v-if="temp.itemImg" :src="fileBefore + temp.itemImg" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"/>
</el-upload>
</el-form-item>
</el-col>
</el-row>
/**
* 上传成功处理
*/
uploadSuccess(res, file) {
this.temp.itemImg = res
this.$notify({
title: '成功',
message: '图片上传成功',
type: 'success',
duration: 1000
})
},
/**
* 上传错误处理
*/
uploadError() {
this.$message.error('上传失败,请重新上传')
},
/**
* 上传前置处理
*/
beforeUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 2
if (!isLt2M) {
this.$message.error('上传图片大小不能超过 2MB!')
}
},
4.7、详情富文本编辑
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="医院详情" label-width="105px" prop="orgContent">
<tinymce :custom-modal="editModal" :upload-url="uploadUrl" :height="300" v-model="temp.orgContent"
:reset="!dialogFormVisible"/>
</el-form-item>
</el-col>
</el-row>
import Tinymce from '@/components/Tinymce'
export default {
directives: {waves},
components: {Pagination, Tinymce},
<import src="../../../wxParse/wxParse.wxml"></import>
<block wx:if="{{productInfo.productDesc}}">
<view class='good-desc'>
<template is="wxParse" data="{{wxParseData:goodDesc.nodes}}"></template>
</view>
</block>
//商品详情
if (data.productDesc) {
WxParse.wxParse("goodDesc", "html", data.productDesc, that, 20);
}
问题记录
发布线上图标不显示
修改一下webpack.base.conf.js的limit
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 100000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}