Vue前端画界面可能会遇到的问题
1.相同字段不同表现形式
从后台传来一个参数,这个参数有不同的值,也就是不同的状态,在前台做转换
v-if
<el-table-column align="center" >
<template slot-scope="scope">
<el-tag v-if="scope.row.status==0" type="primary" size="mini" >不启用</el-tag >
<el-tag v-if="scope.row.status==1" type="primary" size="mini" >启用</el-tag >
</template>
</el-table-column>
如果返回的是布尔类型可以这样写和?判断
//如果是true type="success" 显示内容为启用
<el-table-column align="center" label="是否启用" prop="enabled">
<template slot-scope="scope">
<el-tag :type="scope.row.enabled ? 'success' : 'error' ">{{ scope.row.enabled ? '启用' : '不启用' }}</el-tag>
</template>
</el-table-column>
//如果返回的不是布尔类型也可以这样写,效果应该也是一样的
<el-table-column align="center" label="是否启用" prop="enabled">
<template slot-scope="scope">
<el-tag :type="scope.row.enabled=='1' ? 'success' : 'error' ">{{ scope.row.enabled=='1' ? '启用' : '不启用' }}</el-tag>
</template>
</el-table-column>
关于行政区域的树形结构
在行政区域中,我们在上数据的时候会有个树形结构,如省份->市->区等
官方描述
<el-table>支持树类型的数据的显示。当 row 中包含 children 字段时,被视为树形数据。渲染树形数据时,
必须要指定 row-key。支持子节点数据异步加载。设置 Table 的 lazy 属性为 true 与加载函数 load 。
通过指定 row 中的 hasChildren 字段来指定哪些行是包含子节点。children 与 hasChildren 都
可以通过 tree-props 配置。
说白了就是将子列表的内容都放在children字段中,也就是说省份含有children这个字段,
这个字段放的是这个省拥有的市,这个市也有个children字段,这个字段放的是这个是拥有的哪些区等.注意这个row-key,别写错了
最后由这个<el-table>组件自己来解析
如果还不理解,去看下官方文档吧
https://element.eleme.cn/#/zh-CN/component/table
如果存在3种不同状态的话,可以这样搞
如:省,市,区->1,2,3
使用过滤器
export default {
name: 'Region',
filters: {
// 过滤器将status过滤为省,市,区
typeFilter(status) {
const typeMap = {
'1': '省',
'2': '市',
'3': '区'
}
return typeMap[status]
}
},
data() {
return {
}
},
mounted() {
},
methods: {
}
}
然后在组件中使用
<el-table-column label="区域类型" prop="type">
<template slot-scope="scope">
{{ scope.row.type | typeFilter }}
</template>
</el-table-column>
上传文件组件,如上传图片
<el-form-item label="品牌商图片" prop="picUrl">
<el-upload
:headers="headers"
:action="uploadPath"
:show-file-list="false"
:on-success="uploadPicUrl"
class="avatar-uploader"
accept=".jpg,.jpeg,.png,.gif">
<img v-if="dataForm.picUrl" :src="dataForm.picUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"/>
</el-upload>
</el-form-item>
<style>
.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>
:action="uploadPath" 存放的是后台上传文件的接口
如果没有在data中定义的话,就要这么写
action="https://jsonplaceholder.typicode.com/posts/"
:show-file-list="false" 这个是是否显示上传文件的列表,false就是不显示
:on-success="uploadPicUrl" 这个是上传成功后的钩子,如果上传成功了,就会调用uploadPicUrl这个方法。
accept=".jpg,.jpeg,.png,.gif" 这个是上传文件的格式,只能这些文件的格式
:before-upload="onBeforeUpload" 这个是上传文件之前,上传文件后先调用这个onBeforeUpload方法
:data="data" 如果你需要传其他参数,就把需要传的参数,值包含在data里面
因为后台安全框架的原因,需要一个登录成功时的headers,后台返回的token
computed: {
// 上传请求头
headers() {
return {
'Shopping-Admin-Token': getToken()
}
}
},
有些同学不知道生成的图片路径怎么插入数据库,我这里提点一下
1.使用上传成功后的钩子,这个钩子可以携带一些数据如:
uploadPicUrl(response, file, fileList){
//这个response里面包含了你使用上传文件接口后返回的所有数据,假如我把图片路径放在了
//url里面。我自己定义了一个form,form里面有imgurl属性
this.dataForm.imgurl=response.url
//这样你的dataForm.imgurl存的就是你上传文件后返回的图片路径
}
//最后点击确定时调用插入的后台接口,将数据传到后台
展开行
如商品管理的商品列表
这有官方的例子
官方描述
通过设置 type="expand" 和 Scoped slot 可以开启展开行功能,el-table-column 的模板会被渲染
成为展开行的内容,展开行可访问的属性与使用自定义列模板时的 Scoped slot 相同。
我这里就不沾代码了,直接区官方看吧,都是在table组件里面
https://element.eleme.cn/#/zh-CN/component/table
//存在难点
宣传画廊:一个for循环搞定
<el-form-item label="宣传画廊">
<img
v-for="pic in props.row.gallery"
:key="pic"
:src="pic"
class="gallery" >
</el-form-item>
查看详情
//模态框我就不说了
<el-dialog
:visible.sync="detailDialogVisible"
width="60%"
title="商品详情">
<div v-html="goodsDetail" />
</el-dialog>
//goodsDetail放的是详情数据,也就是那一堆img标签的图片
更新商品时的宣传画廊
其实这也是上传文件,不过它先加载了已有的图片
具体代码
<el-form-item label="宣传画廊">
<el-upload
:action="uploadPath"
:headers="headers"
:limit="5"
:file-list="galleryFileList"
:on-exceed="uploadOverrun"
:on-success="handleGalleryUrl"
:on-remove="handleRemove"
multiple
accept=".jpg,.jpeg,.png,.gif"
list-type="picture-card">
<i class="el-icon-plus"/>
</el-upload>
</el-form-item>
//里面的很多东西前面已经讲过
//galleryFileList存放的就是数据库已有的图片,相当于已上传的文件
//:on-exceed绑定的方法则是处理超出数量后的动作
data() {
return {
galleryFileList: [], // 多文件上传列表
}
},
created() {
// 页面数据初始化
this.init()
},
methods:{
init: function(){
const goodsId = this.$route.query.id
detailGoods(goodsId).then(response => {
this.goods = response.data.data.goods
this.specifications = response.data.data.specifications
this.products = response.data.data.products
this.attributes = response.data.data.attributes
this.categoryIds = response.data.data.categoryIds
//这里放以上传文件的
this.galleryFileList = []
for (var i = 0; i < this.goods.gallery.length; i++) {
this.galleryFileList.push({
url: this.goods.gallery[i]
})
}
const keywords = response.data.data.goods.keywords
if (keywords !== null) {
this.keywords = keywords.split(',')
}
})
}
}
动态编辑标签tag
在项目中的应用
其实这个也是tag组件的应用,这是个官方例子,
https://element.eleme.cn/#/zh-CN/component/tag#dong-tai-bian-ji-biao-qian
官方效果图和代码
<el-tag
:key="tag"
v-for="tag in dynamicTags"
closable
:disable-transitions="false"
@close="handleClose(tag)">
{{tag}}
</el-tag>
<el-input
class="input-new-tag"
v-if="inputVisible"
v-model="inputValue"
ref="saveTagInput"
size="small"
@keyup.enter.native="handleInputConfirm"
@blur="handleInputConfirm"
>
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Tag</el-button>
<style>
.el-tag + .el-tag {
margin-left: 10px;
}
.button-new-tag {
margin-left: 10px;
height: 32px;
line-height: 30px;
padding-top: 0;
padding-bottom: 0;
}
.input-new-tag {
width: 90px;
margin-left: 10px;
vertical-align: bottom;
}
</style>
<script>
export default {
data() {
return {
dynamicTags: ['标签一', '标签二', '标签三'],
inputVisible: false,
inputValue: ''
};
},
methods: {
handleClose(tag) {
this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);
},
showInput() {
this.inputVisible = true;
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus();
});
},
handleInputConfirm() {
let inputValue = this.inputValue;
if (inputValue) {
this.dynamicTags.push(inputValue);
}
this.inputVisible = false;
this.inputValue = '';
}
}
}
</script>
Cascader 级联选择器
项目效果图
官方效果图
官方代码:自己看吧,太多了
https://element.eleme.cn/#/zh-CN/component/cascader
//官方描述
只需为 Cascader 的options属性指定选项数组即可渲染出一个级联选择器。通过
props.expandTrigger可以定义展开子级菜单的触发方式。
关键代码1
1.获取数据
首先需要的是从后台获取数据,需要注意的是,如果是多级选择,他的子列表字段名一定要叫children
和table的树形结构类似
如:
关键代码2
<el-form-item label="所属分类">
<el-cascader :options="categoryList" v-model="categoryIds" expand-trigger="hover" @change="handleCategoryChange"/>
</el-form-item>
//别忘了在data里面定义categoryList
关键代码3
// 所属分类下拉钩子,这个goods是你要提交的表单
handleCategoryChange(value) {
this.goods.categoryId = value[value.length - 1]
},
富文本
我们在项目种应用的是tinymce-vue,这种富文本
在shopping项目中tinymce-vue已经安装,所以我们只需要引用就行
import Editor from '@tinymce/tinymce-vue'
export default {
//注册Editor
components:{Editor},
富文本初始化
data() {
return {
// 富文本编辑器初始化
editorInit: {
language: 'zh_CN',
convert_urls: false,
plugins: [
'advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount'
],
toolbar: [
'searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample',
'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen'
],
// 上传钩子
images_upload_handler: function(blobInfo, success, failure) {
const formData = new FormData()
formData.append('file', blobInfo.blob())
createStorage(formData)
.then(res => {
success(res.data.data.url)
})
.catch(() => {
failure('上传失败,请重新上传')
})
}
}
}
},
在组件中引用
<el-form-item label="商品详细介绍">
<editor :init="editorInit" v-model="goods.detail"/>
</el-form-item>
还不清楚的群里有个商城管理项目-前端注意事项这个文件可以看一下
form表单的快速赋值
this.dataForm = Object.assign({},row)
//dataForm一定要和row里面的值对应