Similar to SELECT, the optional data structure is a tree structure, such as company level, province, region, etc. I used the company’s department tree structure as an example.

Antd TreeSelect official documentation: antdv.com/components/…

The Antd TreeSelect tree selection controls are encapsulated twice, and the basics of encapsulation are explained, such as vm.$attrs, model binding, vm.$Listeners, etc

Reasons for encapsulation: Before, the department tree data was loaded at one time, which had performance problems. When there was a large amount of data, the loading was very slow, and the components might crash. Therefore, we need to change the asynchronous loading data, but the system is used in many places, it is impossible to change a place a place, so encapsulate, unified processing.

Based on using

  1. Open the search box and setshowSearch;
  2. Filter search questions: to combinetreeNodeFilterPropYes, the default isvalue, generally need to be changedtitle
  3. Scroll positioning problem: The default is to follow the body positioning, scrolling will occur dislocation phenomenon, need to setgetPopupContainerTo deal with
  4. Drop-down box style Settings: availabledropdownStyleNotice that values are passed as objects
<a-tree-select
  ref="departIds"
  placeholder="Please select"
  searchPlaceholder="Please enter department name"
  :treeDefaultExpandAll="true"
  v-model="departIds"
  :treeData="departs"
  :dropdownStyle="{ maxHeight: '400px' }"
  show-search
  treeNodeFilterProp="title"
  :getPopupContainer="(triggerNode) => triggerNode.parentNode"
>
</a-tree-select>
Copy the code

Realization effect display:

Secondary packaging

It’s just a simple wrapper that handles some properties in a uniform way, so you don’t have to write the same thing every time. In a management background system, the use of components is roughly the same, packaging the use of more elegant, more convenient for later expansion, can be unified processing, there is no need to change every place.

(1) Sub-component Departtreeselect.vue

<template>
  <a-tree-select
    v-bind="$attrs"
    placeholder="Please select"
    searchPlaceholder="Please enter department name"
    :treeDefaultExpandAll="true"
    :treeData="departSource"
    :dropdownStyle="{ maxHeight: '400px' }"
    show-search
    treeNodeFilterProp="title"
    :getPopupContainer="(triggerNode) => triggerNode.parentNode"
    @select="handleSelect"
  >
  </a-tree-select>
</template>

<script>
  export default {
    props: {
      departSource: {
        type: Array.default: [].}},model: {
      prop: "value".event: "select",},methods: {
      handleSelect(selectedKeys) {
        this.$emit("change", selectedKeys); ,}}};</script>

<style lang="scss" scoped></style>
Copy the code

(2) Parent component call

<departTreeSelect :depart-source="departs" v-model="departIds" />
Copy the code

Principle of encapsulation

attribute$attrs

Vm.$attrs official documentation: cn.vuejs.org/v2/api/#vm-…

– Contains attribute bindings (except class and style) that are not recognized (and retrieved) as prop in the parent scope

$attrs (foo=” XXX “, v-bind=”{value: 12}”, v-bind=”{value: 12}”); The object received by the quilt component props will be placed in $props of the child component

$attrs = {value: “”}; $attrs = {value: “”}; $attrs =” departSource”; $attrs =” departSource”; $attrs =” departSource”;

Two-way bindingmodel

Model official documentation: cn.vuejs.org/v2/api/#mod…

Official explanation: Allows a custom component to customize prop and Event when using the V-Model. By default, a V-Model on a component uses value as prop and input as event.

Example: As shown above, I define value and SELECT; DepartId =”departIds”; v-model=”$attrs.departId”;

// Parent component call<departTreeSelect :departSource="departments" :departId="baseInfo.departIds" />/ / child component<template>
  <a-tree-select
    v-bind="$attrs"// Notice herev-model="$attrs.departId"
    :treeData="$attrs.departSource"
  >
  </a-tree-select>
</template>

<script>
  export default {
    model: {
      prop: "departId".event: "change",},methods: {
      handleSelect(selectedKeys) {
        // The callback must correspond to 'model.event'
        this.$emit("change", selectedKeys); ,}}};</script>
Copy the code

The listener$listeners

Official documentation: cn.vuejs.org/v2/api/#vm-…

A V-ON event listener that contains a parent scope (without the.native modifier).

The parent component mounts event listeners to the child component with @eventName=”fn” or V-ON :eventName=”fn”. For child components, the events that the parent listens for are stored in $Listeners.

Example: In the previous two-way binding, the event callback is @SELECT =handleSelect, can be replaced with the following method, the principle is the same.

<template>
  <a-tree-select v-on="treeListeners"> </a-tree-select>
</template>

<script>
  export default {
    computed: {
      treeListeners() {
        var vm = this;
        return Object.assign(
          // Mount the parent component for all its own events
          this.$listeners,
          // Add custom listeners, or overwrite the behavior of some listeners
          {
            // Make sure the component works with 'V-model'
            select: function(event) {
              vm.$emit("select", event); }}); ,}}};</script>
Copy the code