I haven't written a blog for a long time, and I happened to encounter a difficult problem last week. Let's record it here.
Environment: Vue3.2, Element Plus
Problem: Subcomponent => Pop-up Component Dialog => Tree Select component el-tree-select, the default selection cannot be set default-checked-keys
Scenario: On the list page of a background system, select a row of data, click the Settings button, and assign some functions. The method here is to encapsulate the settings page in a subcomponent, and the subcomponent uses the Dialog component of Element Plus
Then there is an el-tree-select in the Dialog that needs to be initialized, because it may have been allocated before allocation, and the reverse selection needs to be set
At the beginning, I wrote it directly, as follows:
<template> <el-tree-select
:data="store().UserMenus"
:default-expanded-keys="['xxxxxxxx']" /> </template>
Then I found that it does not take effect. On Friday, I can also guess the reason. The value in the global state of pinia bound by data may not be loaded when the component is instantiated. Therefore, when default-expanded-keys is set, it cannot find the node data. After the component is created, the data has a value, but default-expanded-keys will not be reset again, which causes the component to have pull-down data, but there is no anti-select effect.
At first I thought it was a simple question, so I used my mind. Since it was related to the order, it naturally took into account the life cycle, so I added onMounted and reassigned the value here:
// script ts const list = ref() const selectArr = ref<string[]>([]) onMounted(() => { = store().UserMenus = ['xxxxxxxx'] }) // <template> <el-tree-select :data="list" :default-expanded-keys="selectArr" /> </template>
data binds the variable list, default-expanded-keys binds selectArr. Well, I thought it was OK, but I still failed to reverse the election. Just... outrageous ~
Normally, the onMounted function has been created by the component and the Dom is created. At this time, I should be able to set the value of the list and then set selectArr. But in fact, the election was not successful.
This shows that there is still a problem with loading. With a research attitude, I remembered another method. I can set its default value through the method by calling the el-tree-select API, which is the setCheckedKeys method!
Through the template reference, get el-tree-select, name it tree, and then return to onMounted to print: (), good guy, it is actually an undefined, which means that the selected keys cannot be set at all in onMounted. Then strangely, when I repeatedly modify the code, due to hot reloading, the Vue page will be updated and it can be selected instead! But as soon as I refreshed, the anti-select was immediately invalid. enmmmm ..... can basically locate the problem. OnMounted cannot get the component. I later interviewed onUnmounted. This is OK, but I am initializing logic and it is impossible to write it in onUnmounted.
There is another factor here that causes this problem, that is, Dialog is not displayed by default, and the display is hidden through the variable bound by v-model="dialogVisible". The initialization value of false is also a reason for failure. If I set = true at the beginning, then the reverse selection is OK, but I still cannot set it to true, so there is no pop-up window displayed from the beginning.
I was basically stuck in this place on Friday afternoon. After emptiing myself on the weekend (Canyon Timi), I reviewed it on the way to work on Monday morning, and considered looking for the answer from Dialog itself. Hey, sure enough, there is an opened method in its API. Dialog opens the callback at the end of the animation. I initialize it here, and the problem was solved:
// Dialog @opened="opened" // script ts const opened = () => { = ['xxxxxxxx'] }
Another reason why I found this idea is that I also tried the form. The form object could be obtained in the form submission event before, and then I tried whether it could be obtained in onMounted. The result was similar. Put a button and you can get the component in the button click event, because when you can click the button, everything on the page has been loaded. Similarly, in the callback at the end of the Dialog opening animation, the page must have been loaded long ago and all the values should be available. Then, there will be no problem of not finding the key when initializing at this time.
// Dialog @opened="opened" // script ts const opened = () => { = ['xxxxxxxx'] }
This problem seems simple, and finally opened method is solved, but it actually tests Vue's skills, when the components are created, when the data is loaded, the data linkage and order between each attribute. If you write a fixed value and put it in data and keys, there is definitely no problem. Element Plus official documents have a lot of cases that can be taken directly. However, in actual project development, multiple technical points are often combined together, and you basically cannot write the value of a drop-down box to death. Maybe you took the value from pinia like me, maybe the data you read through axios may be other ways, but you will encounter some when there are some inconsistent expectations. Therefore, I will share this case here and make a record. If someone encounters similar problems, you can refer to one or two. If there is a better solution, you can also propose it to communicate together.
This is the article about the analysis of the problem of unselecting anti-select in Vue3. This is all about this. For more related content about Vue3, please search for my previous articles or continue to browse the related articles below. I hope everyone will support me in the future!