当前位置: 首页 > wzjs >正文

那位学生网站开发厦门百度代理公司

那位学生网站开发,厦门百度代理公司,网版制作过程,企业建设网站的主要目的有哪些目录 背景实现功能点遗留问题完整代码参考 背景 需要实现:选择省级地址时,回传节点为 [ 省级地址 id], 选择市级地址时,回传节点为 [ 省级地址 id,市级地址 id], 选择区县地址时,回传节点为 [ …

目录

  • 背景
  • 实现功能点
  • 遗留问题
  • 完整代码参考

背景

  • 需要实现:选择省级地址时,回传节点为 [ 省级地址 id], 选择市级地址时,回传节点为 [ 省级地址 id,市级地址 id], 选择区县地址时,回传节点为 [ 省级地址 id,市级地址 id,区县地址 id]。
  • 但 el-cascader-panel 双向绑定数据-已选区域,仅支持到最末级,即无论选择哪一级,回传节点均为[ 省级地址 id,市级地址 id,区县地址 id],与要求的数据结构不符。

实现功能点

  • 省市区三级地址多选,实现:选择省级地址时,回传节点为 [ 省级地址 id], 选择市级地址时,回传节点为 [ 省级地址 id,市级地址 id], 选择区县地址时,回传节点为 [ 省级地址 id,市级地址 id,区县地址 id]。
  • 过滤 不可选区域
    • checkDisabled 方法
      • 遍历树状结构areaData,为其每个节点添加全路径 path 属性(省级地址 path 为 [ 省级地址 id],市级地址 path 为 [ 省级地址 id,市级地址 id], 区县地址 path 为 [ 省级地址 id,市级地址 id,区县地址 id])
      • 遍历过程中,刷选属性 disabled 为 true 的节点,将其 path 添加到 result 变量中,从而实现将该节点及其祖先节点均添加到 result 变量中
      • 遍历后,对 result 数组元素进行去重,得到当前节点或子孙节点 disabled 为 true 且元素唯一的 disabledIds 数组
      • 在handleChange 方法中,通过过滤已选节点(disabledIds 中不包含该节点 id)实现,过滤不可选区域
  • 兼容后端返回已选区域(已选区域前端回显,以及变更选择区域后后端 api 入参)
    • initSelectedPaths 方法
      • 遍历后端返回的已选区域数组tempSelectedAreas,结合 areaData,将其转为 el-cascader-panel 双向绑定数据-已选区域要求的数据结构,即节点结构均为 [省级地址 id,市级地址 id,区县地址 id],从而实现前端正确回显已选区域
      • 获取到后端数据tempSelectedAreas 后,讲其浅拷贝给selectedAreas,避免当未进行任何操作直接点击保存时,selectedAreas 为空,丢失原有已选区域的问题

遗留问题

  • 树状结构层级硬编码:仅实现了树状结构层级不超过 3 级的场景,更多层级或者无限层级问题并未解决
  • 实现逻辑复杂,过多数据遍历:核心方法findDisabledIds、initSelectedPaths、handleChange 均存在频繁 forEach 遍历数组等情况,但未找到解决办法。

如有更好解决办法,欢迎大佬赐教!!!

完整代码参考

模拟数据-树状结构

[{"id": 1,"name": "河南省","children": [{"id": 4,"name": "郑州市","children": [{"id": 7,"name": "高新区","children": []},{"id": 8,"name": "中原区","children": []}]},{"id": 5,"name": "信阳市","children": [{"id": 9,"name": "息县","children": []}]}]
},{"id": 2,"name": "河北省","children": [{"id": 10,"name": "石家庄市","children": [{"id": 11,"name": "石家庄市区","children": []}]}]
},{"id": 3,"name": "北京市","children": [{"id": 12,"name": "北京市","children": [{"id": 13,"name": "朝阳区","children": []}]}]
}]

主要实现逻辑

<template><div><el-cascader-panelref="cascaderPanel"v-model="selectedPaths":options="areaData":props="cascaderProps"@change="handleChange"/></div>
</template><script lang="ts" setup>import {onMounted, ref} from "vue";import areaData from "../express/areaData.json"; // 假设这是您的树形数据import type {CascaderNode, CascaderProps} from "element-plus";// el-cascader-panelde v-model动态绑定对象const selectedPaths = ref<number[][]>([]);// 后端返回已选择的区域const tempSelectedAreas = ref<number[][]>([])// 选中的区域(包含已选和新选)const selectedAreas = ref<number[][]>([])const cascaderPanel = ref();/** 配置Cascader属性 **/const cascaderProps: CascaderProps = {value: "id", // 值字段名label: "name", // 显示字段名children: "children",disabled: "disabled",multiple: true, // 启用多选};type TreeNode = {id: number;name: string;children?: TreeNode[];disabled?: boolean | string; // 假设 disabled 是字符串类型path?: number[]};/*** 查找树形结构中当前节点或子孙节点 disabled 为 true 的所有 id* @returns 包含符合条件的 id 数组*/const findDisabledIds = (): number[] => {let result:number[] = [];const checkDisabled = (node: TreeNode) => {if (node.disabled === "true" || node.disabled === true) {result = [...result, ...node.path as number[]];}}// 格式化areaData(为每个节点添加全路径path),取出disabled的节点(包含其父节点、祖先节点)areaData.forEach((parentNode: TreeNode ) => {parentNode.path = [parentNode.id]checkDisabled(parentNode)if (parentNode.children && parentNode.children.length > 0) {parentNode.children.forEach((node: TreeNode) => {node.path = [parentNode.id, node.id]checkDisabled(node)if (node.children && node.children.length > 0) {node.children.forEach((childrenNode: TreeNode) => {childrenNode.path = [parentNode.id, node.id, childrenNode.id];checkDisabled(childrenNode)})}})}})const tempResult = new Set(result)return Array.from(tempResult)}// 当前节点或子孙节点 disabled 为 true 的所有 idconst disabledIds = findDisabledIds()// 此处仅为模拟,应该调用后端接口const getTempSelectedAreas = () => {tempSelectedAreas.value = [[1]]initSelectedPaths()selectedAreas.value = [...tempSelectedAreas.value]}// 根据后端返回已选择的区域,初始化el-cascader-panelde v-model动态绑定对象const initSelectedPaths = () => {if(!tempSelectedAreas.value || !tempSelectedAreas.value.length) returntempSelectedAreas.value.forEach(area => {const parentNode:TreeNode | undefined = areaData.find(item => item.id == area[0])if(area.length == 1){if(!parentNode) returnif(parentNode.children && parentNode.children.length > 0){parentNode.children.forEach((node:TreeNode) => {if(node.children && node.children.length > 0){node.children.forEach((childrenNode: TreeNode) => {selectedPaths.value.push(childrenNode.path as number[])})}else {selectedPaths.value.push(node.path as number[])}})}else {selectedPaths.value.push(parentNode.path as number[])}}else if(area.length == 2){const node:TreeNode | undefined = parentNode?.children?.find(item => item.id == area[1])if(!node) returnif(node.children && node.children.length > 0){node.children.forEach((childrenNode:TreeNode) => {selectedPaths.value.push(childrenNode.path as number[])})}else {selectedPaths.value.push(node.path as number[])}}else if(area.length == 3){const node:TreeNode | undefined = parentNode?.children?.find(item => item.id == area[1])const childrenNode:TreeNode | undefined = node?.children?.find(item => item.id == area[2])if(!childrenNode) returnselectedPaths.value.push(childrenNode.path as number[])}})
}/** 处理选中变化 **/
const handleChange = () => {selectedAreas.value = []const checkedNodes = cascaderPanel.value.getCheckedNodes().filter((node:CascaderNode) => !disabledIds.includes(node.value as number))if (!checkedNodes || !checkedNodes.length) returncheckedNodes.forEach( (node:CascaderNode) => {if(node.level == 1 ) {selectedAreas.value.forEach((area, index) => {if(area[0] == node.value){selectedAreas.value.splice(index, 1)}})selectedAreas.value.push(node.pathValues as number[])}else if(node.level == 2){selectedAreas.value.forEach((area, index) => {if(area[1] == node.value){selectedAreas.value.splice(index, 1)}})if(selectedAreas.value.findIndex(item => item.length == 1 && item[0] == node.pathValues[0]) == -1) {selectedAreas.value.push(node.pathValues as number[])}}else if(node.level == 3){selectedAreas.value.forEach((area, index) => {if(area[2] == node.value){selectedAreas.value.splice(index, 1)}})if(selectedAreas.value.findIndex(item => (item.length == 1 && item[0] == node.pathValues[0]) || (item.length == 2 &&  item[1] == node.pathValues[1]))  == -1 ) {selectedAreas.value.push(node.pathValues as number[])}}})
}
onMounted(() => {getTempSelectedAreas()
})
</script>
http://www.dtcms.com/wzjs/199458.html

