Use VueJS Variable inside html2-pdf - vue.js

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.

Related

Adding vue.js to attribute src

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"/>

How to use `v-if` and `v-for` on the same element?

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>

Vue.js SFC conditionally include template elements at compile time

Our product has multiple customers, and each have their own customer-specific modifications.
Is there a way in a Vue2 template of an SFC to conditionally include or exclude other components at the time it's built, based on a build environment variable?
It looks like I can use something like webpack-conditional-loader to conditionally include/exclude JavaScript code at build-time, but is there an equivalent for the template code?
eg. something like this:
<template>
<##if process.env === 'CustomerA'>
<customer-a-dialog></customer-a-dialog>
</##if>
<##if process.env === 'CustomerB'>
<customer-b-dialog></customer-b-dialog>
</##if>
</template>
Thanks,
Spanners
you can use the following library which can allow conditional preprocessing for html/vue template code:
js-conditional-compile-loader
Hope it helps!

Conditionally Add Attribute

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.

Aurelia not outputting attribute with string interpolation in repeat

Is there any reason why a repeat.for binding would remove attributes from elements inside the repeater?
<div repeat.for="i of model.someArray.length">
<label>Some Array - Index ${i + 1}</label>
<input value.bind="model.someArray[i]" some-custom-attribute="someArray[${i}]"/>
</div>
and that some-custom-attribute is not being output within the repeat, but if I were to remove the string interpolation within there then it outputs fine.
== Edit ==
I have put it in a comment but just to make sure everyone is on the same page, ideally this is the output I expect:
<input value.bind="model.someArray[i]" some-custom-attribute="someArray[0]"/>
The some-custom-attribute is not an aurelia attribute, its pure HTML that a 3rd party JS library uses, so the goal here is to get the textual value of the index into the textual attribute value.
model.someArray.length is a number, not an array. You need to iterate over the array. If you do need the current index, the repeater provides the $index property for you to use.
Your code should look like this:
<div repeat.for="item of model.someArray">
<label>Some Array - Index ${$index + 1}</label>
<input value.bind="item" some-custom-attribute.bind="item"/>
</div>
To answer your original question, doing some-custom-attribute="model.someArray[${i}]" makes Aurelia think you are trying to pass a string value to the custom attribute. You can see that in the following gist: https://gist.run/?id=eed8ac8623ff4749aa5bb93c82a7b1fb I've created a custom element that just pushes whatever value it is given in to an element on the page. Note!!! Don't ever do what I'm doing here! I just did this this way so you wouldn't have to open the js console. To actually get a value passed in, you would need to use some-custom-attribute.bind="item" or (to do things how you are doing things, some-custom-attribute.bind="someArray[i]"