赞
踩
在管理端会遇到多分类时,要求有层次展示出来,并且每个分类有额外的操作。例如:添加分类、编辑分类、删除、拖到分类等。
下面将会记录这样的一个需求实习过程。
采用ElementUI 中的 Tree树形控件、Dropdown下拉菜单
- <el-tree :data="classifyData" node-key="id" draggable ref="tree" :accordion="false"
- auto-expand-parent :default-expanded-keys="[checkedId]" :props="defaultProps"
- :allow-drop="allowDrop" :allow-drag="allowDrag"
- @node-drag-start="handleDragStart" @node-drop="handleDrop"
- @node-click="nodeClick" @node-contextmenu="rightClick"
- :show-checkbox="false" :check-strictly="true" >
- <div class="custom-tree-node" slot-scope="{ node, data }">
- <span>{{ data.name }}</span>
- <span>
- <el-dropdown type="primary" trigger="click" :ref="'messageDrop'+data.id" @visible-change="controlCheckedKeys">
- <span class="el-dropdown-link" @click.stop="setSeletKey(data.id)">
- <img src="~@/../more-active.png" v-if="checkedKeys == data.id" class="myicon-opt" />
- <img src="~@/../more.png" v-else class="myicon-opt" />
- </span>
- <el-dropdown-menu slot="dropdown">
- <el-dropdown-item v-if="data.is_add_classify">
- <div @click="openClassify(data.id,'新增子分类')">
- <img src="~@/../add.png" class="myicon-opt"/>
- 新增子分类
- </div>
- </el-dropdown-item>
- <el-dropdown-item v-if="data.is_edit_sort">
- <div @click="editClassify(data)">
- <img src="~@/../edit.png" class="myicon-opt" />
- 修改
- </div>
- </el-dropdown-item>
- <el-dropdown-item v-if="data.is_edit_sort">
- <div @click="delBefore(data.id,data.parent_id)">
- <img src="~@/../del.png" class="myicon-opt" />
- 删除
- </div>
- </el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- </span>
- </div>
- </el-tree>
- <style lang="stylus" scoped>
- .active{
- background: #F2F6F9;
- color: #409EFF;
- }
- .classify{
- padding : 0 16px;
- height: 40px;
- font-family: PingFangSC-Medium;
- font-weight: 500;
- font-size: 15px;
- line-height:40px;
- }
-
- .el-tree ::v-deep {
- .el-tree-node__content{
- @extend .classify;
- &:hover{
- @extend .active;
- }
- .el-tree-node__expand-icon.is-leaf{
- // display:none
- margin-left:-12px
- }
- }
- .is-checked > .el-tree-node__content{
- @extend .active;
- }
- }
- .custom-tree-node{
- display: flex;
- justify-content: space-between;
- width: 100%;
- }
- .myicon-opt{
- vertical-align: middle;
- width: 16px;
- height: 16px;
- }
- </style>
- <script>
- export default {
- props:{
- activeId:{
- type:[String,Number],
- default:''
- },
- classifyData:{
- type:Array,
- default:[]
- }
- },
- watch:{
- activeId: {
- handler(v,o){
- // v 值为0时, 0 == '' 值为true
- if (typeof v == 'number') {
- this.checkedId = v
- this.$nextTick(()=>{
- this.$refs.tree.setCheckedKeys([v])
- })
- }
- },
- immediate:true,
- deep:true
- },
- },
- data() {
- return {
- checkedId:'',
- checkedKeys:'',
- defaultProps: {
- children: 'child',
- label: 'name'
- },
- classifyCofig:{
- flag:false,
- Id: '',
- title:'',
- value:''
- },
- }
- },
- methods: {
- // 点击分类名称
- nodeClick(data,node){
- this.checkedId = data.id
- this.$refs.tree.setCheckedKeys([data.id])
- node.expanded = true
- this.$emit('selectId',data.id)
- // console.log('node',data.id,node.parent)
- let addId = [ data.id]
- if(node.parent.parent != null) this.selectNode(addId,node.parent)
- // console.log('addId',addId)
- this.$emit('selectaddId', addId)
- },
- // 获取多层级的父类id加入到数组下标为0的位置
- selectNode(id,node){
- id.unshift(node.data.id)
- if(node.parent.parent != null){
- this.selectNode(id,node.parent)
- }
- },
- // 右击分类
- rightClick(event,data, Node, element){
- setTimeout(()=>{
- this.checkedKeys = data.id
- this.$refs['messageDrop'+data.id].show()
- })
- },
- // 点击操作按钮
- setSeletKey(k){
- setTimeout(()=>{
- this.checkedKeys = k
- })
- },
- // 下拉菜单的异步监听,打开(true)还是隐藏(flase)
- controlCheckedKeys(flag){
- if(!flag){
- this.checkedKeys = ''
- }
- },
- // 节点开始拖拽时触发的事件
- handleDragStart(node) {
- if(!node.data.is_edit_sort){
- return false
- }
- },
- // 拖拽成功完成时触发的事件
- handleDrop(draggingNode, dropNode, dropType) {
- if(dropType == 'none') return
- // 准备排序参数可自行更改
- let params = {
- pk1: draggingNode.data.id,
- pk2: dropNode.data.id,
- direction:dropType == 'before' ? -1 : 1
- }
- this.orderClassify(params)
- },
- /**
- * 拖拽时判定目标节点能否被放置。
- * @param {*} draggingNode
- * @param {*} dropNode
- * @param {*} type 参数有三种情况:'prev'、'inner' 和 'next',分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
- */
- allowDrop(draggingNode, dropNode, type) {
- if (draggingNode.level === dropNode.level) {
- if (draggingNode.data.parent_id === dropNode.data.parent_id && dropNode.data.is_edit_sort) {
- // 向上拖拽 || 向下拖拽
- return type === "prev" || type === "next"
- }
- } else {
- // 不同级进行处理
- return false
- }
- },
- //判断节点能否被拖拽
- allowDrag(draggingNode) {
- if(!draggingNode.data.is_edit_sort){
- return false
- }
- return true
- },
- async orderClassify(params){
- // 发送排序请求
- },
- setClassCofig(flag,id,title,value){
- this.classifyCofig['flag'] = flag
- this.classifyCofig['Id'] = id
- this.classifyCofig['title'] = title
- this.classifyCofig['value'] = value
- },
- openClassify(pid,txt){
- this.setClassCofig(true,pid, txt ? txt : '新增分类','')
- },
- editClassify(row){
- this.setClassCofig(true,row.id, '修改分类', row.name)
- },
- closeAdd(){
- this.setClassCofig(false,'', '', '')
- },
- // 新增/修改分类
- async sureClassify(params){
- let {value,Id} = this.classifyCofig
- // 通过value的值判断当前是新增还是修改
- // 刷新分类,cid 新分类的id
- let refresh = { }
- if(value){
- refresh.flag = false
- }else{
- refresh.flag = true
- }
- // 准备参数,发送请求
- // 请求成功后执行
- this.setClassCofig(false,'', '', '')
- refresh.cid = value? this.checkedId : res.data.data.id
- this.$emit('refreshClass',refresh)
- },
- //判断分类是否可以删除
- async delBefore(id,pid){
- //1.自定义判断是否可以删除,
-
- //2.可以删去执行删除操作,
- this.sureDelete(id,pid)
-
- },
- //删除分类,删除后回到上一级
- async sureDelete(id,pid){
- //1.准备删除的接口使用数据
- //2.发起请求,请求成功后执行下面代码
- this.setClassCofig(false,'', '', '')
- let refresh = {
- flag: true,
- cid: pid
- }
- this.$emit('refreshClass',refresh)
- },
- }
- };
- </script>
- <PersonalTree :activeId="currentClassfiyId" :classifyData="classifyData"
- @selectId="changeSelectId" @selectaddId="setAddId" @refreshClass="refreshClass"/>
- <script>
- // 在此处引入tree组件命名为customTree
- export default{
- components:{customTree},
- data(){
- return{
- currentClassfiyId:'',
- addClassifyId:[],
- classifyData:[],
- }
- },
- mounted(){
- this.getClassList(true)
- },
- methods:{
- async getClassList(flagScene,cid){
- // console.log(flagScene,cid)
- // 发送请求,获取全部分类
- this.classifyData = res.data.data.classify
- this.currentClassfiyId = cid || this.classifyData?.[0].id
- if(flagScene){
- // 可以去获取内容
- }
- }
- },
- refreshClass({flag,cid}){
- // 去刷新分类列表
- this.getClassList(flag,cid)
- },
- setAddId(val){
- this.addClassifyId = val
- },
- changeSelectId(id){
- this.currentClassfiyId = id
- // 可以去获取内容
- },
- }
- }
- </script>
classifyData的数据:
- [{
- "id": 1033,
- "name": "一级分类",
- "parent_id": 0,
- "level": 1,
- "child": [
- {
- "id": 1036,
- "name": "aaaaaaaaa",
- "parent_id": 1033,
- "level": 2,
- "child": [],
- "is_edit_sort": true,
- "is_add_classify": true,
- "is_add_scene": true
- },
- {
- "id": 1035,
- "name": "aaaaa",
- "parent_id": 1033,
- "level": 2,
- "child": [
- {
- "id": 1037,
- "name": "a-1",
- "parent_id": 1035,
- "level": 3,
- "child": [
- {
- "id": 1040,
- "name": "a-1-3",
- "parent_id": 1037,
- "level": 4,
- "child": [],
- "is_edit_sort": true,
- "is_add_classify": false,
- "is_add_scene": true
- },
- {
- "id": 1038,
- "name": "a-1-1",
- "parent_id": 1037,
- "level": 4,
- "child": [],
- "is_edit_sort": true,
- "is_add_classify": false,
- "is_add_scene": true
- }
- ],
- "is_edit_sort": true,
- "is_add_classify": true,
- "is_add_scene": true
- }
- ],
- "is_edit_sort": true,
- "is_add_classify": true,
- "is_add_scene": true
- }
- ],
- "is_edit_sort": true,
- "is_add_classify": true,
- "is_add_scene": true
- },{
- "id": 1032,
- "name": "测试分类b",
- "parent_id": 0,
- "level": 1,
- "child": [],
- "is_edit_sort": true,
- "is_add_classify": true,
- "is_add_scene": true
- },{
- "id": 1015,
- "name": "无操作区",
- "parent_id": 0,
- "level": 1,
- "child": [],
- "is_edit_sort": false,
- "is_add_classify": false,
- "is_add_scene": false
- }]
如有帮到您,请收藏+关注哦!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。