With vuetify, I am trying to set <v-pagination> on a <v-list-item> but I don't see how to bind my items (n in notification) to the pagination. Does it need an extra function? Most of the documentation I found was with vuetify tables.
<template>
<div>
<v-card
class="mx-auto"
max-width="300"
tile
>
<v-list rounded>
<v-subheader>NOTIFICATIONS</v-subheader>
<v-list-item-group color="primary">
<v-list-item
v-for="(n, i) in notification"
:key="i"
>
<v-list-item-content>
<v-list-item-title v-text="n.payload"></v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-pagination
v-if="pages > 1"
v-model="pagination.page"
:length="pages"
></v-pagination>
</v-list-item-group>
</v-list>
</v-card>
</div>
</template>
<script>
export default {
name: "status",
data() {
return {
pagination: {
page: 1,
total: 0,
perPage: 0,
visible: 3
},
notification: [],
}
},
computed: {
pages () {
Math.ceil(this.notification.length / 3)
}
}
}
</script>
How do I set the number of items displayed by page?
you can use the pagination component's v-model to get a list of items to display.
here's an example
<div id="app">
<v-app id="inspire">
<div class="text-center">
{{ visiblePages }}
<v-pagination
v-model="page"
:length="Math.ceil(pages.length/perPage)"
></v-pagination>
</div>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
page: 1,
perPage: 4,
pages: [0,1,2,3,4,5,6,7,8,9,10,11,12,13]
}
},
computed: {
visiblePages () {
return this.pages.slice((this.page - 1)* this.perPage, this.page* this.perPage)
}
}
})
https://codepen.io/scorch/pen/RwwGKrQ
you can then pass the visiblePages to you item list.
Related
I'm using v-list-item-group and I want to show data in another component when the list item is selected. clear data when I unSelect item, and change data when I click on another list item
how can I possibly do it in vue?
the list item which I select:
Here I want to clear curr step data if the list.eid changed or when index changed
<v-list-item-group v-model="wfs">
<v-list-item v-for="(list,index) in workflowStepsList" :key="index"
#click="getWorkflowStep(list.eid)">
<v-list-item-action-text class="pe-4"> {{ index+1 }}</v-list-item-action-text>
<v-list-item-content v-if="!list.title">
{{ list.stepTitle }}
</v-list-item-content>
<v-list-item-content v-if="!list.stepTitle">
{{ list.title }}
</v-list-item-content>
<v-list-item-icon>
<v-icon small color="red">mdi-delete</v-icon>
</v-list-item-icon>
</v-list-item>
<v-list-item v-if="!workflowStepsList.length">
مرحله ای وجود ندارد
</v-list-item>
</v-list-item-group>
and the list I render data based on what I selected:
<v-card>
<v-card-title class="bg-success text-white d-flex justify-space-between">
مرحله فعلی
<add-curr :getSteps="getSteps"/>
</v-card-title>
<v-card-text>
<v-list>
<v-list-item-group class="v-list-item-group" v-model="stepId">
<v-list-item
v-if="!currStep.length"
class="text-muted"
>
یک مرحله انتخاب کنید
</v-list-item>
<v-list-item
v-for="(element) in currStep"
:key="element.eid"
v-show="element.eid !== null"
>
{{ element.title }}
</v-list-item>
</v-list-item-group>
</v-list>
</v-card-text>
</v-card>
the function:
async getWorkflowStep(weid) {
await this.$store.dispatch("axiosGet",
{url: `folder/api/workflow-steps/${weid}`, params: {workflowId: this.id}}).then(response => {
if (response.status === 'error') return
this.workflowStepsObj = response.data.data
const x = response.data.data
const curr = {
title: x.stepTitle,
eid: x.stepEid
}
this.currStep.push(curr)
})
},
I just added an another component and passing the model value as a prop in that component.
Live Demo :
Vue.component('another-component', {
props: ['val'],
template: '<h3>{{ val }}</h3>'
});
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [
{ text: 'Inbox' },
{ text: 'Star' },
{ text: 'Send' },
{ text: 'Drafts' }
],
model: 1,
}),
});
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.12/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.12/dist/vuetify.min.css"/>
<div id="app">
<v-list>
<v-list-item-group v-model="model">
<v-list-item v-for="(item, i) in items" :key="i">
{{ item.text }}
</v-list-item>
</v-list-item-group>
</v-list>
<another-component :val="items[model].text"></another-component>
</div>
You can either use store value and watch it from the component you want to track the change (it is possible to watch store properties if they change). If using vuex: https://vuex.vuejs.org/api/#watch
Or you can use emits and listen to the change on desired component, if there's depth issue for the emit you could pass emits on top level using (v-on="$listeners"): https://v2.vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components
Since there's no statement about Vue or Vuetify version, inferring it is the 2nd version.
Sometimes when using Vuetify or UI libraries we may forget the features that Vue provides. Despite Vuetify having built-in features most probably they can be overridden by implementing yours on top of them.
I have these combobox chips with a prob deletable-chips
<v-combobox
v-model="selectedCategories"
:items="attributeCategories"
item-text="name"
item-value="id"
label="Category"
multiple
chips
clear-icon="mdi-close-circle"
deletable-chips
v-on:change="changeCategory(selectedCategories)"
></v-combobox>
Is there a way to prevent a specific chip to be deleted? For example not show the remove button on a specific one? Let's say for Device and only allow Weather and Geo Location to me removed
Instead of using in-built delete method of v-chips. You can do the implementation via custom #click:close event. I created a working demo for you :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
model: [],
items: [
{
text: 'Weather'
},
{
text: 'Geo Location'
},
{
text: 'Device'
}
]
}),
methods: {
remove (itemText) {
if (itemText === 'Device') {
return;
} else {
this.model.forEach(obj => {
if (obj.text === itemText) {
this.model.splice(this.model.indexOf(obj), 1)
}
})
this.model = [...this.model]
}
}
}
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.6/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.6/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://unpkg.com/#mdi/font#6.x/css/materialdesignicons.min.css"/>
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-combobox
v-model="model"
:items="items"
label="Select"
multiple
small-chips
>
<template v-slot:selection="{ attrs, item, parent, selected }">
<v-chip
v-bind="attrs"
:input-value="selected"
close="false"
#click:close="remove(item.text)"
>
<span class="pr-2">
{{ item.text }}
</span>
</v-chip>
</template>
</v-combobox>
</v-container>
</v-app>
</div>
everyone, I am new to vuejs and vuetify and trying to make a book app but the problem is all the code is complete but when I click on the dropdown item it shows all the books item but I want to show only selected book item.
This is my HTML where I am stuck I am doing mistakes here this and I am failed many times cannot get my answer
<v-container fluid>
<v-row aign="center">
<v-col cols="12">
<v-toolbar-title>State Selection</v-toolbar-title>
<div v-on-clickaway="away" class="searchField dropdown">
<v-text-field
:label="labeling"
v-model="search"
#input="waitForSearch"
>
</v-text-field>
<!-- <div class="bookParent" v-for="item in items" :key="item.id"> -->
<!-- <img :src="item.volumeInfo.imageLinks.thumbnail" /> -->
<div
class="clickUpdateElement"
v-for="(item, index) in items"
:key="item.id"
>
<HelloWorld v-show="show">
<template v-slot:contentHandler class="option" id="option1">
<div
#click="clickCard(item, $event.target)"
class="containerForI"
>
<v-img>
<img :src="item.volumeInfo.imageLinks.thumbnail" />
</v-img>
<a class="anchorTag">{{ item.volumeInfo.title }}</a>
<!-- <span>{{ item.volumeInfo.author }}</span> -->
</div>
</template>
</HelloWorld>
<div class="content">
<Content v-show="show2" #load="updateCard(item, $event.target)">
<template v-slot:cardContent>
<v-card class="mx-auto" elevation="2" outlined shaped>
<v-list-item three-line>
<v-list-item-avatar>
<!-- <v-img :src="imageSrc"></v-img> -->
</v-list-item-avatar>
<v-list-item-content>
<v-card-title>
{{ item.volumeInfo.title }}
</v-card-title>
<v-card-subtitle>
{{ index }} {{ item.volumeInfo.description }}
</v-card-subtitle>
</v-list-item-content>
<v-card-actions>
<v-btn primary>Act</v-btn>
</v-card-actions>
</v-list-item>
</v-card>
</template>
</Content>
</div>
</div>
<v-btn #click="show2 = false">Remove</v-btn>
</div>
</v-col>
</v-row>
</v-container>
MY JS
import axios from "axios";
import { directive as onClickaway } from "vue-clickaway";
import HelloWorld from "../components/HelloWorld";
import Content from "../components/Content";
export default {
name: "Home",
directives: {
onClickaway: onClickaway,
},
data() {
return {
BASE_URL: "https://www.googleapis.com/books/v1/volumes",
items: [],
search: "",
timerId: "",
labeling: "Search For Book",
show: false,
show2: false,
imageSrc: "",
showTitle: "",
showDescription: "",
};
},
components: {
HelloWorld,
Content,
},
created() {},
computed: {},
//Fetch the required Information from Google Book Api
watch: {},
methods: {
async getBooks() {
this.show = true;
let response = await axios.get(`${this.BASE_URL}`, {
params: {
q: this.search,
apikey: "",
},
});
this.items = response.data.items;
console.log(this.items);
},
away() {
console.log("clicked away");
this.show = false;
},
clickCard(item, target) {
console.log(item);
console.log(target);
this.show = false;
this.show2 = true;
},
updateCard(item, target) {
console.log(item);
console.log(target);
},
//Method That Take and wait for the Input
waitForSearch() {
// this.search = "";
clearTimeout(this.timerId);
this.timerId = setTimeout(() => {
this.getBooks();
}, 1000);
},
},
Content.vue i just used slot nothing else
<div class="container">
<div class="row">
<slot name="cardContent"></slot>
</div>
</div>
HelloWorld.vue
html
<div class="menu pointerCursor hide">
<slot name="contentHandler"></slot>
</div>
I try many times but failed. Any leads, please?
What I would try is to keep a record of the index that I want to show.
So what you could do is the following:
1.Change the code calling ClickCard
<div #click="clickCard(item, index)" class="containerForI">
2.Assign the value of index to a component variable
clickCard(item, index) {
console.log(item);
this.indexToShow = index;
this.show = false;
this.show2 = true;
},
3.Initialize the aforementioned variable in your component
data() {
return {
BASE_URL: "https://www.googleapis.com/books/v1/volumes",
indexToShow: null,
...
4.Finally, check if the currently selected index is the one to show
<Content v-show="indexToShow === null || indexToShow === index"
If you want to show all items, after showing only 1, you will have to set indexToShow to null. The Content component is checking for it.
Hello I am trying to implement socket.io with vue.js however I cannot access the emits in the different views.
After configuring main.js I can get emits on the APP, but I can't get them on HOME.
Is it possible to help with this situation.
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import vuetify from "./plugins/vuetify";
import * as io from "socket.io-client";
import VueSocketIO from "vue-socket.io";
Vue.use(
new VueSocketIO({
debug: true,
connection: io("http://localhost:3001"),
})
);
Vue.config.productionTip = false;
new Vue({
router,
store,
vuetify,
render: (h) => h(App),
}).$mount("#app");
Here I have the implementation of the first view, and here I have access to the socket.io emit!
<template>
<v-app id="inspire">
<v-app-bar app color="white" flat>
<v-container class="py-0 fill-height">
<v-avatar class="mr-10" color="grey darken-1" size="32"></v-avatar>
<v-btn v-for="link in links" :key="link" text>
{{ link }}
</v-btn>
<v-spacer></v-spacer>
<v-responsive max-width="260">
<v-switch
v-model="switchLogIn"
label="login"
color="success"
hide-details
></v-switch>
</v-responsive>
</v-container>
</v-app-bar>
<v-main class="grey lighten-3">
<v-container>
<v-row>
<v-col cols="2">
<v-sheet rounded="lg">
<v-list color="transparent">
<v-list-item v-for="n in 5" :key="n" link>
<v-list-item-content>
<v-list-item-title> List Item {{ n }} </v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-divider class="my-2"></v-divider>
<v-list-item link color="grey lighten-4">
<v-list-item-content>
<v-list-item-title to="/about">
{{ nextSip["Estado Processo"] }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-sheet>
</v-col>
<v-col>
<v-alert icon="mdi-database-outline" prominent text type="info">
FILA DE TRABALHO COM {{ workFlowSize }}.
</v-alert>
<v-sheet min-height="70vh" rounded="lg" v-if="switchLogIn">
<router-view></router-view>
</v-sheet>
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
</template>
<script>
export default {
data: () => ({
links: ["Dashboard"],
switchLogIn: false,
workFlow: "",
workFlowSize: 0,
nextSip: Object,
}),
sockets: {
connect: function () {
this.$swal("Conectado com Sucesso", "Servidor Localhost:3001", "success");
console.log("socket connected");
},
workFlowSize(data) {
this.workFlowSize = data;
},
nextSip: (data) => {
console.log(data);
},
},
watch: {
switchLogIn: function (value) {
if (value == true) {
console.log("Im LOGIN");
}
},
},
};
</script>
but not here
<template>
<div class="home">
<SipForm/>
</div>
</template>
<script>
import SipForm from "#/components/SipForm.vue";
export default {
name: "Home",
components: {
SipForm,
},
data: () => ({
workFlowSize: 0,
}),
sockets: {
connect: function () {
this.$swal("Conectado com Sucesso", "Servidor Localhost:3001", "success");
console.log("socket connected");
},
workFlowSize(data) {
this.workFlowSize = data;
},
nextSip: (data) => {
console.log(data);
},
},
};
</script>
I am using Vue draggable to change the position of my v-chips. When you click on a chip, the chip shows Active and is binded to selection with its index. The problem is that when you drag a chip and change its position it does not update the selection index.
How can I make sure one follows the other?
<v-chip-group
v-model="selection"
active-class="primary--text"
column
>
<draggable v-model="items" #start="drag=true" #end="drag=false">
<v-chip v-for="(item, i) in items" :key="i"
close
draggable>
{{item.name}}
</v-chip>
</draggable>
</v-chip-group>
You can able to set the selection index using #start and #end event in draggable component
Here is the working codepen: https://codepen.io/chansv/pen/zYvOYyd?editors=1010
Find the working code here:
<div id="app">
<v-app id="inspire">
<v-card
max-width="400"
class="mx-auto"
>
<v-card-text>
<v-chip-group
v-model="selection"
column
active-class="primary--text"
>
<draggable v-model="tags" #start="dragStart" #end="dragEnd">
<v-chip v-for="(tag, i) in tags" :key="i" draggable>
{{ tag.name }}
</v-chip>
</draggable>
</v-chip-group>
</v-card-text>
</v-card>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
selection: null,
currentTag: null,
tags: [{
name: 'Shoping',
},{
name: 'Art',
}, {
name: 'Tech',
}, {
name: 'Creative Writing'
}
],
}),
methods: {
dragStart() {
if (this.tags[this.selection]) this.currentTag = this.tags[this.selection].name;
else this.currentTag = null;
},
dragEnd() {
var self = this;
if (this.currentTag) {
this.tags.forEach((x, i) => {
if (x.name === self.currentTag) self.selection = i;
});
}
}
}
})