Vue.JS Custom Truncated Pagination Problem - vue.js

I need a help in creating a pagination with ellipsis dynamically from a component
Javascript code. let's say we have 10 pages
<script setup>
import { ref } from "vue"
// page starts with #1
const pageStart = ref(1)
const pages = ref(10)
</script>
Here's my template:
<template>
<div>
<ul v-for="number in pages" :key="number">
<li v-if="number < pageStart">
<button>{{number}}</button>
</li>
<li v-else-if="number > 2">
...
</li>
</ul>
</div>
</template>
So far, the result I get is like:
1 2 3 ... ... ... ... ... ...
But I want achieve something like this
1 2 3 ... 10
or
1 ... 3 4 5 ... 10

Related

How to fix simple error in moving ".slice()" into setup() as a computed function?

I'm using Vuejs3 and trying to move .slice(0,3) (limits v-for to 3) into a computed function in the setup(), in order to limit the number of elements in a v-for (that happens to be nested in another v-for).
Everything works as intended before the change, using the following code:
<ul class="mt-4">
<div v-for="review in prime.allReviews" :key="review">
<li v-for="pro in review.propPros.slice(0, 3)" :key="pro">
{{ pro }}
</li>
</div>
</ul>
When I try to move the slice(0, 3) into the setup() as a computed function, per a dozen suggestions it's best practice to do so, the DOM goes blank. Here's the code causing the problem:
<ul class="mt-4">
<div v-for="review in prime.allReviews" :key="review">
<li v-for="pro in limitedPros" :key="pro">
{{ pro }}
</li>
</div>
</ul>
And in setup():
const limitedPros = computed(() => {
return review.propPros.slice(0, 3);
});
...
return {
limitedPros,
};
Thanks for any help!
Try to pass review to function, without computed property:
(When you want to loop review you need to know which one)
const { ref } = Vue
const app = Vue.createApp({
setup() {
const prime = ref({allReviews: [{propPros: [1,2,3,4,5]}, {propPros: [6,7,8,9]}]})
const limitedPros = (review) => {
return review.propPros.slice(0, 3);
};
return { limitedPros, prime };
}
})
app.mount('#demo')
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
<div id="demo">
<ul class="mt-4">
<div v-for="review in prime.allReviews" :key="review">
<li v-for="pro in limitedPros(review)" :key="pro">
{{ pro }}
</li>
</div>
</ul>
</div>

How to fix "multiple root element" v-for error

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>

How can I create n divs, n coming from data in Vue?

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

VueJS slots with v-for loop do not display proper elements

I'm trying to create a component that displays a subset of items passed to it.
So far I have a 'sublist' component with named slots as follows:
...
data: () => ({
startItem : 0
})
...
<template>
<div>
<slot v-for="ctr in maxItems" :name="'s-' + (ctr + startItem - 1)"></slot>
</div>
</template>
In the parent I do the following:
<sublist :max-items="5">
<div v-for="(i,index) in items" :slot="'s-'+index">
{{index}}
</div>
</sublist>
When it loads, everything renders fine:
0 1 2 3 4
However when I increment startItem in the sublist component, the output becomes:
5 1 2 3 4
So it removes the 0th slot and stuffs slot 5 in its place. What is a proper way to replace the slots or make them "dynamic"? I'm using VueJS 2.4.2
Thanks to #SteveHolgado I found the answer: had to add :key attribute in the parent v-for and wrap each slot in the child in its own div:
<template>
<div>
<div v-for="ctr in maxItems">
<slot :name="'s-' + (ctr + startItem - 1)"></slot>
</div>
</div>
</template>

How to make data reactive when it's array in Vue Template

<template>
<button v-on:click="modify"> modify </button>
<div v-model="lists">{{ lists[0] }}</div>
</template>
<script>
export default {
methods: {
modify: function() {
console.log(this.lists)
this.lists[0][0] = 2
console.log(this.lists)
},
data: function () {
return {
lists: [[1,2,3],[2,3,3]]
}
}
}
</script>
The array at template does not seems to get updated. But the log console has changed.
How do you make a data reactive when it's an array?
What is actually happening:
Before clicking modify
<div v-model="lists">{{ lists[0] }}</div> # produce 1
After clicking modify
<div v-model="lists">{{ lists[0] }}</div> #produce 1
What is expected:
Before clicking modify
<div v-model="lists">{{ lists[0] }}</div> # produce 1
After clicking modify
<div v-model="lists">{{ lists[0] }}</div> #produce 2
This is a caveat when updating arrays by index in Vue. Try this.
this.lists[0].splice(0,1,2)