Naive UI 组件使用体验之-级联选择 Cascader

image.png

使用场景

  • 地址区域选择

简单使用

安装依赖

npm install naive-ui -D

按需引入之-手动引入

import {
    NCascader,
    CascaderOption
} from 'naive-ui'

使用

<n-cascader
    :value="regionValue"
    :options="regionOptions"
    :multiple="false"
    placeholder="所在地区"
    remote
    clearable
    check-strategy="child"
    @load="handleLoad"
/>

增加操作

这里我们是要对收货地址进行一个增加操作。
我们这里只针对所在地址进行说明。

获取region

这里需要通过接口提前请求

const regionOptions = ref([])

// 获取区域列表
const getRegionList = async () => {
  // 获取region的接口
  const res = await findBaseRegion()
  regionOptions.value = res.map((item: CascaderOption) => {
    return {
      label: item.regionName,
      value: item.id,
      depth: 1,
      isLeaf: false
    }
  });
}

onMounted(() => {
  getRegionList()
})

接口返回的数据如下:

{
  "code": 200,
  "message": "成功",
  "data": [
    { "id": 1, "regionName": "华北" },
    { "id": 2, "regionName": "华东" },
    { "id": 3, "regionName": "东北" },
    { "id": 4, "regionName": "华中" },
    { "id": 5, "regionName": "华南" },
    { "id": 6, "regionName": "西南" },
    { "id": 7, "regionName": "西北" }
  ],
  "ok": true
}

这个数据需要进行格式转换,处理成下面的格式:

[
  {
    label: '华北',
    value: 1, 
    depth: 1,
    isLeaf: false
  },
  ...
]

属性说明

属性 描述
label 标题
value
depth 深度,根据depth来判断处在同一级的元素
isLeaf 是否是最后一层,如果为true,后面的数据不再展开

我们使用上面处理好的数据,赋值给regionOptions即可进行渲染。

获取province

接下来我们需要在选择完毕region以后,根据对应的value去接口请求对应的province的数据,然后展示出来。

这里涉及到一个异步请求数据的过程,我们这样做

<n-cascader
    :value="regionValue"
    :options="regionOptions"
    @load="handleLoad"
/>

绑定load事件,在load事件中,接收option参数

const handleLoad = (option: CascaderOption) => {

  return new Promise<void>(async (resolve, reject) => {
    const list = await getProvinceList(option.value as number); 
    if (list.length > 0) {
      option.children = list;
      resolve()
    } else {
      reject()
    }
  })
}

option.value即为我们选中的value值,根据这个值去请求getProvinceList这个接口,最后拿到
provinceList赋值给option。children。注意这里的return new Promise,返回的一定得是一个Promise,而且必须要resolveorreject才能请求成功,不然有个菊花会一直在那爱的魔力转圈圈。

在请求接口的时候,同样的也需要把返回的数据处理成符合规范的数据格式,代码如下:

const getProvinceList = async (id: number) => {
  const res = await findBaseProvinceByRegionId(id as number)
  const list:CascaderOption[]  = [];
  for(let i = 0; i < res.length; i ++) {
    list.push({
      label: res[i].name,
      value: `${id}-${res[i].id}`,
      depth: 2,
      isLeaf: true
    })
  }
  return list;
}

注意:

  • value: ${id}-${res[i].id},写成这样的原因是它的value值的规则限制是x、x-y、x-y-z这种,比如1,1-2,1-2-3,不知道能不能看懂,看不懂自己实践一下。
  • depth的值变成了2
  • isLeaf: true,表示是最后一层了。

最后通过绑定的value值,在发生了value值变化的时候,我们就可以实时拿到他的值了。在所有的数据添加完毕,提交数据的时候,还需要对value值进行处理,因为我们选择完地址以后,发现它的value值是1-1,1-2,1-3这样的,-前面的的表示regionId,-后面的表示provinceId,后端需要的是分开传,不是1-1,1-2,1-3这样的,所以得拆开一下,我也是吐了。我们这里简单的split一下就行了。

const addstr = regionValue.value.split('-');
modal.value.regionId = addstr[0];
modal.value.provinceId = addstr[1];  

添加操作到此为止。

修改操作

这里我们是要对收货地址进行过一个修改操作。修改的话就需要数据回显。我们需要拿到regionList和对应的privinceList的数据。

获取regionList还是和之前一样,没有变化。当我们点击修改按钮的时候,拿到对应的reginId去请求privinceList的数据,代码如下:

// 更新地址
const handleUpdateAdd = (item: any) => {
  showModal.value = true;
  editType.value = 'update';

  regionOptions.value.map(async (n: CascaderOption) => {
    if (n?.value === item.regionId) {
      // 根据相同的value值,触发接口请求,处理好的数据,赋值给children即可
      n.children = await getProvinceList(item.regionId)
      // 更新绑定的vaue值的格式,跟上面讲的格式一样
      regionValue.value = `${item.regionId}-${item.provinceId}` as any
    }
  })
  
  // 对表单默认值覆盖
  modal.value = {
    ...item
  }
}

如上代码所示,回显的时候赋值一下valuechildren的值就能正常显示了,必须按照数据格式的要求来。

使用总结

上面啰里八嗦的一大堆,其实是我搞了好半天才摸索出来的,看着其实也没啥难点,只有一点,当初搞崩溃了,就是value的值怎么触发它都不变化,最后看了一下它这个值的规则,吐血了直接,官方文档也没有说明,只是看它示例中写的1-1, 1-1-1这样的。一直以为就是选择哪个值它就是那个值,没想它的是根据父级-子级这样子来的。

最后附上官网链接:https://www.naiveui.com/zh-CN/light/components/cascader#Cascader-Slots

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容