VueJS Evaluating on Escaped Characters - vue.js

I've run into a bit of an issue when running VueJS. It feels like it is a bug, but I'm not 100% sure. When I have HTML with escaped double curly braces, it still gets evaluated by the engine.
https://jsfiddle.net/judda/ge042znc/1/
HTML:
<body>
<div id="body">
<ul>
<li v-for="bar in foo">{{ bar }}</li>
</ul>
{{ foo }}
</div>
</body>
JavaScript:
new Vue({
data: function() {
return {
foo: ['bar', 'foobar',]
};
},
el: '#body',
});
The output that I would expect to see is:
<body>
<div id="body">
<ul><li>bar</li><li>foobar</li></ul>
{{ foo }}
</div>
</body>
However, what I get is:
<body>
<div id="body"><ul><li>bar</li><li>foobar</li></ul>
["bar","foobar"]
</div>
</body>
Is there any way that I am able to stop this from happening?

You need use the v-pre or v-html directive:
<span v-pre>{{ foo }}</span>
https://v2.vuejs.org/v2/api/#v-pre
<span v-html="'{{ foo }}'"></span>
Dynamically rendering arbitrary HTML on your website can be very
dangerous because it can easily lead to XSS vulnerabilities. Only use
HTML interpolation on trusted content and never on user-provided
content.
https://v2.vuejs.org/v2/guide/syntax.html#Raw-HTML

Related

Vue Animation Script misses the timing

