I am using element ui tree with lazy load.
I am trying to set default nodes expanded.
But seems lazy loading and expanded are not working together.
<el-tree :data="DocumentField" class="fullHeight" lazy :load="loadNode" :default-expanded-keys="[0]">
Following is the reproduction of the same.
https://codepen.io/anon/pen/oRQXxQ?editors=1010
So is it possible to keep default node expanded and lazy loading work only with non expanded nodes?
You need to set node-key to make it work
<el-tree
:props="props"
:load="loadNode"
:default-expanded-keys="[2, 3]"
lazy
node-key="id"
show-checkbox>
</el-tree>
Demo on codepen
Related
I have the following component:
<transition name='component-fade' mode='out-in'>
<component
:is='marketType'
:key='market.id'
:market='market'
:match='market.match'
/>
</transition>
I'm noticing the transition works well the marketType has changed, fully changing from different components. However, it is not working when the component doesn't change, but the key does. Vue seems to be instantly replacing it to be efficient, and ignores the fact that the key has changed.
The docs show an example of transition between dynamic components but they don't have examples of both a dynamic component swap + using a key at the same time.
I need the transition to activate when the data changes, regardless of whether the same type of component rendered.
How can I accomplish this?
Yes, this old chestnut.
I'm making an editor for a large object tree, and it seemed sensible to make components for each of the property types at a vertex in the tree in order to remove clutter from the main component. However, this has created the problem that the main JSON object isn't being updated beause the editor is implemented in child components (#Input).
Using #Output and EventEmitter seems infeasible because:
how on earth do you get a component to call the emitter very time a change is made to the data it's editing, and
it seems really stupid to have to write an update function to handle the event because the UI should be just automatically bound to the JSON object it's editing -- that's the point of this observable malarkey.
The only solution I can think of is to not use components and just wirte a massive monolithic editor.
Is there a better way?
The way you describe is pretty standard. An alternative though would be to use a template # variable to access your child properties.
<hello #childcomponent name="{{ name }}"></hello>
<div>
{{ childcomponent.name }} - Parent component
</div>
You can use this to access your child component through the typescript as well.
#ViewChild('childcomponent') childcomponent;
Stackblitz
I have a div tag with an 'id="meet"' into v-tabs.
I need to access the node of this tag after I click a tab. I am using
let node=document.querySelector("#meet").
My problem is that it always returns "null". Here is the codepen: https://codepen.io/luizalves/pen/WNrepxz
What is wrong here?
There is no guarantee that after $nextTick you will see DOM element immediately.
<div id="meet"></div>
<button #click="onTest">test</button>
...
methods: {
onTest () {
let node=document.querySelector("#meet");
console.log('meet here',node)
},
After you clicked test you'll see in a console:
"meet here" "<div id='meet'></div>"
You can try to extract this div with an unique id into a separate component and inside it you can use mounted hook to know that it exists in DOM
Of course, according to vuetify docs, you may add eager prop to v-tab-item component, and that's it, but...possibly you are doing something wrong.
It's not a good idea to always add this prop because you are losing one of the vuetify 2.X advantages - lazy loading. This may lead to big performance problems if there are many elements on the tab.
Maybe it would be better if you will work directly with reactive variables (like variables in v-model directive), not DOM objects.
I’m using Vue & Vuetify to create my app. With vuetify I’m using v-expansion-panels to create an accordion style display. Each v-expansion-panel itself contains a custom component.
I have noticed these components are not created until the expansion panel is clicked for the first time. After that, using keep-alive allows all reactive properties and methods of the child component to be active (this is my desired behavior).
How can I force the child components to be created when the parent is created? This, any method triggered in the created() lifecycle hook of a child component should fire when the parent is created.
This Codepen is an example of the current behavior. Note: be sure to look at the console when you click the panel.
If you think about it, it actually makes sense to lazy load content of expansion panels since it is useless work if the user never opens them anyway. So probably the thing you try to accomplish has some better approach, but if you still like it then my advice is to find a way of programatically opening / closing the panel (as seen here) and quickly open it and close it when rendering parent component. In this way, you will have your child component created and the UI will remain the same.
A Vuetify solution should be achievable by adding the eager prop to a v-expansion-panel-content element in the Expansion Panel. This should force any components or content contained within the v-expansion-panel-content element to render on mounted.
<v-expansion-panels v-model="panels">
<v-expansion-panel>
<v-expansion-panel-content eager>
<custom-component />
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
I have to code a web application and the most important element is the q-tree. I'm already able to load and show data (passing an array called list), but I want that all nodes are expanded.
The vue.js examples of the official documentation show that you're be able to do this with the 'default-expand-all' attribute but this isn't working for me.
It only shows me the root node with an arrow, where I have to expand the children nodes manually.
<q-tree
:nodes="list"
:selected.sync="selected"
#update:selected="onSelectionChangedNode"
node-key="NodeNr"
label-key="NodeTxt"
default-expand-all
></q-tree>
Taking a cue from the accepted answer, I realised that the dom has already been created with the tree component on first render.
In my use case, I want to update the Tree when data comes back from the server.
So, I had to force it to re-render with the expanded functionality using:
this.$nextTick(function () {
this.$refs.nodes.expandAll();
})
The nextTick function will update the dom in the next window of execution, by which time the nodes will get expanded by calling the expandAll function.
And NB: For those confused by the astericks on the ref attribute or how to add it to the component, here goes:
<q-tree :nodes="list"
:selected.sync="selected"
#update:selected="onSelectionChangedNode"
node-key="NodeNr"
label-key="NodeTxt"
ref="nodes"
>
Solved my problem as following:
I have added a ref attribute to the QTree DOM Element which makes it possible to access predefined methods of QTree API.
<q-tree
:nodes="list"
:selected.sync="selected"
#update:selected="onSelectionChangedNode"
node-key="NodeNr"
label-key="NodeTxt"
**ref="nodes"**
>
The function I have been using is expandAll().
updated() {
this.$refs.nodes.expandAll();
}
The most important thing for me was, I had to find out which lifecycle hook was the right one for me. The update() hook was the one I was looking for.
The reason:
Called after a data change causes the virtual DOM to be re-rendered and
patched.
The component’s DOM will have been updated when this hook is called, so you
can perform DOM-dependent operations here.
The default-expand-all is only applied on the first rendering of that Component.
So if your Component renders when the nodes aren't assigned they wont expand if assigned afterwards.
https://v1.quasar-framework.org/vue-components/tree
You have to work with scoped slots and an expanded attribute if you dont have the nodes on first rendering.