I have installed, "vuedraggable": "^4.1.0",
Works very well, and orders well, but inputs lost focus on any keypress action with v-model.
The problem is definitely with vuedraggable and v-model.
<draggable
:list="widgets"
item-key="name"
class="list-group"
ghost-class="ghost"
#update="saveUpdatedOrder"
>
....
<el-input
v-model="element.name"
class="add-new-item__title"
placeholder="Title"></el-input>
When I want to change element.name value, this input loses focus, so after every character I need to touch input again and put focus on him, to be able to continue charging text.
Any idea?
This is probably caused because you use the element.name in the input field and as the key for vue-draggable. Since vue is keeping track of DOM-elements by its key in a v-for loop, I think changing the name will make vue to delete the DOM element and create a new one, with the new key as identifier. That is why it looks like the input is loosing focus, while it actually is another input element.
Changing item-key="name" to another unique property of the widget object, like title or id, will solve the problem. Since you did not provide the widgets array, I cannot be clear on what would be a usable property.
Related
I still don't quite get the use of keys even after reading through the docs but I understand that it has to do with keeping each item unique. I've been solely adding a key when using a v-for and only to the outer most parent (not the children of the v-for. Are there any other situations when keys should be used?
<div v-for="(person,index) in people" :key="index>
<div class="name-label>
<img :src="person.img/>
<div> {{ person.name }} </div>
</div>
</div>
The key directive alongside v-for, is used to uniquely identify each parent element rendered on the v-for operation.
The same happens in Reactjs:
{elements.map((value, index) => {
return <li key={index}>{value}</li>
})}
The key directive in Vuejs is also used to force Vuejs to re-render an element that contains it every time :key receives a new value.
As #firmino-changani indicated, other uses of key is if you want Vue to force a re-render or replacement of an element or component. See key special attribute documentation:
It can also be used to force replacement of an element/component
instead of reusing it. This can be useful when you want to:
Properly trigger lifecycle hooks of a component
Trigger transitions For example:
<transition>
<span :key="text">{{ text }}</span>
</transition>
When text changes, the <span> will always be replaced instead of patched, so a transition will be triggered.
Another example, lets say you have a dialog popup to add new data and another component that needs updating once the new data was entered via the popup. This second component might have logic inside lifecycle hooks like onMounted etc. Using a :key you can force re-rending this component once the dialog popup is saved e.g.
<template>
<page>
<add-data-popup #save="myKey++" />
<show-data :key"myKey" />
</page>
</template>
From the vueJs docs around Keys:
The key special attribute is primarily used as a hint for Vue’s virtual DOM algorithm to identify VNodes when diffing the new list of nodes against the old list.
To simply put it, if a div is rendered via a For-loop the div will be identical to each other div. When a user clicks on one of these Div's and you instantiate a #click function, how will vueJs know what differentiates each of these divs? How will vue know how to reorder these div's in the correct order if you remove a middle div?
VueJs uses the key to know how to reorder the DOM when an action is taken on one of these objects in your For loop.
Here is an article fully explaining about vueJs keys, and more details on the VueJS reactivity engine which is good to know about: https://www.telerik.com/blogs/in-vue-when-do-i-actually-need-the-key-attribute-and-why
I am getting strange behaviour when trying to dynamically update the content of a slot in Vue with Vuetify. I'm sure this is just a function of misunderstanding how slots work.
I have a slot in a custom component, like so:
<template #selectButtons="slotProps">
<v-icon #click="dropToggle(slotProps.player)"
:color="dropColor(slotProps.player)"
class="mr-5"
>
fas fa-skull-crossbones
</v-icon>
</template>
When the user clicks on the icon, it is meant to toggle the icon to different colors.
I cannot seem to get dropColor to fire on each click consistently, HOWEVER, the weird part is, if I make some change inside the <v-icon> component, like say I just add {{dropColor(slotProps.player)}} inside the v-icon tags, then all of a sudden the code will work.
But then if I do a full refresh of the page, it stops working. Then I delete that code and put it back in, then it works again!
I have tried forceUpdate and keys on the v-icon tag.
Would appreciate any help
You are trying to pass function dropColor(slotProps.player) as props. The better idea is to replace function to an object or variable and change that object/variable within method dropToggle(slotProps.player) after #click event is firing .
I have a prismic group (link_sections) containing a bunch of fields. One of the fields is a link, because the markup I am creating with these groups is supposed to contain a button that links elsewhere on the site. The problem is that I don't know how to use prismic links properly in this context because as far as I can tell it is not possible to bind the link data inside of a v-btn like so...
<v-layout v-for="(section, index) in fields.link_sections" :key="index">
<h2>{{section.header}}</h2>
<v-btn router-link :to="{{section.link}}"></v-btn>
</v-layout>
If I just render out {{section.link}} outside of the v-btn element I can render out the text value of the link successfully, but that's about as much as I can do and obviously I want to use the text as an actual link. Anyone know how I can make a link field from a prismic group work with a v-btn element?
Your syntax is wrong, try this snippet:
<v-btn :to="section.link">Link</v-btn>. Also <b-btn></v-btn> has not router-link prop. Just pass prop to. If you pass to prop, it implies that you want that button to be a <router-link>
Denotes the target route of the link.
I have been trying and investigating about disabling the form by default.
<v-form ref="form" v-model="valid" lazy-validation>
<v-select v-model="test" :items="data" :disabled="status"></v- select>
<v-text-field v-model="name" :disabled="status"></v-text-field>
</v-form>
I don't see any disable prop to the v-form. So i am just adding disabled prop to each and every input field to solve this problem. Like Angular adding disable prop to <fieldset> tag or to the form looks simple, is there any thing available in vuetify? any other approach to do this?
I have looked into this my self, made my own form that extends VForm and tried making a disabled directive for it (v-disabled="isDisabled").
Unfortunately at the moment without the knowledge and time to extend all of the components and buttons in question, what you are currently doing is the only way or else you get the mutating prop warning on setting disabled directly with an iterator and trying to set isDisabled will throw an "has no setter method error".
Vuetify needs to update the input and button components to allow pragmatic changes to the disabled property.
Having to set :disabled on each element isn't really that drastic but yes I agree that from the parent form it would be nice to have.
I'm still pretty new to vue.js.
I recently created some vue components to tidy up my html. The components are different inputs like text and checkbox. They update the parents data using $emit('input', val). And make sure that the components are up-to-date using props and watch() on those props.
Now there is a problem with using watch() on <input type="file />, since you cannot set the input value like you can on other input types.
Using this example:
https://jsfiddle.net/minde281/nyu73dz6/25/
I have a list of, in this case, items on a shoppinglist. You can add an image for each item.
The image is loaded and added to the list. This works fine.
To get my problem:
add an image to item1
delete that item by clicking the X-button
The result is now that item2 will have that image on the <input type="file" />. The preview works as expected since this can be set through script and therefore use watch(). But somehow vue removes the wrong part of the html markup causing the last one to be removed.
Is there a different way to solve this problem? Or is there a way to tell vue to remove the correct part of the html markup?
-Minde
Vue tries to reuse the component and thats why the selected file is in the second input after deleting the component.
To prevent that you should use the key binding like this:
<li v-for="(item, index) in items" :key="item.name">
Now the hole component gets removed and everything should work as expected.