Why <v-stepper/> component not working properly in vuetify nuxt 3 - vue.js

I'm using vuetify3 in nuxt3, some code work but when a try to use the <v-stepper>...</v-stepper> component i get the following error :
✔ Nitro built in 533 ms
nitro 17:34:04
[Vue warn]: Failed to resolve component: v-stepper
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
I want to understand why. This is the code I used from the official doc :
<template>
<v-container>
<h1>Login</h1>
<v-stepper v-model="e1">
<v-stepper-header>
<v-stepper-step
:complete="e1 > 1"
step="1"
>
Name of step 1
</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step
:complete="e1 > 2"
step="2"
>
Name of step 2
</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step step="3">
Name of step 3
</v-stepper-step>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content step="1">
<v-card
class="mb-12"
color="grey lighten-1"
height="200px"
></v-card>
<v-btn
color="primary"
#click="e1 = 2"
>
Continue
</v-btn>
<v-btn text>
Cancel
</v-btn>
</v-stepper-content>
<v-stepper-content step="2">
<v-card
class="mb-12"
color="grey lighten-1"
height="200px"
></v-card>
<v-btn
color="primary"
#click="e1 = 3"
>
Continue
</v-btn>
<v-btn text>
Cancel
</v-btn>
</v-stepper-content>
<v-stepper-content step="3">
<v-card
class="mb-12"
color="grey lighten-1"
height="200px"
></v-card>
<v-btn
color="primary"
#click="e1 = 1"
>
Continue
</v-btn>
<v-btn text>
Cancel
</v-btn>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
</v-container>
</template>
<script>
export default {
data () {
return {
e1: 1,
}
},
}
</script>
My nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
css: ['vuetify/lib/styles/main.sass'],
build: {
transpile: ['vuetify'],
},
vite: {
define: {
'process.env.DEBUG': false,
},
},
})
My plugins/vuetify.js
// plugins/vuetify.js
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
export default defineNuxtPlugin(nuxtApp => {
const vuetify = createVuetify({
components,
directives,
})
nuxtApp.vueApp.use(vuetify)
})
My package.json
{
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev --port=8001",
"generate": "nuxt generate",
"preview": "cross-env PORT=8001 node .output/server/index.mjs"
},
"devDependencies": {
"nuxt": "3.0.0-rc.4"
},
"dependencies": {
"sass": "^1.53.0",
"vuetify": "^3.0.0-beta.5"
}
}

