m0_62833091 2025-08-08 10:42 采纳率: 88.4%
浏览 9
已结题

三级菜单选项,第二级高亮如何实现?

img


如图所未:一级菜单(生产制造)下的二级菜单(普工)下的三级菜(普工/操作工,包装工等),如果有点击选中(普工),不管三级菜单(普工/操作工第选项)有没有选中,都为高亮。如果点击选中(普工)下的三级菜单选中了(普工/操作工),那么二级菜单(普工)就为高亮,切换点击二级菜单(机械加工)后,(普工)选项依然为高亮,除非取消了(普工/操作工)的选中,二级菜单切换为(机械加工)后,取消(普工)的高亮,这个效果如何实现?

<!--pages/relase/certificate/certificate.wxml-->
<view class="content">
    <view class="select-group">
        <view class="position-title">{{positionselect}}</view>
        <view class="position-number">
            <view class="count">6/</view>
            <view class="total">20</view>
        </view>
    </view>
    <view class="container">
        <!-- 证书类型 -->
        <scroll-view class="first-column" scroll-y scroll-with-animation>
            <view wx:for="{{grades}}" wx:key="id" class="first-item {{currentGrade.id === item.id ? 'greenColor':''}}" bindtap="selectGrade" data-item="{{item}}">
                <view class="first-float-carvit {{currentGrade.id === item.id ? 'greenBg':''}}"></view>
                <view class="first-float-title">{{item.name}}</view>
                <view class="first-float-count" wx:if="{{selectedCountMap[item.id]}}">{{selectedCountMap[item.id]}}</view>
            </view>
        </scroll-view>
        <!-- 第二列证书名称 -->
        <scroll-view class="second-column" scroll-y scroll-with-animation>
            <view wx:for="{{classes}}" wx:key="id" class="second-item {{(currentClass.id === item.id || (selectedMap[currentGrade.id]&&selectedMap[currentGrade.id].class&&selectedMap[currntGrade.id].class.id === item.id)) ? 'active':''}}" bindtap="selectClass" data-item="{{item}}" data-index="{{index}}">{{item.name}}</view>
        </scroll-view>
        <!-- 证书等级 -->
        <scroll-view class="third-column" scroll-y scroll-with-animation>
            <view wx:for="{{students}}" wx:key="id" class="second-item {{(currentStudent.id === item.id || (selectedMap[currentGrade.id] && selectedMap[currentGrade.id].student && selectedMap[currentGrade.id].student.id === item.id)) ? 'active':''}}" bindtap="selectStudent" data-item="{{item}}">{{item.name}}</view>
        </scroll-view>
    </view>
    <view class="add-group" >
        <view class="add-title">已添加:</view>
        <scroll-view scroll-x="true" class="add-srcooll" show-scrollbar="{{false}}" enhanced="{{true}}" enable-flex>
            <view class="text-list" bindtap="removeBenefit" wx:for="{{selectedStudents}}" wx:key="name" data-index="{{index}}">
                <text class="text">{{item.name}}</text>
                <view class="close">×</view>
            </view>
        </scroll-view>
    </view>
    <view class="btn-group">
        <button bindtap="confirmSelection" type="primary" class="sunbmit-btn" disabled="{{selectedStudents.length === 0}}">确定(已选 <view class="position-number">
                <view class="count">{{selectedStudents.length}}/</view>
                <view class="total">5</view>
            </view>项) </button>
    </view>
</view>