相关文章:

  • 缙云做网站周口seo推广
  • 烟台网站建设设计开发app拉新项目一手渠道商
  • 想要找个网站做环评公示昆明seo排名外包
  • 上海的外贸网站建设公司价格购物网站有哪些
  • 大淘客可以做几个网站北京seo技术交流
  • 网站模板制作教程视频教程自媒体是什么
  • 广州汽车网络推广服务网站推广优化排名seo
  • 新图闻的互联网+产品及服务三台网站seo
  • 做谷歌推广对网站的要求长沙seo霸屏
  • 四川简阳建设局招标公告网站竞价托管怎么做
  • 网站页面效果图怎么做的seo专业术语
  • 网站建设进度表模板下载深圳专门做seo的公司
  • 聊城手机网站建设公司企业培训课程安排表
  • 如何创建自己的软件桔子seo网
  • 网站网页怎么做百度数据研究中心官网
  • 360免费建站怎么样外包公司和劳务派遣的区别
  • 省内注销二建 建设部网站更新慢竞价推广账户托管
  • 企业官网设计优化神马排名软件
  • 现在做网站用什么工具都有什么推广平台
  • 上海备案证查询网站查询网站查询系统网站优化就是搜索引擎优化
  • 武汉网站建设公司排名网站推广怎么写
  • 手机视频网站建站国际域名注册网站
  • 网站js修改头像代码自己如何制作网站
  • 企业网站页头背景图百度在线客服问答
  • 网站做支付功能专注于网站营销服务
  • 比较好的网站建设公司电话沈阳企业网站seo公司
  • 国内常见b2b平台有哪些北京seo推广系统
  • 建设凡科网站seo策略
  • 做网站的外包公司上班好不好竞价开户公司
  • jsp网站入门自助建站网站哪个好