目录
9.3,现在只允许选中最后一级分类,如果想允许选中任何一级分类,需要添加属性
1,渲染排序和操作列
1.从API里查看排序的数据属性是cat_level
值为0是一级分类,值为1是二级分类,2是三级分类
在代码里找到columns数组,里面是列的对象,复制出一个新的模版列
columns: [
{
label: '分类名称',
prop: 'cat_name',
},
{
label: '是否有效',
//表示将当前定义为模版列
type: 'template',
//表示当前这一列使用模版名称
template: 'isok'
},
//复制为一个操作列
{
label: '排序',
//表示将当前定义为模版列
type: 'template',
//表示当前这一列使用模版名称,自定义名称,在表格结构中进行定义
template: 'order'
}
<!-- 操作 slot为columns中自定义的模版名称一致,
slot-scope="scope"使用scope接受作用域插槽中的数据
渲染出不同等级的标签-->
<template slot="order" slot-scope="scope">
<el-tag size="mini">一级</el-tag>
<el-tag size="mini" type="success">二级</el-tag>
<el-tag size="mini" type="warning">三级</el-tag>
</template>
2,进行按需渲染
目前是同时显示了三个标签,
需要进行按需渲染,一级分类只显示一级标签,使用v-if,v-else-if,v-else进行按需渲染
当等于0时只展示一级标签,为1时展示二级标签,为2时展示三级标签
<!-- 操作 slot为columns中自定义的模版名称一致,
slot-scope="scope"使用scope接受作用域插槽中的数据
渲染出不同等级的标签-->
<template slot="order" slot-scope="scope">
<el-tag size="mini" v-if="scope.row.cat_level===0">一级</el-tag>
<el-tag size="mini" type="success" v-else-if="scope.row.cat_level===1">二级</el-tag>
<el-tag size="mini" type="warning" v-else>三级</el-tag>
</template>
3.渲染操作列
//复制为一个操作列
{
label: '操作',
//表示将当前定义为模版列
type: 'template',
//表示当前这一列使用模版名称,自定义名称,在表格结构中进行定义
template: 'opt'
}
然后渲染操作列的两个按钮
<!-- 操作 -->
<template slot="opt" slot-scope="scope">
<!-- size="mini" 可以让按钮变的最小,danger是红色 -->
<el-button size="mini" type="primary" icon="el-icon-edit">编辑</el-button>
<el-button size="mini" type="danger" icon="el-icon-delete">删除</el-button>
</template>
4,渲染页面的分页
从element粘贴分页
//监听pagesize改变
handleSizeChange(newSize){
this.querInfo.pagesize =newSize
this.getCateList()
},
//监听pagenum改变
handleCurrentChange(newPage){
this.querInfo.pagenum =newPage
this.getCateList()
}
<!-- 分页区
size-change事件绑定一个事件处理函数,handleSizeChange监听pagesize改变-->
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="querInfo.pagenum" :page-sizes="[3, 5, 10, 15]" :page-size="querInfo.pagesize"
layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
5,表格和按钮的距离太近
给表格增加一个类名,设计样式
.treeTable{
margin-top: 15px;
}
<tree-table class="treeTable" :data="cateList" :columns="columns" :selection-type="false" :expand-type="false" show-index
6.添加点击分类按钮事件
会有一个级联选择框,后期会进行介绍
先添加一个对话框
<!-- 添加分类的对话框 -->
<el-dialog title="添加分类" :visible.sync="addCateDialogVisible" width="50%">
<span>这是一段信息</span>
<span slot="footer" class="dialog-footer">
<el-button @click="addCateDialogVisible= false">取 消</el-button>
<el-button type="primary" @click="addCateDialogVisible">确 定</el-button>
</span>
</el-dialog>
让对话框在页面中显示出来,添加一个点击事件
<el-button type="primary" @click="showAddCateDialog">添加分类</el-button>
一定不要忘记在data里return中定义
//控制添加分类对话框的显示和隐藏
addCateDialogVisible :false
在methods新增一个
//展示添加分类的对话框
showAddCateDialog(){
this.addCateDialogVisible =true
}
渲染对话框,在element中搜索表单,将表单添加到对话框里
7.带有校验规则的表单
<!-- 添加分类的表单 -->
<el-form :model="addCateForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="活动名称" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
</el-form>
在data,return中写
//添加分类的表单数据对象
addCateForm:{}
梳理修改表单对应的名称
<!-- 添加分类的表单 -->
<el-form :model="addCateForm" :rules="addCateFormRules" ref="addCateFormRef" label-width="100px" class="demo-ruleForm">
<el-form-item label="分类名称" prop="cat_name">
<el-input v-model="addCateForm.cat_name"></el-input>
</el-form-item>
</el-form>
可以从api中查看输入框应该获取到的属性名称为cat_name,双向绑定事件也应该保存到addCateForm.cat_name中
因为是必填项,需要使用带有验证规则的表单,并在data里的return中编写验证规则,如果不填就会提示。
//添加分类的表单数据对象
addCateForm: {
//将要添加的分类名称
cat_name: '',
//父级分类的id
cat_pid:0,
//当前默认添加的分类等级,默认要添加的是一级分类
cat_level:0
},
//添加分类表单的验证规则对象
addCateFormRules:{
cat_name:[
{required: true, message:'请输入分类名称', trigger: 'blur'}
]
}
渲染表单中的父级分类,这个不是必填项,所以没有验证规则,所以没有prop,默认是一级分类。
什么都不选就是一级分类,
设置一个新的 item项
<!-- 父级分类 -->
<el-form-item label="父级分类">
</el-form-item>
关于级联的选择框之后再学
梳理整个代码
<!-- 添加分类的对话框 -->
<el-dialog title="添加分类" :visible.sync="addCateDialogVisible" width="50%">
<!-- 添加分类的表单 -->
<el-form :model="addCateForm" :rules="addCateFormRules" ref="addCateFormRef" label-width="100px"
class="demo-ruleForm">
<el-form-item label="分类名称" prop="cat_name">
<el-input v-model="addCateForm.cat_name"></el-input>
</el-form-item>
<!-- 父级分类 -->
<el-form-item label="父级分类">
</el-form-item>
</el-form>
<!-- 对话框底部区域 -->
<span slot="footer" class="dialog-footer">
<el-button @click="addCateDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="addCateDialogVisible = false">确 定</el-button>
</span>
</el-dialog>
8,获取父级列表信息
点击添加按钮,获取到父级分类加载出来,只需要加载前两级的,因为最多只有三级分类,添加只需要选择两级
找到对应的api,
然后添加对应的methods
//获取父级分类的数据列表
async getParentCateList(){
const {data:res} = await this.$http.get('categories',{params:{type:2}})
if(res.meta.status !==200){
return this.$message.error('获取父级分类数据失败')
}
console.log(res.data)
}
写好的函数在点击按钮弹出对话框之前去调用
//展示添加分类的对话框
showAddCateDialog() {
//先获取父级分类的数据列表
this.getParentCateList()
//再展示对话框
this.addCateDialogVisible = true
},
可以看到获取到的数据
把数据保存到data中去使用
先定义一个私有数据
//父级分类的列表
parentCateList:[]
然后在函数里赋值,保存到 parentCateList:[]
this.parentCateList=res.data
9.级联选择器
element提供了两种,一种是点击展开,一种是覆盖展开
<!-- 父级分类 -->
<el-form-item label="父级分类:">
<!-- 父级分类中的级联选择框 -->
<!-- options="parentCateList" 用来指定数据源的 -->
<!-- props用来指定配置对象 在配置对象中用value指定所选中的值,用label指定看到的值,children指定父子之间的嵌套-->
<!-- v-model="value" 将选中的值双向绑定到data中,必须绑定一个数组,不能是一个值或者一个对象,因为级联选择器可以选择多项,应该把id都保存起来,保存到一个数组中,在data中设定一个数组-->
<!-- 只要级联选择器进行触发,就会触发change -->
<el-cascader expand-trigger="hover" v-model="selectedKeys" :options="parentCateList"
:props="cascaderProps" @change="parentCateChanged">
</el-cascader>
</el-form-item>
在data中设计
//父级分类的列表
parentCateList: [],
//指定级联选择器的配置对象
// value:'',真实赋给的参数
// label:'',表面上显示的参数
// children:''父子之间参数的传递
cascaderProps: {
value: 'cat_id',
label: 'cat_name',
children: 'children'
},
//选中的父级类别的id数组,因为可选两级
selectedKeys: []
在methods中写方法
//选择项发生变化触发这个函数,
parentCateChanged() {
console.log(this.selectedKeys)
}
形成的页面
进行优化
9.1、发现选择框没有和上面的长度一致
通过类名选择器进行设定样式
.el-cascader{
width: 100%;
}
9.2、选择清空属性
clearable
9.3,现在只允许选中最后一级分类,如果想允许选中任何一级分类,需要添加属性
change-on-select
10,处理添加分类的表单数据
如果添加分类的名称为a,如果没有选任何父级分类,父分类id默认为0,
应该监听选择器的变化,只要发生了变化,就应该更新绑定的父分类的id和level
在@change="parentCateChanged">进行监听,发生变化后,这个数组v-model="selectedKeys"也会发生变化
如果selectedKeys数组里面的长度大于0了,就代表选中了一个父级分类
先做一个判断,把选中的最后一级分类的值赋值即可
//选择项发生变化触发这个函数,
parentCateChanged() {
console.log(this.selectedKeys)
// 如果selectedKeys数组里面的长度大于0了,就代表选中了一个父级分类
//应选择最后一项作为父级分类的id,如果选中了大家电和电视,大家电的id是1,电视的id是3,那么该项的父分类id应该是3
//那么最后一项应该怎么去找呢: this.selectedKeys.length -1为最后一项的索引,通过中括号取值
if (this.selectedKeys.length>0){
//父级分类的id
this.addCateForm.cat_pid=this.selectedKeys[
this.selectedKeys.length -1
]
}
}
父级分类发生变化后,对应的level值应该也发生变化
选中一项,level值应该变为1,两项level值应该为2
发现始终和数组里面的长度保持一致,如何没选中任何值,应该重置清零
//选择项发生变化触发这个函数,
parentCateChanged() {
console.log(this.selectedKeys)
// 如果selectedKeys数组里面的长度大于0了,就代表选中了一个父级分类
//应选择最后一项作为父级分类的id,如果选中了大家电和电视,大家电的id是1,电视的id是3,那么该项的父分类id应该是3
//那么最后一项应该怎么去找呢: this.selectedKeys.length -1为最后一项的索引,通过中括号取值
if (this.selectedKeys.length>0){
//父级分类的id
this.addCateForm.cat_pid=this.selectedKeys[
this.selectedKeys.length -1
]
//为当前分类的等级赋值
this.addCateForm.cat_level=this.selectedKeys.length
return
}
//如果没有走上面的if,说明没有选中任何父级分类,重置这两项为0
this.addCateForm.cat_pid=0
this.addCateForm.cat_level=0
}
为确定按钮添加一个打印表单的函数
//点击添加分类对话框的确定按钮,添加新的分类
addCate() {
console.log(this.addCateForm)
}
可以看到选中之后,点击确定,可以正常获得属性
每次对话框都会遇到关闭之后再打开没有清空的问题,还保存上次的数据
11.让对话框清空
监听close事件处理函数
//监听对话框的关闭事件,重置表单数据
addCateDialogClosed(){
this.$refs.addCateFormRef.resetFields()
}
但现在只能清空分类名称,对父级分类没有清空,需要清空级联选择框的数组和id还有level
//监听对话框的关闭事件,重置表单数据
addCateDialogClosed(){
this.$refs.addCateFormRef.resetFields()
this.selectedKeys=[]
this.addCateForm.cat_pid = 0
this.addCateForm.cat_level = 0
}
这个才是完整的重置操作
12,在点击确定按钮之后,要对表单进行预验证
当预验证通过之后,调用对应的API接口,发起请求
在调接口的时候,查看添加分类的API
在代码里,找到点击确定触发的函数
进行预验证,拿到表单的引用,使用validate方法,指定一个回调函数,用valid对校验结果进行接受
//点击添加分类对话框的确定按钮,添加新的分类
addCate() {
// console.log(this.addCateForm)
this.$refs.addCateFormRef.validate(async valid =>{
if(!valid)return
const{data:res} = await this.$http.post('categories',this.addCateForm)
if(res.meta.status !==201){
return this.$message.error('添加分类失败')
}
this.$message.success('添加分类成功')
this.getCateList()
this.addCateDialogVisible = false
})
},
13,编辑和删除操作是类似的
删除:
先给删除按钮添加一个单击事件
@click="removeTreeById(scope.row.cat_id)"
使用作用域插槽获取到信息
然后进行删除
//根据id删除用户信息
async removeTreeById(id) {
//弹窗询问用户是否删除数据
const confirmResult = await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).catch(err => err)
//此时用户点确定返回的是一个confirm字符串,如果点取消是返回一个错误,如果解决,加一个catch
//修改好错误之后,用户点击取消删除之后返回的是一个字符串cancel
// console.log(confirmResult)
if (confirmResult !== 'confirm') {
return this.$message.info('已取消删除')
}
// console.log('确认了删除')
const { data: res } = await this.$http.delete('categories/' + id)
if (res.meta.status !== 200) {
return this.$message.error('删除用户失败')
}
this.$message.success('删除用户成功')
this.getCateList()
},
14。编辑分类名称步骤
1, 给编辑按钮添加一个单击打开对话框获取到分类名称的事件,因为要获取分类名称,所以要传递参数,使用作用域插槽,但这里不能只传一个分类名称,还需要通过分类id,所以把全部的信息传递过去,在私有数据中定义一个数组进行存放。 @click="showeditCateDialog(scope.row)">编辑</el-button>
editCate: {},
editCateId: ''
2,梳理对话框
不需要设置一个重置的关闭事件了,以为只有一个分类名称
<el-dialog title="修改分类" :visible.sync="editDialogVisible" width="50%">
<el-form :model="editCate" ref="editCateRef" :rules="editCateRules" label-width="100px">
<el-form-item label="分类名称:" prop="cat_name">
<el-input v-model="editCate.cat_name"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="editCateInfo">确 定</el-button>
</span>
</el-dialog>
3.在data中添加一个编辑规则,重命名的内容不能为空
editCateRules: {
cat_name: [{ required: true, message: '请输入要修改的信息', trigger: 'blur' }]
},
4.data中的数据
// 编辑对话框的显示和隐藏
editDialogVisible: false,
// editCateDialogVisbel: false,
editCate: {},
//添加规则
editCateRules: {
cat_name: [{ required: true, message: '请输入要修改的信息', trigger: 'blur' }]
},
editCateId: ''
}
5。编写获取分类名称并展示对话框
// 获取到分类名称,展示到编辑分类对话框里
async showeditCateDialog(cateInfo) {
this.editCateId = cateInfo.cat_id
const { data: res } = await this.$http.get('categories/' + cateInfo.cat_id)
//因为请求不一定永远都是成功的,所以要进行判断
if (res.meta.status !== 200) {
return this.$message.error('查询分类信息失败!')
}
//将查询到的分类信息保存到私有表单数据对象上
this.editCate = res.data
console.log(this.editCate)
//点击编辑按钮,展开显示对话框
this.editDialogVisible = true
},
6.对用户修改后的表单进行预校验,对应上面的确认按钮事件,需要把修改同步到后端,提交put请求。注意这里的参数传递
要求分类名称的参数放在请求体中,如何把参数放在请求体里。
最后从码云上粘贴了代码
const { data: res } = await this.$http.put('categories/' + this.editCate.cat_id, { cat_name: this.editCate.cat_name })
直接逗号后加一个花括号,写上接收的参数名加冒号, { cat_name: this.editCate.cat_name })
// 修改分类名称并提交,对表单进行预验证,valid是一个布尔值
editCateInfo() {
this.$refs.editCateRef.validate
(async valid => {
if (!valid) return
//当预验证通过后,就发起修改表单提交请求,编辑用户提交API将数据自动同步到editform
const { data: res } = await this.$http.put('categories/' + this.editCate.cat_id, { cat_name: this.editCate.cat_name }
)
if (res.meta.status !== 200) {
return this.$message.error('更新分类信息失败')
}
//关闭对话框
this.editDialogVisible = false
//刷新数据列表
this.getCateList()
//提示修改成功
this.$message.success('更新分类信息成功')
})
},
15,上传文件
git branch
git status
git add .
git status
git commit -m "完成了分类功能的开发”
git status
git push
git branch
git checkout master
git merge goods_cate
git push