I was trying to add the attribute src with vue.js to the img tag:
<img v-bind:src="{object.url}"/>
But for some reason the image is not loading.
Vue's syntax is unlike React's where you use {object.url} a lot.
In Vue, this is like this directly
<img :src="object.url" />
In a Vue template, a colon : prefixing an html attribute is a shorthand for v-bind. This allows you to use variables, computed etc. as attribute value instead of static values.
What you are trying is a react way which replace quotes around the attribute value with curly braces. But in Vue you can directly bind the variables without using curly braces.
Hence, It should be :
<img :src="object.url"/>
Related
I'm having trouble trying to use the Vue.Draggable library. I would like to use a component inside my draggable while keeping the transition-group. It's working without the transition group but whenever Im adding the transition-group tag with the animation name its not working anymore. My components elements are not showing up and I'm having this error :
TypeError: Cannot set properties of null (setting '__draggable_context')
Here is my code :
<draggable :list="teams" item-key="idteam" tag="transition-group" :component-data="{name:'fade'}>
<template #item="{ element, index }">
<my-team :id="element.idteam" :name="element.teamName" :index="index">
</my-team
></template>
</draggable>
Any idea how could I make all work together ?
Thanks for your help
You need to add :animation="200"; only adding tag="transition-group" is not enough.
Hi I'm trying to figure out how to use v-if on a iterated element which also uses v-for. I need to check if the current element has any of a series of classes, which are numbers.
so the classes of each article would be:
<article class="post-item post-guide 12 22 19 30 55">...
this is the HTML that renders all:
<article v-if="showIfHasClass" :class="'post-item post-guide ' + guide.categories.toString().replace(/,/g, ' ')"
v-for="(guide, index) in guides" :key="index">
<header>
<h1 class="post-title">
{{ guide.title.rendered}}
</h1>
</header>
</article>
I have tried with methods that check the class of all elements, that works, but i'm trying to use a clean Vue built-in solution with v-if without success, i'm not able to retrieve the class of this in a successful way.
Should showIfHasClass be a computed property? I have tried with that too... but it seems, I'm missing something along the way.
my data I have to check against is an array:
data:{
guides: [...]
selectedCategories: [1, 22, 33, 100, 30];
}
or maybe it is better to directly loop over the guides and check if they have the selectedCategory or not, then remove the element from the guides data array?
What is more effective?
Besides the option to create an additional filtered computed (effectively eliminating the need to use v-for and v-if on the same element), you also have a template level way of dealing with such edge-cases: the <template> tag.
The <template> tag allows you to use arbitrary template logic without actually rendering an extra element. Just remember that, because it doesn't render any element, you have to place the keys from the v-for on the actual elements, like this:
<template v-for="(guide, index) in guides">
<article v-if="isGuideVisible(guide)"
:key="index"
class="post-item post-guide"
:class="[guide.categories.toString().replace(/,/g, ' ')]">
<header>
<h1 v-text="guide.title.rendered" />
</header>
</article>
</template>
isGuideVisible should be a method returning whether the item is rendered, so you don't have to write that logic inside your markup. One advantage of this method is that you can follow your v-if element with a fallback v-else element, should you want to replace the missing items with fallback content. Just remember to also :key="index" the fallback element as well.
Apart from the above use-case, <template> tags come in handy when rendering additional wrapper elements is not an option (would result in invalid HTML markup) (i.e: table > tr > td relations or ol/ul > li relations).
It's mentioned here as "invisible wrapper", but it doesn't have a dedicated section in the docs.
Side note: since you haven't actually shown what's inside guide.categories, I can't advise on it, but there's probably a cleaner way to deal with it than .toString().replace(). If guide.categories is an array of strings, you could simply go: :class="guide.categories".
I think the most Vue way is to create a computed property with filtered items from selected categories, then use that in v-for loop (the idea is to move the business logic away from template).
computed: {
filteredItems(){
return this.guides.filter(e => this.selectedCategories.includes(e.category))
}
}
Also, as a note, it is not recommended to use v-if and v-for on the same element, as it may interfere with the rendering and ordering of loop elements. If you don't want to add another level of nesting, you can loop on a 'template' element.
<template v-for="item in items">
// Note the key is defined on real element, and not on template
<item-element v-if='condition' :key="item.key"></item-element>
</template>
i have use html2-pdf in VueJS project in terms of generate pdf file from HTML.
My problem is, is there way to use VueJS variable like {{ variableName }} inside tag <section slot="pdf-content"> ?
Because i have tried but it not print out the value of the variableName. Is there any way to use variable inside the tag of html2-pdf?
Thank you so much.
Is it possible to conditionally add an attribute to an element using binding syntax? I am aware of if.bind, but that targets elements. Rather I am interested in targeting a specific attribute on an element.
Example:
<a href.bind="model.link">${model.text}</a>
If model.link is falsy, then I don't want the href at all--just treat the <a /> as a container element.
I realize I could create two <a /> tags--one with the attribute and one without--and use an if.bind on both, but that seem clunky and un-aurelia like.
I don't think it's supported in Aurelia currently (issue 1, issue 2)
This,
<a href.bind="addLink ? link : ''">Link</a>.
will produce
<a href>Link</a>
if addLink is false.
It won't remove the attribute entirely. If you are using a library which will check the existence of an attribute to manipulate the element, then this won't work. Another option would be to create a custom attribute like this. But that seems like an overhead.
Supposed I have the following html only element:
<template bindable='value: Math.random()'>
${value}
</template>
<!-- In another component {Main} -->
<template>
<require from='./that-element'></require>
<that-element></that-element>
</template>
The result is an empty string in main component. The question is how can I define a default value for html only element?
EDIT: Default value for element will not work if an 2 bindings need to have the same unique default value. I can make it unique myself but then I have to do it manually. Was looking for something like Math.random()
The contents of bindable attribute on <template> tag is handled as comma-separated list of strings. Therefore, you won't be able to set default values there.
I can think of two approaches:
Set default values in parent viewmodel class and use explicit binding. Considering above scenario, this will work for you.
<that-element value.bind="someVarFromParent"></that-element>
In some really simple cases, when default value should be a static string, you can use JavaScript expressions within an interpolation.
${value || 'default value'}
Gist demo: https://gist.run/?id=f0698d5b0066c3674c29c40d850217dc
Just putting my 2 cents in here...I think Marton nailed it on the head with the html only solution. I generally use the value.bind method because I usually always have a vm along with my view. So, to simplify JayDi's response (which is a valid response), I've created a GistRun for you.
Basically, you'll create a custom-elem html file and a custom-elem js file. In the html file, you would have something like this:
<template>
<h1>${value}</h1>
</template>
and in the js file, you'd have something like this:
import {bindable} from "aurelia-framework";
export class CustomElem {
#bindable value = "default value";
}
Finally, you'd just require it in your main parent file like so:
<template>
<require from="./custom-elem"></require>
<custom-elem></custom-elem>
<custom-elem value.bind="'myVal'"></custom-elem>
</template>
I just added a default value for the custom element. You can leave it undefined if you'd like. Also, you can add as many properties as you would like. This is the simplest way to tackle this in my opinion, unless your situation lets you get by with the html only method.
Also, in this case, I'm using a string of "myVal". If you wanted to use a variable that you have in your parent vm, you would just take the single quotes off and use that variable name.
Here's the running Gist so that you can fool around with it:
https://gist.run/?id=2eb14ecd2b0b859fd5d1a33b5ee229bd
You can use || statement in html-only element for default value:
<template bindable="param1, param2, param3">
<h1>${param1 || 'default 1'}</h1>
<h2>${param2 || 'default 2'}</h2>
<h3>${param3 || 'default 3'}</h3>
</template>