can't display array inside of html using vuejs v-for - vue.js

I am returning back an array of object to render all on the screen. I am making a Ajax request to get a bunch of titles. Right now I can only manage to make it bring back one by writing vm.CourseTitle=data.d.results[0].Title; Instead, I want it to return all, I have tried vm.CourseTitle=data.d.results.Title; but that breaks it. How do I need to format the vuecode to make this display all the titles? In theory, this would be enclosed within a return{}. No idea why I can't get this to work!
new Vue({
el: "#app",
data: {
CourseTitle: [{ "Title":"Ford", "models":[ "Fiesta", "Focus", "Mustang" ] },
{ "Title":"BMW", "models":[ "320", "X3", "X5" ] },
{ "Title":"Fiat", "models":[ "500", "Panda" ] }
],
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Todos:</h2>
<li v-for="course in CourseTitle"></li>
{{CourseTitle}}
</div>

You're not correctly manipulating html. It should be:
<li v-for="course in CourseTitle">{{course.Title}}</li>
Further, li tag should be wrapped with ul tag.

Related

vuejs bind url from data to click method

I have a set of data that has urls nested in the data model. I want to bind the url from from the data to click event. Right now it does not get the exact url just the variable. It should open the url in the data in a blank tab.
new Vue({
el: "#app",
data: {
chocs: [
{ url: "https://yahoo.com"},
]
},
methods: {
myclick2: function(choc){
alert("test")
window.open(choc.url)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>
my hat
</h2>
<button v-on:click="myclick2(choc)">
my link
</button>
</div>
There are multiple little error in your code
First the correct code:
new Vue({
el: "#app",
data() {
return {
chocs:
{ url: "https://yahoo.com"},
}
},
methods: {
myclick2: function(){
alert("test ")
window.open(this.chocs.url, "_blank")
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>
my hat
</h2>
<button v-on:click="myclick2()">
my link
</button>
</div>
List of errors:
the data part is written as data(){return{...}}
in your function you were calling choc instead of chocs (you have access to the data, don't pass something that is undefined as parameter)
because you use data, you need to call it with this
based on the structure from chocs, you have an object in an array (the first place in the array; index 0) OR based on your comment -> remove this brackets [ ]
if you want to open a new window, you can add "_blank"
You have defined the data as an array named chocs. Containing an object with an url.
This would be saved as follows:
cohc: [
{ url: "https://yahoo.com/" }
]
This array could contain more items, but right now it only contains this one item. If you want to "open" that item you would do something like the following:
cohcs: [
{ url: "https://yahoo.com/" }
]
console.log(cohcs[0]) // returns: { url: "https://yahoo.com/" }
The 0 is the index of the array.
In case of the code provided above, you can define your v-on:click event like this:
<button v-on:click="myclick2(chocs[0])">
If you only want to save one link. you could also define your data as
data: {
chocs: { url: "https://yahoo.com"}
},

In VueJS using v-for, is this structure possible?

Given a collection of objects in the data of a component:
data: function () {
return [
{ id: 1, name: "foo", br: false },
{ id: 1, name: "bar", br: true },
{ id: 1, name: "baz", br: false }
]
}
...is it possible to render a structure like so...
<div id="1">foo</div>
<div id="2">bar</div><div class="break" />
<div id="3">baz</div>
In a nutshell, I need to have another div conditionally rendered at the same level as the items in the list. If it matters or helps, the individual items in the list are also components. I know how to set up the rest of the data and properties - it's just getting that additional HTML rendered in the list that I need to accomplish.
I want to avoid creating another item in the list and additional component to represent the break. No need to add the overhead of the additional Vue objects for the simple HTML div. This list may have > 100 items and "breaks" and it can add up quickly.
Yes. You should loop through the items like so:
<template v-for="item in items">
<div :id="item.id">
{{ item.name }}
</div>
<div class="break" v-if="item.br">
</div>
</template>
You can do it with a normal v-for and a normal v-if for your optional div
<html>
<head>
<script type = "text/javascript" src = "https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js">
</script>
</head>
<body>
<div id="app">
<div v-for="item in items">
<div :id="item.id">{{item.name}}</div>
<div v-if="item.br" class="break">
</div>
</div>
<script type = "text/javascript">
var vue_det = new Vue({
el: '#app',
data: {
items: [
{ id: 1, name: "foo", br: false },
{ id: 2, name: "bar", br: true },
{ id: 3, name: "baz", br: false }
]}
});
</script>
</body>
</html>
You should not be afraid of 100 divs or around so, a library like Vue is made to manage efficiently thousands of components

How to render HTML from a property of items being displayed with v-for loop?

I send an array of objects which each have a .html property that has HTML text in it, e.g. <h1>...</h1> or <h2>...</h2>
I want to have the HTML from each item display one after another in the DOM, like this:
<h1>...</h1>
<h2>...</h2>
<h2>...</h2>
<h1>...</h1>
<h2>...</h2>
However, all of these attempts do not work:
<div v-for="item in outlineItems" v-html="item.html"></div>
displays HTML wrapped in divs: <div><h1>...</h1></div> and <div><h2>...</h2></div>
<template v-for="item in outlineItems" v-html="item.html"></template>
displays nothing
<template v-for="item in outlineItems">{{item.html}}</template>
displays the literal HTML instead of rendering it
<template v-for="item in items"><template v-html="item.html"></template></template>
displays nothing
How can I simply display the contents of the .html property of each item so that the HTML in it renders, without any wrapping elements on it?
You could do it using a single wrapper element for the whole lot by concatenating all the HTML in a computed property:
new Vue({
el: '#app',
data () {
return {
outlineItems: [
{ html: '<h1>Heading 1</h1>' },
{ html: '<h2>Heading 2</h2>' },
{ html: '<h3>Heading 3</h3>' }
]
}
},
computed: {
outlineHtml () {
return this.outlineItems.map(item => item.html).join('')
}
}
})
<script src="https://unpkg.com/vue#2.6.11/dist/vue.js"></script>
<div id="app">
<div v-html="outlineHtml"></div>
</div>
Behind the scenes v-html sets the innerHTML of its corresponding DOM node. A <template> tag doesn't create a DOM node so the innerHTML can't be set anywhere.
I would add that v-html is considered an 'escape hatch'. Where possible you should avoid using it and let Vue create the HTML itself. Generally the approach would be to use a suitable data structure to hold the data (rather than a blob of markup) and then render that data structure within the template.
One possible solution is to create multiple unique components. You can even pass in props, and there are no wrappers
Vue.component('greeting', {
template: '<h1>Welcome to coligo!</h1>'
});
Vue.component('titles', {
template: '<h1>title 1</h1>'
});
Vue.component('title2', {
template: '<h2>Welcome to coligo!</h2>'
});
Vue.component('title3', {
template: '<h3>{{text}}</h3>',
props: ['text']
});
var vm = new Vue({
el: '#app',
data: {
items: [
{ type: 'greeting' },
{ type: 'titles' },
{ type: 'title2' },
{ type: 'title3', text: 'test' }
]
}
});
<script src="https://unpkg.com/vue#2.6.11/dist/vue.js"></script>
<div id="app">
<component v-for="(item,i) in items" :is="item.type" :text="item.text" :key="i"></component>
</div>

Removing last item when rendering in vue.js

I am facing an issue where a item is getting rendered even though there is no associated Title with it as shown in my JSON. Please see the attached screenshot which will make you understand my problem (marked in red). I know this is happening due to lid in my JSON for which vue is rendering that without any associated (i.e Title) values. How do I solve this issue. Is there a way to remove the last item when rendering or is there any other way ?. I need the lid in this.dino but do not need it when rendering in my vue-app. Is there a way to pop out the last item from the JSON when rendering.
<div id="vue-app">
<div id="myList" v-for="item in items">
<p>{{item.Title}}</p>
<button v-on:click="loadmore()" class="fluid ui button">Load More</button>
Below is my vue function
new Vue({
el: '#vue-app',
delimiters: ['[[', ']]'],
data: {
dino: d_var,
cati: d_catox,
items: []
},
methods: {
loadmore: function () {
axios.get(this.dino)
.then(response => {
this.items.push(...response.data);
this.dino = "/api/search/" + this.items[this.items.length - 1].lid + "/" + this.cati;
})
}
}
})
Below is my JSON
[
{
"Title": "HealthXP1"
},
{
"Title": "HealthXP2"
},
{
"Title": "HealthXP3"
},
{
"lid": "A1234567890"
}
]
you can use 'v-if' or 'v-show' directive as:
<div id="vue-app">
<div id="myList" v-for="item in items" v-show="item.Title">
<p>{{item.Title}}</p>
<button v-on:click="loadmore()" class="fluid ui button">Load More</button>
that will show that item on the list if the item.Title is defined, otherwise it will not be rendered in DOM

How to bind CSS class into an HTML code tag?

I have data like so:
new Vue({
el: '#app',
data: {
icons: [
{ "name": "Car", "css": "car" }, { "name": "Airplane", "css": "airplane" }
]
}
});
And I want to bind the css value to my view inside an HTML <code> element and formatted and rendered as so:
<i class="fa fa-car></i>
Here's my attempt using Vuejs2.0:
<code>%lt;i class="fa" :class="'fa-' + icon.css"></i></code>
Unfortunately, the DOM is rendered like so:
<i class="fa" :class="'fa-' + icon.css"></i>
How do I make this work? Thanks!
If you want to iterate inside your icons array, you can use a template with the v-for directive :
<template v-for="icon in icons">
<i class="fa fa-{{ icon.css }}></i>
</template>