// pages/relase/certificate/certificate.js
Page({

    /**
     * 页面的初始数据
     */
    data: {
        positionselect: "资格证书",
        certificate: [{
                id: 1,
                title: "生产制造",
                
                listtitle: [{
                        ltitle: "普工",
                        position: [{name: "普工/操作工",selected: false},
                            {name: "包装工",selected: false},
                            {name: "学徒工",selected: false},
                            {name: "搬运工/装卸工",selected: false},
                            {name: "组装工",selected: false}
                        ]
                    },
                    {
                        ltitle: "机械加工",
                        position: [{name: "焊工",selected: false},
                            {name: "氩弧焊工",selected: false},
                            {name: "车工",selected: false},
                            {name: "钳工",selected: false},
                            {name: "切割工",selected: false},
                            {name: "钣金工",selected: false},
                            {name: "注塑工",selected: false},
                            {name: "折弯工",selected: false},
                        ]
                    },
                ]
            },
            {
                id: 2,
                title: "人事/行政",
                
                listtitle: [{
                    // id: 2,
                    ltitle: "人力资源",
                    position: [{name: "人力资源专员/助理",selected: false},
                        {name: "人力资源经理/主管",selected: false},
                        {name: "人力资源总监",selected: false},
                        {name: "人力资源VP/CHO",selected: false},
                    ]
                }, 
                {
                  ltitle: "行政",
                  position: [{name: "行政专员/助理",selected: false}, 
                    {name: "行政经理/主管",selected: false}, 
                    {name: "行政总监",selected: false}, 
                    {name: "前台",selected: false}, 
                    {name: "后勤",selected: false}, 
                    {name: "销售行政主管",selected: false}
                  ]
                },]
            }

        ],
        currentType: {}, // 当前选中的证书类型
        currentName: [], // 当前选中的证书名称
        currentGrade: {}, // 当前选中的证书等级

        showName: [], // 当前显示的证书名称列表
        showGrade: [], // 当前显示的证书等级列表
        selectedNames: [], // 已选中的证书名称
        selectedGrade: [], // 已选中的证书等级

        isSelected: false,
        selectedCount: 0,
        selectedList: [],
        selectedCountMap: {},
        hasSelectedGrade:false
    },

    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
        // 设置默认的第一列选中项
        const currentType = this.data.certificate[0];
        console.log(currentType);
        // 设置默认的第二列内容
        const showName = currentType.listtitle;
        console.log(showName);
        const showGrade = currentType.listtitle[0].position;
        console.log(showGrade);
        // 更新数据
        this.setData({
            currentType: currentType.id,
            showName: showName,
            showGrade: []
        });

    },
    certificateType(e) {
        console.log(e);
        const {id} = e.currentTarget.dataset;
        console.log(id);
        // 找到选中的第一列项
        const selectedType = this.data.certificate.find(item => item.id === id);
        console.log(selectedType);
        // 设置第二列内容
        const showName = selectedType.listtitle;
        // console.log(showName);
        // const showGrade = selectedType.listtitle[0].position;
        // console.log(showGrade);
        
        // 更新数据
        this.setData({
            currentType: selectedType.id,
            showName: showName,
            currentName: [], 
            currentGrade: {},
            showGrade: []
        });
    },
    certificateName(e){
        console.log(e);
        // 第一列选中的ID
        const id = this.data.currentType;
        console.log( id)
        // 第二列选中的index
        const {index} = e.currentTarget.dataset;
        console.log( index)
        // 第一列当前选中的证书类型
        const selectedType = this.data.certificate.find(item => item.id === id);
        console.log( selectedType)
        // 第二列当前选中的证书名称
        const currentName = selectedType.listtitle[index].ltitle;
        console.log( currentName)
        const showGrade = selectedType.listtitle[index].position;
        console.log( showGrade)

        this.setData({
            currentName: currentName,
            showGrade: showGrade,
            currentGrade: {},
        });
    },

    certificateGrade(e){
        console.log(e)
        const typeId = this.data.currentType;
        console.log("证书类型ID",typeId)
        // const Name = this.data.showName[typeId];
        //  console.log(Name);
        const {posindex} = e.currentTarget.dataset;
        // console.log( posindex) // 打印的值为:0  
        const isSelected = this.data.showGrade[posindex];
        // console.log(isSelected) 
        const selectedCountMap = this.data.selectedCountMap;
        // console.log("已选中证书名称ID下的证书等级数量",selectedCountMap)

        let selectedList = [...this.data.selectedList]
        // console.log(selectedList) 
        if (isSelected.selected == false) {
            if (selectedList.length >= 5) {
                wx.showToast({
                    title: '最多选择5项',
                    icon: 'none'
                })
                return
            }
            // Name.selected = true;
            isSelected.selected = true
            selectedList.push({ name: isSelected.name, posindex });
            selectedCountMap[typeId] = (selectedCountMap[typeId] || 0) + 1;
        } else {
            // Name.selected = false;
            isSelected.selected = false
            selectedCountMap[typeId] = (selectedCountMap[typeId] || 0) - 1;
            selectedList = selectedList.filter((item) => !(item.posindex === posindex));
        }
        
         
         
         if(currentName){
            // 如果第二列有选中的情况下,第三列有没有选中都是高亮
             if(isSelected.selected == false){
                 this.setData({currentName:currentName})
             }else{
                this.setData({currentName:currentName})
            }
         }else{
        // 如果第二列没有选中的情况下,第三列选中,第二列高亮,如果第三列没有选中,第二列不高亮
            if(isSelected.selected == true){
                this.setData({currentName:''})
            }else{
                this.setData({currentName:currentName})
            }
        }
        this.setData({
            currentName:this.data.showName,
            showGrade:this.data.showGrade,
            selectedList,
            selectedCountMap:selectedCountMap,
        })
    },


    removeBenefit(e) {
        const index = e.currentTarget.dataset.index;
        const selectedList = this.data.selectedList.filter((item, idx) => idx !== index);
        this.setData({ selectedList });
    
        // 更新已选中项的数量
        const selectedCount = selectedList.length;
        const selectedCountMap = { ...this.data.selectedCountMap, [this.data.currentType]: selectedCount };
        this.setData({ selectedCount, selectedCountMap });
      },
})
  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-08-08 10:55
    关注

    上午好☀️☀️☀️️
    本答案参考通义千问

    要实现 三级菜单选项中, 第二级高亮的逻辑,需要根据用户的选择动态更新数据状态,并在视图中根据当前选中的状态来决定是否高亮二级菜单。以下是详细的解决方案:


    一、核心逻辑分析

    1. 点击一级菜单(如“生产制造”):只改变一级菜单的高亮状态,不影响二级和三级菜单。
    2. 点击二级菜单(如“普工”)无论三级菜单是否选中,二级菜单都应高亮
    3. 点击三级菜单(如“普工/操作工”)如果该三级菜单被选中,则二级菜单也要高亮
    4. 切换到其他一级菜单(如“机械加工”)若之前选中的三级菜单未被取消,则二级菜单仍高亮;否则取消高亮

    二、实现步骤

    1. 数据结构设计

    确保你的数据结构能够记录每个层级的选中状态:

    data: {
        grades: [
            { id: 1, name: "生产制造", listtitle: [...] },
            { id: 2, name: "机械加工", listtitle: [...] }
        ],
        classes: [], // 当前一级选中后的二级列表
        students: [], // 当前二级选中后的三级列表
        selectedMap: {}, // 存储选中状态
        currentGrade: null,
        currentClass: null,
        currentStudent: null
    }
    

    2. 点击事件处理

    a) 选择一级菜单(selectGrade

    selectGrade(e) {
        const item = e.currentTarget.dataset.item;
        this.setData({
            currentGrade: item,
            classes: item.listtitle,
            currentClass: null,
            currentStudent: null,
            selectedMap: {} // 清空之前的选中状态
        });
    }
    

    b) 选择二级菜单(selectClass

    selectClass(e) {
        const item = e.currentTarget.dataset.item;
        const gradeId = this.data.currentGrade.id;
    
        // 更新当前选中的二级菜单
        this.setData({
            currentClass: item,
            students: item.position,
            currentStudent: null
        });
    
        // 如果当前选中的二级菜单没有被选中过,则标记为选中
        if (!this.data.selectedMap[gradeId] || !this.data.selectedMap[gradeId].class) {
            this.setData({
                selectedMap: {
                    ...this.data.selectedMap,
                    [gradeId]: {
                        class: item,
                        student: null
                    }
                }
            });
        }
    }
    

    c) 选择三级菜单(selectStudent

    selectStudent(e) {
        const item = e.currentTarget.dataset.item;
        const gradeId = this.data.currentGrade.id;
        const classId = this.data.currentClass.id;
    
        // 标记当前选中的三级菜单
        this.setData({
            currentStudent: item
        });
    
        // 更新 selectedMap 中的三级选中状态
        this.setData({
            selectedMap: {
                ...this.data.selectedMap,
                [gradeId]: {
                    class: this.data.currentClass,
                    student: item
                }
            }
        });
    }
    

    3. 视图中高亮判断逻辑

    a) 一级菜单高亮

    <view wx:for="{{grades}}" wx:key="id" class="first-item {{currentGrade.id === item.id ? 'greenColor':''}}" bindtap="selectGrade" data-item="{{item}}">
        ...
    </view>
    

    b) 二级菜单高亮(关键逻辑)

    <view wx:for="{{classes}}" wx:key="id" class="second-item 
    {{(currentClass.id === item.id || (selectedMap[currentGrade.id] && selectedMap[currentGrade.id].class && selectedMap[currentGrade.id].class.id === item.id)) ? 'active':''}}" 
    bindtap="selectClass" data-item="{{item}}">
        {{item.name}}
    </view>
    

    重点说明:

    • currentClass.id === item.id:表示当前选中的是这个二级菜单。
    • selectedMap[currentGrade.id].class.id === item.id:表示之前选中了这个二级菜单,即使三级菜单没有选中,也应保持高亮

    c) 三级菜单高亮

    <view wx:for="{{students}}" wx:key="id" class="second-item 
    {{(currentStudent.id === item.id || (selectedMap[currentGrade.id] && selectedMap[currentGrade.id].student && selectedMap[currentGrade.id].student.id === item.id)) ? 'active':''}}" 
    bindtap="selectStudent" data-item="{{item}}">
        {{item.name}}
    </view>
    

    三、关键代码修改总结

    修改后的 certificate.js 示例(部分关键代码)

    Page({
        data: {
            grades: [...],
            classes: [],
            students: [],
            selectedMap: {},
            currentGrade: null,
            currentClass: null,
            currentStudent: null
        },
    
        selectGrade(e) {
            const item = e.currentTarget.dataset.item;
            this.setData({
                currentGrade: item,
                classes: item.listtitle,
                currentClass: null,
                currentStudent: null,
                selectedMap: {}
            });
        },
    
        selectClass(e) {
            const item = e.currentTarget.dataset.item;
            const gradeId = this.data.currentGrade.id;
    
            this.setData({
                currentClass: item,
                students: item.position,
                currentStudent: null
            });
    
            if (!this.data.selectedMap[gradeId] || !this.data.selectedMap[gradeId].class) {
                this.setData({
                    selectedMap: {
                        ...this.data.selectedMap,
                        [gradeId]: {
                            class: item,
                            student: null
                        }
                    }
                });
            }
        },
    
        selectStudent(e) {
            const item = e.currentTarget.dataset.item;
            const gradeId = this.data.currentGrade.id;
            const classId = this.data.currentClass.id;
    
            this.setData({
                currentStudent: item
            });
    
            this.setData({
                selectedMap: {
                    ...this.data.selectedMap,
                    [gradeId]: {
                        class: this.data.currentClass,
                        student: item
                    }
                }
            });
        }
    });
    

    四、注意事项

    • 数据结构清晰:确保 selectedMap 能够正确存储每一级的选中状态。
    • 状态同步:每次选择后都要更新 selectedMapcurrentXXX 状态。
    • 视图逻辑准确:在视图中使用条件判断来控制高亮,特别是 二级菜单的高亮 需要考虑 三级菜单是否被选中

    五、最终效果

    • 点击二级菜单时,不管三级是否选中,二级高亮。
    • 点击三级菜单时,二级菜单依然高亮。
    • 切换一级菜单时,只有当三级菜单未选中,才取消二级高亮。

    通过以上逻辑,你可以实现你描述的高亮效果。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 8月23日
  • 已采纳回答 8月15日
  • 创建了问题 8月8日