CityCascader.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <template>
  2. <el-cascader
  3. :key="cascaderKey"
  4. v-model="internalValue"
  5. placeholder="请选择地址.."
  6. :props="SearchCityData"
  7. filterable
  8. clearable
  9. @change="handleChange">
  10. </el-cascader>
  11. </template>
  12. <script>
  13. export default {
  14. props: {
  15. value: { // 接收外部传递的 v-model 值
  16. type: [Array, String], // 允许传入数组或字符串类型的数据
  17. default: () => [],
  18. },
  19. },
  20. data() {
  21. let self = this;
  22. return {
  23. internalValue: [], // 用于与级联选择器进行双向绑定的内部数据
  24. cascaderKey: 0, // 用于强制刷新 cascader
  25. SearchCityData: {
  26. checkStrictly: true,
  27. lazy: true,
  28. async lazyLoad(node, resolve) {
  29. const { level, data } = node;
  30. let parentId = level == 0 ? 0 : data.value;
  31. let parames = {
  32. pid: parentId,
  33. };
  34. self.$store
  35. .dispatch("pool/getcityList", parames)
  36. .then((res) => {
  37. if (res.data) {
  38. const nodes = res.data.map((item) => ({
  39. value: item.id,
  40. label: item.name,
  41. leaf: level >= 3,
  42. children: [],
  43. }));
  44. resolve(nodes);
  45. }
  46. })
  47. .catch(() => {
  48. this.$message({
  49. type: "info",
  50. message: "网络错误,请重试!",
  51. });
  52. });
  53. },
  54. },
  55. };
  56. },
  57. watch: {
  58. value: {
  59. immediate: true, // 组件挂载时立即执行
  60. handler(newVal) {
  61. try {
  62. const parsedValue = Array.isArray(newVal) ? newVal : JSON.parse(newVal);
  63. this.internalValue = parsedValue; // 设置内部值
  64. if (parsedValue.length) {
  65. this.loadCascaderPath(parsedValue); // 动态加载回显的路径
  66. }
  67. } catch (error) {
  68. console.error("无法解析传入的值:", error);
  69. this.internalValue = []; // 如果解析失败,重置为默认空数组
  70. }
  71. },
  72. },
  73. },
  74. methods: {
  75. handleChange(value) {
  76. // 当选择变化时,向父组件发送更新的值
  77. this.$emit("input", value); // v-model 双向绑定
  78. this.$emit("update-city-id", value); // 额外事件,方便父组件监听
  79. },
  80. async loadCascaderPath(path) {
  81. for (let i = 0; i < path.length; i++) {
  82. const parentId = path[i - 1] || 0; // 获取当前层级的父级ID
  83. const level = i; // 当前层级的索引
  84. await this.$store.dispatch('pool/getcityList', { pid: parentId })
  85. .then((res) => {
  86. const nodes = res.data.map(item => ({
  87. value: item.id,
  88. label: item.name,
  89. leaf: level >= 3, // 假设4层结构,设置叶子节点标记
  90. }));
  91. // 级联选择器加载数据
  92. if (level === path.length - 1) {
  93. this.internalValue = path; // 确保最后一级路径正确设置
  94. this.cascaderKey += 1; // 强制刷新 cascader
  95. }
  96. });
  97. }
  98. },
  99. },
  100. };
  101. </script>
  102. <style scoped>
  103. /* 可根据需要自定义样式 */
  104. </style>