I have a web api project and I want to play an animation on one of my html spans.Specificly the vue returns a number and I want that number to animate increasing from 00.00% up to its value.It actually works fine with a js script that I found online if I delete a part of my html but it doesnt work and the numbers appears as 00.00 if I use my entire HTML Code.
Here is my code:
<html>
<body>
//This is the part that I want to work but appears as 00.00
<span class="Animation">{{number}}</span>%
//This is the part that if I delete it the upper part works but I want both parts in my project
<div v-for="item in items">
<h3>{{item1.name1}}</h3>
<h5 class="prediction-2">Score:{{item2.name2}}%</h5>
<a v-bind:href="'test.html?id=' + item.other_id" class="btn">
<span style="color:white;">click here</span>
</a>
</div>
<script>
$('.Animate').each(function () {
var $this = $(this);
jQuery({
Counter: 0
}).animate({
Counter: $this.text()
}, {
duration: 5000,
easing: 'swing',
step: function () {
$this.text(this.Counter.toFixed(2));
}
});
});
</script>
</body>
</html>
````````````````````
Your Vue markup is broken. Because it errors it blocks the execution of JavaScript in your page and one of the side effects is the animator doesn't run anymore.
This code is invalid:
<div v-for="item in items">
<h3>{{item1.name1}}</h3>
<h5 class="prediction-2">Score:{{item2.name2}}%</h5>
<a v-bind:href="'test.html?id=' + item.other_id" class="btn">
<span style="color:white;">click here</span>
</a>
</div>
It loops through items defining item for each iteration but then tries to use item1 and item2 (which are not defined).
My advice is to exclude the animator from your question (as it clearly works as intended when there are no errors in the page) and rewrite your question by describing what the Vue code should do.
An example of how a valid v-for looks like:
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: () => ({
items: [{
name: 'Item 1',
prediction: 56,
other_id: 101
}, {
name: 'Item 2',
prediction: 82,
other_id: 102
}]
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="item in items">
<h3>{{item.name}}</h3>
<h5 class="prediction-2">Score: {{item.prediction}}%</h5>
<a :href="'test.html?id=' + item.other_id" class="btn">
<span>click here</span>
</a>
</div>
</div>
As you can see, it's looping through each item and rendering them according to each of their values. You'll also notice the links are correct. Without more definition on what the code should actually do/render, I can't help you more.

Simplest v-for example doesn't work in <li v-for="todo in todos">

I've started learning Vue.js and I immediately hit a bump.
<body>
<div id="app">
<span v-if='show'>{{ message }}</span>
</div>
<ol>
<li v-for="todo in todos">
{{ todo }}
</li>
</ol>
</body>
var app = new Vue({
el: '#app', // elementul pe care il controleaza Vue
data: { // datele aplicatiei (model)
message: "Hello Vue",
show: true,
todos: [
"Learn JavaScript",
"Learn Vue.JS",
"Learn React",
"Be Free !"
]
}
});
Using the above code should display :
Hello Vue
1.Learn JavaScript
2.Learn Vue.JS
3.Learn React
4.Be Free !
Instead this is what I get:
Hello Vue
1.{{ todo }}
I am watching a video tutorial and my code is identical to the teacher's; his works, mine does not.
The console is empty. There is no error, no warning message, no nothing. It just does not work.
I have also tried using {{ todo.text }} but with no luck.
Your list is outside of the main div element, so it won't be part of the component's template.
Fix is:
<body>
<div id="app">
<span v-if='show'>{{ message }}</span>
<ol>
<li v-for="todo in todos">
{{ todo }}
</li>
</ol>
</div>
</body>

Output html using a Vue template tag, but without having a nested element

My over-arching question is: In Vue, how to output inner html while iterating over a collection but without having to wrap it in an additional div or span.
Specifically: I'm iterating over an array of js objects from within a Vue template. Each object has a "render" method which outputs html.
This works:
template:
`<div id="container">
<template v-for="element in elements">
<span v-html="element.render()"></span>
</template>
</div>
`,
But I would like to do something like below, because I don't want the output to be wrapped in a div or span. This code produces no error but also produces no output:
template:
`<div id="container">
<template v-for="element in elements" v-html="element.render()">
</template>
</div>
`,
In a perfect world, I would do something like this, but mustache format can't output html:
<div id="container">
<template v-for="(element, index) in elements">
{{ element.render() }}
</template>
</div>
The desired output:
<div id="container">
(output of element.render())
(output of element.render())
(output of element.render())
etc.
</div>
Thank you for any guidance,
L
Delete the <template> tag completely and use render function in <script> tag. Something like this, but this code is not tested, demonstrational only.
export default {
...
render (h) {
return h('div', this.elements.map(function (elm) {
return h(elm.render())
})
}
}

vuejs render part of template inside different elements without repeating

I am new to Vuejs. This is what I need to do.
<div v-for="r in records">
<div v-if="r.something">
<div id="x">
{{ r. something}}
more of r here.
</div>
</div>
<div v-else id="x">
same div as in the block above.
</div>
</div>
What I want do is not define div with id x two times as it is huge.
Make your 'div' a component and refer to it in both places.
There are many ways to define your component. This is example shows just one. If you are using WebPack, use a single file component. You can then have your script, html, and css all in one file that gets precompiled. That's the best way to manage your 'huge' div. Then you can continue to refactor and break it up into more components.
const myComponent = {
template: "<div :id='id'>HELLO, my id is {{id}}. r.foo is {{r.foo}} </div>",
props: {
id: String
},
data() {
return {
r: {
foo: 'bar'
}
}
}
}
<div v-for="r in records">
<div v-if="r.something">
<my-component id='x' />
</div>
<div v-else id="x">
<my-component id='x' />
</div>
</div>

Vue.js doesn't display brackets like {{ post.title }}

For some reason Vue doesn't render {{post.title}}, {{ post.content }} brackets for me. The content is empty (look at the rendered html below), but v-bind:href="post.url" works for some reason. I'm new to Vue.js and really stuck for day now.
Backstory:
this code is Vue instant search for my Jekyll blog.
HTML
<div v-if="articles" class="large-12 columns">
<article v-for="post in itemsSearched" class="article-summary">
<header>
<h2><a v-bind:href="post.url">{{post.title}}</a></h2>
</header>
<p>{{ post.content }}</p>
<div class="large-12 column">
<a class="read-more" v-bind:href="post.url">Read More...</a>
<div class="middle_line"></div>
</div>
</article>
</div>
Rendered HTML
<article class="article-summary">
<header>
<h2></h2>
</header>
<p></p>
<div class="large-12 column">
Read More...
<div class="middle_line"></div>
</div>
</article>
Jekyll uses double curly braces itself, so you need to define custom delimiters for your Vue.
new Vue({
delimiters:['<%', '%>'],
....
})
And then use
<% post.title %>
Instead.
You can define whatever delimiters you want, I just used those as an example.
Please use v-text or v-html instead. In vue 2.0,Vue-config-delimiters was deprecated, delimiters is only avaliable in the full build.[]:https://v2.vuejs.org/v2/guide/migration.html#Vue-config-delimiters-replaced