微信小程序分类界面显示、左树右表形式

这是一个智能医疗系统的界面设计实例,展示了医院科室选择的功能。用户可以通过顶部下拉框选择搜索类型,左右两侧支持懒加载,右侧科室列表会根据左侧医院选择动态更新。界面采用自适应布局,能根据设备高度自动调整,确保在不同设备上的良好兼容性。同时,用户可以多选科室,提供更好的交互体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 主要以医院科室为示例进行编写,左边为医院列表,右侧为每个医院下对应的具体科室列表,左右两侧均支持添加懒加载功能;顶部下拉框选择,则可实现根据不同的选择,改变搜索框需要搜索的内容;此外,支持选择多个科室。
    此界面的数据显示完全支持自适应,均是经过设备高度自动换算,增强界面的兼容性。可根据自己需求随意修改,当然也存在很多不足的地方,欢迎指正批评,多谢!
    别忘了点赞收藏哦!

1.界面展示:
微信小程序左右分类界面
2.JS代码:

Page({

  /**
   * 页面的初始数据
   */
  data: {
    scroll:true, //是否允许右侧内容滚动
    index: 0,
    array: ['医院', '科室'],
    useHeight:'',
    current:'0',
    leftList:[
      {id:'0',text:'测试医院1'},{id:'1',text:'类别医院2'},{id:'2',text:'测试医院3'},
      {id:'3',text:'测试医院4'},{id:'4',text:'测试医院5'},{id:'5',text:'测试医院6'},
      {id:'6',text:'测试医院7'},{id:'7',text:'类别医院8'},{id:'8',text:'测试医院9'},
      {id:'9',text:'测试医院10'},{id:'10',text:'测试医院11'},{id:'11',text:'测试医院12'},
      {id:'12',text:'测试医院13'},{id:'13',text:'类别医院14'},{id:'14',text:'测试医院15'},
      {id:'15',text:'测试医院16'},{id:'16',text:'测试医院17'},{id:'17',text:'测试医院18'},
      {id:'18',text:'测试医院19'},{id:'19',text:'类别医院20'},{id:'20',text:'测试医院21'},
      {id:'21',text:'测试医院22'},{id:'22',text:'测试医院23'},{id:'23',text:'测试医院24'},
      {id:'24',text:'测试医院25'},{id:'25',text:'类别医院26'},{id:'26',text:'测试医院27'},
      {id:'27',text:'测试医院28'},{id:'28',text:'测试医院29'},{id:'29',text:'测试医院30'}
    ],
    rightList:[]
  },
  /**
   * 选择搜索类型
   */
  bindPickerChange(e){
    this.setData({
      index:e.detail.value
    })
  },
  /**
   * 左侧点击事件
  */
  bindSelectLeft(e){
    let index = e.currentTarget.dataset.id;
    this.setData({
      current:index
    })
    this.getDataList(index);
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.getDataList(0);
  },
  // 数据初始化
  getDataList(e){
    let list1 = [
      {code:'0',text:'点赞科室'}, {code:'1',text:'收藏科室'},{code:'2',text:'关注科室'},
      {code:'3',text:'谢谢科室'},{code:'4',text:'非常感谢科室'},{code:'5',text:'栓Q科室'},
      {code:'0',text:'点赞科室'},{code:'1',text:'收藏科室'},{code:'2',text:'关注科室'},
      {code:'3',text:'谢谢科室'},{code:'4',text:'非常感谢科室'},{code:'5',text:'栓Q科室'},
      {code:'0',text:'点赞科室'},{code:'1',text:'收藏科室'},{code:'2',text:'关注科室'},
      {code:'3',text:'谢谢科室'},{code:'4',text:'非常感谢科室'},{code:'5',text:'栓Q科室'}
    ];
    let list2 = [
      {code:'3',text:'谢谢科室'},{code:'4',text:'非常感谢科室'},{code:'5',text:'栓Q科室'},
      {code:'0',text:'点赞科室'},{code:'1',text:'收藏科室'},{code:'2',text:'关注科室'},
      {code:'3',text:'谢谢科室'},{code:'4',text:'非常感谢科室'},{code:'5',text:'栓Q科室'}
    ]
    if(e==0){
      this.setData({
        rightList:list1,
        scroll:true
      })
    }else if(e==2){
      this.setData({
        rightList:list2,
        scroll:true
      })
    }else{
      this.setData({
        rightList:[],
        scroll:false
      })
    }
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    // 获取当前设备可用高度
    let that = this;
    wx.getSystemInfo({
      success(res) {
        that.setData({
          useHeight:res.windowHeight
        })
      }
    })
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

3.wxml代码:

<!-- 顶部区域 -->
<view class="level search-box" style="height: {{useHeight*0.08}}px;">
  <!-- 左边下拉框 -->
  <view class="down-box">
    <picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
      <text>{{array[index]}}</text>
      <text></text>
    </picker>
  </view>
  <!-- 中间搜索框 -->
  <view class="level input-box">
    <icon class="input-icon" type="search" size="16"></icon>
    <input placeholder="请输入{{array[index]}}名称"/>
  </view>
  <!-- 搜索按钮 -->
  <view class="button-box">
    <view>搜索</view>
  </view>
</view>
<!-- 内容区域 -->
<view class="level">
  <!-- 左边 -->
  <view class="left-box">
    <scroll-view scroll-y="true" style="height: {{useHeight*0.91}}px;">
      <block wx:for="{{leftList}}" wx:key="item">
        <view 
        bindtap="bindSelectLeft" 
        data-id="{{item.id}}" 
        class="left-text {{current==item.id?'yes':'no'}}">{{item.text}}</view>
      </block>
    </scroll-view>
  </view>
  <!-- 右边 -->
  <view class="right-box">
    <scroll-view scroll-y="{{scroll}}" style="height: {{useHeight*0.85}}px;">
      <view wx:if="{{rightList.length>0}}">
        <block wx:for="{{rightList}}" wx:key="item">
          <view class="right-text">
            <label class="level">
              <view class="right-value">{{item.text}}</view>
              <checkbox class="check-box" value="{{item.code}}" checked="true"/>
            </label>
          </view>
        </block>
      </view>
      <!-- 无数据显示 -->
      <view class="not-data" wx:else>
        <text>暂无数据!</text>
      </view>
    </scroll-view>
    <view class="level">
      <view class="btn btn-no">取消</view>
      <view class="btn btn-yes">确定</view>
    </view>
  </view>
</view>

4.wxss代码:

page{
  background-color: white;
}
/* 水平居中摆放(行内元素) */
.level{
  display: flex;
  flex-direction: row;
  align-items: center;
}
/* 搜索 */
.search-box{
  padding-left: 15rpx;
  padding-right: 15rpx;
  border-bottom: 1rpx solid #f1f1f1;
}
.down-box{
  width: 15%;
  border: 1rpx solid #f1f1f1;
  border-radius: 10rpx;
  font-size: 32rpx;
  padding: 10rpx 15rpx;
  color: gray;
}
.input-box{
  width: 70%;
  font-size: 30rpx;
  background-color: #f1f1f1;
  margin-left: 10rpx;
  border-radius: 10rpx;
  padding: 10rpx 15rpx;
}
.input-icon{
  padding: 0 5rpx;
}
.button-box{
  width: 15%;
  font-size: 32rpx;
  color: #0099ff;
  text-align: center;
}
/* 左侧内容 */
.yes{
  background-color: white;
  border-left: 10rpx solid #0099ff;
  border-top-left-radius: 10rpx;
  border-bottom-left-radius: 10rpx;
}
.no{
  border-left: 10rpx solid transparent;
}
.left-box{
  width: 30%;
  background-color: #f1f1f1;
  text-align: center;
  font-size: 32rpx;
}
.left-text{
  border-bottom: 1rpx solid white;
  padding: 30rpx 10rpx;
}
/* 右侧内容 */
.right-box{
  width: 70%;
  margin: 0rpx 10rpx;
  color: rgb(43, 38, 38);
}
.right-text{
  font-size: 31rpx;
  padding: 30rpx 10rpx;
  border-bottom: 1rpx solid #f1f1f1;
}
.right-value{
  flex: 1;
}
.check-box{
  flex: 1;
  text-align: right;
  zoom: .6;
}
/* 确定取消 */
.btn-box{
  justify-content: center;
}
.btn{
  flex: 1;
  padding: 10rpx 15rpx;
  border-radius: 10rpx;
  font-size: 32rpx;
  text-align: center;
  margin: 15rpx 15rpx 0rpx 15rpx;
}
.btn-no{
  color: #0099ff;
  background-color: #dddddd;
}
.btn-yes{
  color: white;
  background-color: #0099ff;
}
/* 无数据显示 */
.not-data{
  display: flex;
  justify-content: center;
  font-size: 32rpx;
  color: gray;
  margin-top: 50%;
}

### React中使用Ant Design实现左树右联动的解决方案 在React中,通过Ant Design组件库实现左树右联动的功能,可以结合`Tree`和`Table`组件完成。以下是具体的实现方法和示例代码: #### 数据源构造 为了实现左树右的联动效果,需要先构造数据源。左侧树的数据结构通常为嵌套数组形式,右侧格的数据源则遵循Ant Design的`dataSource`规范[^1]。通过配置生成左树`leftTree`和上树`topTree`,并结合自身的pipeline插件机制,可以实现格的交互操作(排序、筛选、分页)。 #### 左树右联动逻辑 当用户点击左侧树的某个节点时,右侧格需要展示与该节点相关的数据。这可以通过以下步骤实现: - 在`Tree`组件中绑定`onSelect`事件,捕获用户选择的节点信息。 - 根据选中的节点ID或其他标识符,过滤右侧格的数据源,仅显示符合条件的记录。 #### 示例代码 以下是一个完整的示例代码,展示了如何在React中使用Ant Design实现左树右联动功能: ```jsx import React, { useState, useEffect } from 'react'; import { Tree, Table } from 'antd'; const treeData = [ { title: 'Node1', key: '0-0', children: [ { title: 'Child Node1-1', key: '0-0-0' }, { title: 'Child Node1-2', key: '0-0-1' }, ], }, { title: 'Node2', key: '0-1', children: [ { title: 'Child Node2-1', key: '0-1-0' }, { title: 'Child Node2-2', key: '0-1-1' }, ], }, ]; const dataSource = [ { key: '1', name: 'Node1 Data', age: 32, address: 'New York', parentId: '0-0' }, { key: '2', name: 'Node1 Child Data', age: 42, address: 'London', parentId: '0-0-0' }, { key: '3', name: 'Node2 Data', age: 35, address: 'Sidney', parentId: '0-1' }, ]; const LeftTreeRightTable = () => { const [selectedKey, setSelectedKey] = useState(''); const [filteredData, setFilteredData] = useState([]); useEffect(() => { if (selectedKey) { const filtered = dataSource.filter((item) => item.parentId === selectedKey); setFilteredData(filtered); } else { setFilteredData(dataSource); } }, [selectedKey]); const onSelect = (selectedKeys) => { setSelectedKey(selectedKeys[0]); }; const columns = [ { title: 'Name', dataIndex: 'name', key: 'name' }, { title: 'Age', dataIndex: 'age', key: 'age' }, { title: 'Address', dataIndex: 'address', key: 'address' }, ]; return ( <div style={{ display: 'flex' }}> <Tree treeData={treeData} onSelect={onSelect} style={{ width: '30%' }} /> <Table dataSource={filteredData} columns={columns} pagination={false} style={{ width: '70%', marginLeft: '10px' }} /> </div> ); }; export default LeftTreeRightTable; ``` #### 关键点说明 1. **树结构数据**:`treeData`定义了左侧树的结构,每个节点包含`title`和`key`属性,子节点通过`children`字段嵌套。 2. **格数据源**:`dataSource`是右侧格的数据源,每条记录包含`parentId`字段,用于关联左侧树的节点。 3. **联动逻辑**:通过`onSelect`事件捕获用户选择的树节点,并根据`selectedKey`过滤格数据[^1]。 ### 注意事项 - 确保树节点的`key`值与格数据中的`parentId`值一致,以便正确实现联动。 - 如果需要支持更多交互功能(如搜索、展开/折叠),可以参考相关文档或扩展逻辑[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒜鸟小窝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值