This code doesnt create 4 divs. It just creates a div with 4 in it. How can I create divs by getting the number from data?
<template>
<div>
<div v-for="n in number" :key="n">
{{n}}
</div>
</div>
</template>
<script>
export default {
data: function () {
return{
number: 4
}
}
}
</script>
v-for can most certainly range over integers: https://v2.vuejs.org/v2/guide/list.html#v-for-with-a-Range
Here is your div example:
https://codesandbox.io/s/l7lr4q6qoz
If your version doesn't work your problem lies elsewhere, not with v-for="n in 5".
Related
While I was trying to create my own carousel, I decided to use slots for this purpose.
I have two components: the main one is a carousel. vue and slide. vue. The carousel.vue stores all slides as slots.
What do I want? I want all slots which I add to my carousel that is a wrapper for all slides to display one at a time, so later I can add all functionality for my carousel
This is my carousel. vue
<template>
<div class="carousel">
<slot/>
</div>
</template>
<script>
</script>
This is my slide.vue
<template>
<div class="slide">
<slot/>
</div>
</template>
<script>
</script>
<template>
<Carousel>
<Slide>Image</Slide>
<Slide >Image</Slide>
<Slide >Image</Slide>
</Carousel>
</template>
<script setup>
import Carousel from "../../components/Reusable components/Carousel.vue"
import Slide from "../../components/Reusable components/Slide.vue"
</script>
<style>
</style>
Please, explain to me how to do it. I want to loop them with v-for but I don't know how to do it as long as I don't know how to create array for slides.
There are many ways to achieve, what you want to do. I will show you below an example (Simple) way to achieve what you want.
In your slide.vue, accept a prop which is display a boolean, based on which the slide will be displayed.
<template>
<div class="slide" v-if="display">
<slot />
</div>
</template>
<script setup>
defineProps({
display: {
type: Boolean,
default: false,
},
});
</script>
In your grandparent component, you can use a v-for to loop through the slides array. In my example, i have an array of objects in slides which i am looping through. You could have other content too.
Now i have the showslide reactive ref whose initial value is 0 and i have added buttons to navigate through the slides by incrementing or decrementing. The display prop will be true only when showslide === index of the slides array.
<template>
<Carousel>
<div v-for="(slide, index) in slides" :key="index">
<Slide :display="showslide === index">{{ slide.content }}</Slide>
</div>
</Carousel>
<button #click="display = (display + 1) % slides.length">Next</button>
<button #click="display = (display - 1) % slides.length">Previous</button>
</template>
<script setup>
import Carousel from "#/components/Carousel.vue";
import Slide from "#/components/Slide.vue";
import { ref } from "vue";
const slides = [{ content: 1 }, { content: 2 }, { content: 3 }];
const showslide = ref(0);
</script>
<style></style>
So with this code, at first, the 0th slide will be shown and when you click next first slide and so on.
Hope it gives you an idea of how to achieve what you want.
I'm new to Vue.js and I'm still learning it. I bumped into this error which I don't know how to solve.
Here is my simple script:
<template>
<div v-for="item in array" :key="item.id">
{{item}}
</div>
</template>
<script>
export default {
data () {
return {
array: ['Lion','Bear','Fish','Bird']
}
}
}
</script>
And here is the error that come up:
Cannot use v-for on stateful component root element because it renders multiple elements.
1 |
2 | <div v-for="item in array" :key="item.id">
| ^^^^^^^^^^^^^^^^^^^^^
3 | {{item}}
4 | </div>
Is there anyone who knows how to fix this error?
Try also renaming variable from array to animalNames similar. And remove id from loop as there is not id element exist, instead you can use index
<template>
<div>
<div v-for="item,index in array" :key="index">
{{item}}
</div>
</div>
</template>
You must have a root tag. Try wrapping your looped div in another div.
<template>
<div>
<div v-for="item in array" :key="item.id">
{{item}}
</div>
</div>
</template>
<script>
export default {
data () {
return {
array: ['Lion','Bear','Fish','Bird']
}
}
}
</script>
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())
})
}
}
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>
Let's say I have three components: Alpha, Bravo and Charlie.
Which looks like this:
Alpha.vue
<template>
<div class="alpha">
<bravo>
<template slot="card">
<charlie></charlie>
</template>
</bravo>
</div>
</template>
Bravo.vue
<template>
<div class="bravo">
<slot name="card" v-for="result in results" :result="result"></slot>
</div>
</template>
<script>
export default {
data: function() {
return {
results: [1, 2, 3]
}
}
}
</script>
Charlie.vue
<template>
<h1>{{ result }}</h1>
</template>
<script>
export default {
props: [
'result'
]
}
</script>
How can I pass the result prop to Charlie while defining it in a slot in Alpha?
The idea behind this is that Bravo contains a lot of shared logic. There are different variations of Alpha which may contain a different card for the slot (but will always have a result prop.)
At the moment when running that, the result prop is not being parsed to the Charlie component and an undefined error is occurring (there are probably several wrong things with the example but I hope it demonstrates what I'm trying to achieve.)
I think this is solution for your case
Alpha.vue
<template>
<bravo>
<template slot="card" slot-scope="{ result }">
<charlie :result="result"></charlie>
</template>
</bravo>
</template>
And you should wrap your slots in Bravo.vue
Documentation