I have the same Problem with some Vuetify3 tags. It`s because of "Beta release" i mean. the next Release (Titan) should be soon published thats written on official Vuetify site. Well done im exited..

Stepper component is not supported in Vue 3. If you check vuetify documentation for version beta 3.0 you can see the list of supported components.

Related

After adding 1 item to TODO app fails when I just type on text field, How to fix it?

this might be stupitest question to ask but I just can't understand why this is happening , I am trying to Build simple TODO app with Nuxt Js with Vuex, When I add one Item it works fine and displays, after that if I just type something on text field app failds and gives error
"Error: [vuex] do not mutate vuex store state outside mutation handlers."
Here is index.vue file
<template>
<v-main>
<v-row justify="center" class="py-10">
<h1 class="teal--text">NUXT TODO APP</h1>
<v-col cols="12" md="10">
<v-text-field type="text" outlined v-model="item.text"> </v-text-field>
<v-btn color="teal" x-large class="mt-3" #click="addItem">Add</v-btn>
</v-col>
<v-col cols="8">
<h1 v-if="items.length <= 0">No Data Found</h1>
<v-list v-else>
<v-list-item v-for="item in items" :key="item.id" class="my-5">
<v-list-item-content>
<v-list-item-title>{{ item.text }}</v-list-item-title>
</v-list-item-content>
<v-list-item-action class="d-flex flex-row">
<v-btn color="teal"> Edit </v-btn>
<v-btn color="error" class="mx-5"> Delete </v-btn>
</v-list-item-action>
</v-list-item>
</v-list>
</v-col>
</v-row>
</v-main>
</template>
<script>
export default {
computed: {
items() {
return this.$store.state.items;
},
},
data: () => ({
item: {
text: "",
},
}),
methods: {
addItem() {
this.$store.commit("addItem", this.item);
},
},
};
</script>
And here is index.js file for Vuex
export const state = () => ({
items: [],
});
export const mutations = {
addItem(state, payload) {
state.items.push(payload);
},
};
please guide me what the hell I am missing here.
Thank You.

how to implement a reusable vuetify dialog

I want to create a reusable v-dialog with vuetify,
I created the BaseModal:
<v-dialog
v-model="inputVal"
:hide-overlay="overlay"
:max-width="width"
>
<v-card>
<v-toolbar flat>
<v-btn color="black" dark icon right #click="closeModal">
<v-icon>mdi-close</v-icon>
</v-btn>
<v-spacer></v-spacer>
<v-toolbar-title id="toolbar-title">{{ title }}</v-toolbar-title>
</v-toolbar>
<v-card-title class="headline">
<!--Card Title-->
</v-card-title>
<v-card-text>
<slot name="content"></slot>
</v-card-text>
</v-card>
</v-dialog>
InputVal as computed and dataBindingName as props :
computed: {
inputVal: {
get() {
return this.dataBindingName;
},
set(val) {
this.$emit("input", val);
}
}
},
props: {
dataBindingName: {
Boolean,
required: false
},}
I'm calling this base component in another component like this:
<modal-simple
:dataBindingName="dataBindingName"
title="Nouveau"
width="418"
>
<template v-slot:content>
<add-time-sheet-form />
</template>
</modal-simple>
My problem now is how to implement correctly the closeModal and how to implement a button inside that close the modal and open a new modal
Part 1. Modal component.
Take care that you should not use v-model="dialog". As already described in this answer, you need to replace it with :value and #input.
Moreover, you should not mutate dialog prop directly, that's why you need to emit close-dialog event when you need to close your modal.
<template>
<v-dialog
:value="dialog"
#input="$emit('input', $event)"
max-width="500px"
persistent
>
<v-card>
<v-card-title>
... dialog header ...
</v-card-title>
<v-card-text>
... dialog content ...
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn #click="close">
Close
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
editedId: Number,
dialog: Boolean,
},
methods: {
close() {
this.$emit("close-dialog");
},
},
};
</script>
Part 2. Parent component.
Imagine you want to use your component when adding or editing entities.
You need to implement two methods: addItem and editItem to open your dialog. You also need to pass extra entity props (editedId in my example), dialog prop with sync modifier and close-dialog event handler that was emitted from modal component.
<template>
<div>
<v-toolbar flat color="white">
<v-spacer />
<edit-modal
:edited-id="editedId"
:dialog.sync="dialog"
#close-dialog="
editedId = null;
dialog = false;
"
/>
<v-btn color="primary" dark class="mb-2" #click="addItem">
Add entity
</v-btn>
</v-toolbar>
<v-data-table :items="items" :headers="headers">
<template v-slot:item="props">
<tr>
<td>{{ props.item.name }}</td>
<td class="justify-center text-center">
<v-icon small class="mr-2" #click="editItem(props.item)">
edit
</v-icon>
</td>
</tr>
</template>
</v-data-table>
</div>
</template>
<script>
import Dialog from "./ReusableDialog";
export default {
components: {
"edit-modal": Dialog,
},
data() {
return {
items: [
... some items ...
],
headers: [
... some headers ...
],
editedId: null,
dialog: false,
};
},
methods: {
addItem() {
this.dialog = true;
},
editItem(item) {
this.editedId = item.id;
this.dialog = true;
},
},
};
</script>
Part 3. Modifying modal to reopen automatically.
In this example, modal component will reopen automatically until editedId will not be set.
In modal component:
...
close() {
this.$emit("close-dialog");
if (this.editedId === null) {
this.$emit("open-dialog");
}
},
...
In parent component:
...
<edit-modal
... some props ...
#open-dialog="
editedId = 999;
dialog = true;
"
/>
...
There is a codesandbox with working example.

How can I make Vuetify mobile responsive navigation bar and linked drawer have NESTED menus?

I am making a navbar component through the Vue framework using Vuetify. I would like to make the products item have a drop down into two links.
This is the template html and script code (I have some additional custom CSS for color and such that I am not adding here):
<template>
<div>
<v-toolbar id="navbar" dense elevation=1 dark >
<v-app-bar-nav-icon class="hidden-md-and-up" #click="sidebar = !sidebar"></v-app-bar-nav-icon>
<v-navigation-drawer v-model="sidebar" app hide-overlay temporary>
<v-list>
<v-list-item v-for="(item, i) in menuItems" exact :key="i" :to="item.path">{{item.title}}</v-list-item>
</v-list>
</v-navigation-drawer>
<v-toolbar-items d-flex>
<v-btn href="#" id="logo" flat depressed text>Company Name</v-btn>
</v-toolbar-items>
<v-spacer></v-spacer>
<v-toolbar-items class="hidden-sm-and-down">
<v-btn text v-for="item in menuItems" :key="item.title">
<router-link :to="item.path">{{item.title}}</router-link>
</v-btn>
</v-toolbar-items>
</v-toolbar>
</div>
</template>
<script>
export default {
data: function() {
return {
sidebar: false,
menuItems: [
{ path: "/product", name: "product", title: "Product" },
{ path: "/us", name: "us", title: "Us" },
{ path: "resources", name: "resources", title: "Resources" },
{ path: "/portal", name: "login", title: "Login" }
]
};
}
};
</script>
How about app-bar?
v-menu tag support drop down
https://vuetifyjs.com/en/components/app-bars/#dense

"Maximum call stack size exceeded" error using v-dialog component twice on the same view with Vue Observable

When I open and close the v-dialog I get:
VDialog.ts:238 Uncaught RangeError: Maximum call stack size exceeded.
at VueComponent.onFocusin (VDialog.ts:238)
at VueComponent.onFocusin (VDialog.ts:238)
...
My view includes the same component twice as you can see below. Each uses a different slot. If I include the component once I do not get this error.
How to replicate the error:
1. Open the dialog
2. click close on on the dialog card
3. re-open the dialog
4. Click close again
5. The error appears
Main.vue
<CreateProjectDialog>
<template v-slot:default="slotProps">
<v-btn v-on="slotProps.dialog.on" color="primary" class="white--text">
Project <v-icon>mdi-plus</v-icon>
</v-btn>
</template>
</CreateProjectDialog>
<CreateProjectDialog>
<template v-slot:default="slotProps">
<v-btn
v-on="slotProps.dialog.on"
class="ma-5 mr-md-12"
fixed
x-large
fab
bottom
right
color="primary"
>
<v-icon>mdi-plus</v-icon>
</v-btn>
</template>
</CreateProjectDialog>
CreateProjectDialog component
<template>
<div>
<v-dialog v-model="dialog" max-width="600px">
<template v-slot:activator="{ on }">
<slot v-bind:dialog="{ on }"></slot>
</template>
<v-form ref="form" v-model="valid">
<v-card>
<v-card-title class="justify-center">
</v-card-title>
<v-card-text>
</v-card-text>
<v-card-actions>
<v-btn color="blue darken-1" text #click="dialog = false">Close</v-btn>
<v-btn color="blue darken-1 white--text" #click="submitProject" :disabled="!valid">Create</v-btn>
</v-card-actions>
</v-card>
</v-form>
</v-dialog>
</div>
</template>
I use this computed property to calculate the dialog value through an observer in store.js
createProjectDialog component
computed: {
dialog: {
get () {
return getters.projectDialog();
},
set (val) {
mutations.toggleProjectDialog(val);
}
}
},
store.js
import Vue from 'vue';
const state = Vue.observable({
projectDialog: false
});
export const getters = {
projectDialog () {
return state.projectDialog;
}
};
export const mutations = {
toggleProjectDialog (val) {
state.projectDialog = val;
}
};
If I remove the computed property dialog entirely, and instead return a normal data property it works.
export default {
data () {
return {
dialog: false
}
}
}
I want to understand why this happens exactly and how I can make it work with the observer.
Is there a better way of handling this instead of using slots?

Vuex state undefined

Versions:
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vuetify": "^1.0.0",
"vuex": "^3.0.1"
I have a simple vuex store with 1 state property(meetUps) and 2 getters(featuredMeetups & listMeetups). featuredMeetups is fine, when i do console log i can see the array of objects. But, listMeetups is undefined, I have been trying to figure out for a long time, can someone please tell me why one would work and not the other
/* eslint-disable */
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
meetUps: [
{
imageUrl: 'https://www.seetorontonow.com/wp-content/uploads/2017/12/cn-tower-dusk.jpg',
id: 0,
title: 'Meetup in Toronto',
date: '2018-08-01'
},
{
imageUrl: 'https://dminc.com/wp-content/uploads/2017/09/Montreal-copy.jpg',
id: 1,
title: 'Meetup in Montreal',
date: '2018-08-09'
},
{
imageUrl: 'https://www.tripsavvy.com/thmb/Rps6KG7F6Fc1lXtcSaGZJJ3oVE4=/960x0/filters:no_upscale():max_bytes(150000):strip_icc()/quebec-city-skyline-in-winter-548633225-5986417f22fa3a001072905e.jpg',
id: 3,
title: 'Meetup in Qubec City',
date: '2018-08-19'
}
]
},
mutations: {},
actions:{},
getters: {
featuredMeetups: state => {
return state.meetUps.splice(0,5)
},
listMeetups: state => {
return state.meetUps
}
}
})
//Vue componenet
<template>
<v-container>
<v-layout row wrap v-for="meetup in meetups" :key="meetup.id" class="mb-2">
<v-flex xs12 sm10 md8 offset-sm1 offset-md2>
<v-card color="blue-grey light-2" class="white--text">
<v-container fluid>
<v-layout xs5>
<v-flex xs5 sm4 md3>
<v-card-media class="white--text elevation-20" height="130px" :src="meetup.imageUrl">
</v-card-media>
</v-flex>
<v-flex xs7 sm8 md3>
<v-card-title primary-title>
<div>
<h3 class="white--text" mb0>{{ meetup.title }}</h3>
<div>{{ meetup.date }}</div>
</div>
</v-card-title>
<v-card-actions>
<v-btn flat to="/meetup/1">
<v-icon left light>arrow_forward</v-icon>
View Meetups
</v-btn>
</v-card-actions>
</v-flex>
</v-layout>
</v-container>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
export default {
computed: {
meetups () {
//return this.$store.state.meetUps
return this.$store.getters.listMeetups
}
}
}
</script>
In fact you are using splice rather than slice JavaScript method.
It's two diferents behaviours.
The splice() method adds/removes items to/from an array, and returns the removed item(s).
The slice() method returns the selected elements in an array, as a new array object.
Here you can find your problem solved using slice ;)
https://codesandbox.io/s/52031kl03x