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
- Open the search box and set
showSearch
; - Filter search questions: to combine
treeNodeFilterProp
Yes, the default isvalue
, generally need to be changedtitle
- Scroll positioning problem: The default is to follow the body positioning, scrolling will occur dislocation phenomenon, need to set
getPopupContainer
To deal with - Drop-down box style Settings: available
dropdownStyle
Notice 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