element级联二次封装一个省市区组件

记录二次封装 element 的备忘点

v-model 绑定输入值,在template 中属性使用 v-model, v-model 使用的值可以是 computed 来接收值,如果是需要往上级 emit 数据变化的,要在 computed 中的设置 get()、set()

级联无法在封装的组件 v-model 的值改变后反显失败,这里查看了组件源码后发现,这个地方是在渲染的时候绑定了缓存的值,所以要给 el-cascader 添加 key 来让组件能够反显渲染

省市区组件代码

<template>
  <div class="city-container">
    <el-cascader
      :key="cascaderKey"
      ref="city"
      v-model="values"
      :props="cAttrs"
      separator="-"
      clearable
      width="100%"
      :options="options"
      @change="handleChangeValue"
    />
  </div>
</template>
<script>
import dictApi from "../server/dictApi";
export default {
  name: "City",
  props: {
    value: {
      type: Array,
      default() {
        return [];
      },
    },
    attrs: {
      type: Object,
      default() {
        return {};
      },
    },
    options: {
      type: Array,
      default() {
        return [];
      },
    },
    level: {
      type: Number,
      default: 2,
      required: false,
    },
  },
  data() {
    return {
      cascaderKey: 0,
    };
  },
  computed: {
    cAttrs() {
      return Object.assign(
        {
          value: "cityCode",
          label: "name",
          lazy: true,
          lazyLoad: (node, resolve) => {
            const { level, value } = node;
            dictApi
              .getCityData({ level: level + 1, parentCode: value || 0 })
              .then(
                (data) => {
                  data.map((item) => {
                    item.leaf = level >= this.level;
                    return item;
                  });
                  resolve(data);
                },
                (err) => {
                  this.$message.warning(err);
                }
              );
          },
        },
        this.attrs
      );
    },
    values: {
      get() {
        return this.value.map((item) => {
          return item;
        });
      },
      set(val) {
        this.$emit("input", val);
      },
    },
  },
  watch: {
    value() {
      this.cascaderKey++;
    },
  },
  methods: {
    handleChangeValue(val) {
      let selectedLabels =
        this.$refs.city.getCheckedNodes() !== undefined &&
        this.$refs.city.getCheckedNodes().length > 0 &&
        this.$refs.city.getCheckedNodes()[0].pathLabels;
      this.$emit("change", val, selectedLabels);
      this.$emit("input", val);
    },
  },
};
</script>

扩展 render 的写法继承 element 组件所有的属性和事件

有时候封装组件是为了组件的一致性限制了组件的属性,有时候需要实现不同的业务需求的时候,又需要用到 element 组件的属性或事件,这种情况就最好把属性都继承过来传递给 element 的原生组件中。

export default {
  render() {
    return (
      <el-input
        vModel={this.model}
        {...{
          attrs: this.$attrs,
          on: this.$listeners,
        }}
        clearable
      ></el-input>
    );
  },
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值