vue3 element

lxf2023-04-15 08:32:01

一. 先弄实际效果

vue3 element

二. 需求背景

省市县镇乡多级联动, 依据父级懒加载表明子级, 写一个通用组件

  1. 这一通用组件必须满足双重数据绑定, 直接使用v-model, 能表格校检
  2. 交互形式维持统一的下拉选择挑选实际效果
  3. 不但新增加能够, 改动也可以正常的回显

三. 解决策略

vue3 element-plus

  1. 界定子组件接受值, 和3D渲染值;应用特性监视, 随后公布事情, 进行双向绑定
  2. 应用el-select部件, 随后用empty扩展槽, 裹住 el-cascader-panel
  3. 监视值更改时进行外键约束查询接口, 依据值获得相对应的地域目标

四. 代码逻辑

<template>
  <el-select
    v-model="provinceId"
    placeholder="挑选地域"
    class="selectLazy"
    clearable
    @change="changeSelect"
    :disabled="disabled"
    ref="selectLazyRef"
  >
    <template #prefix>
      <div class="areaName" v-if="areaName">{{areaName}}</div>
      <div class="empty" v-else>挑选地域</div>
    </template>
    <template #empty>
      <el-cascader-panel
        :props="propsCascader"
        v-model="cascaderValue"
        @change="changeCascader"
        ref="cascaderLazyRef"
      />
    </template>
  </el-select>
</template>

<script setup>
import { provinceQuery, provinceById } from "@/api/system/dict/data";

const { proxy } = getCurrentInstance();
const props = defineProps({
  modelValue: [String, Object, Array],
  disabled: {
    type: Boolean,
    default: false
  }
});

const cascaderValue = ref([]);
const selectLazyRef = ref(null);

const areaName = ref("");
const provinceId = ref("");

const propsCascader = {
  label: "name",
  value: "id",
  checkStrictly: true,
  lazy: true,
  lazyLoad: cascaderLazyLoad,
};
watch(
  () => props.modelValue,
  (val) => {
    provinceId.value = val;
    getProvinceById();
  },
  { deep: true, immediate: true }
);

const emit = defineEmits();

// 懒加载插口
function cascaderLazyLoad(node, resolve) {
  if (!node) {
    return false;
  }
  const { level } = node;
  const { id } = node.data;
  //level意味着现阶段点一下挑选哪一项,,例如0意味着第一次进去载入数据信息,1就是选择省后实际操作
  if (level == 0) {
    provinceQuery({ pid: 0 })
      .then((res) => {
        res.data.forEach((item) => {
          item.leaf = false;
        });
        resolve(res.data);
      })
      .catch((err) => {
        resolve([]);
      });
  } else {
    if (id) {
      provinceQuery({ pid: id })
        .then((res) => {
          res.data.forEach((item) => {
            item.leaf = level >= 3;
          });
          resolve(res.data);
        })
        .catch((err) => {
          resolve([]);
        });
    } else {
      resolve([]);
    }
  }
}

// 数据信息 外键约束 查看
function getProvinceById() {
  if (provinceId.value) {
    provinceById({ id: provinceId.value }).then((res) => {
      areaName.value = res.data.fullPath;
    });
  }
}

// 挑选 数据信息更改
function changeSelect() {;
  cascaderValue.value = [];
  areaName.value = "";
  emit("update:modelValue", null);
  selectLazyRef.value.visible = false;
}

// 级联 数据信息更改
function changeCascader() {;
  let emitProvinceId =
    cascaderValue.value && Array.isArray(cascaderValue.value)
      ? cascaderValue.value[cascaderValue.value.length - 1]
      : cascaderValue.value; // 所属区域
  emit("update:modelValue", emitProvinceId);
  selectLazyRef.value.visible = false;
}

</script>


最终

自然, 这类并不是最佳方案, 确能迅速高效的解决问题;