Vue3 with vuetify alpha - vue.js

I am trying to install the latest version of Vuetify 3 with Vue 3 but I am getting an error at run time. I am upgrading from Vue2 to Vue3. It doesn't appear I am integrating Vuetify correctly. I have spent all labor day trying to figure this one out.
Uncaught TypeError: Cannot read properties of undefined (reading 'lgAndUp')
It's coming from my Vue component:
<template>
<div
:class="{
'mx-5 px-5 pt-5': $vuetify.breakpoint.lgAndUp,
'py-5 my-3 px-0': $vuetify.breakpoint.mdAndDown
}"
id="login_router_wrapper"
>
<router-view id="login_router"></router-view>
</div>
</template>
<script>
import { mapState, mapActions, mapMutations } from 'vuex';
export default {
props: ['errors'],
data() {
return {};
},
async created() {},
destroyed() {},
computed: {},
methods: {}
};
</script>
<style></style>
My main login_app.js
import 'material-design-icons-iconfont/dist/material-design-icons.css';
import 'vuetify/styles' // Global CSS has to be imported
import { createApp } from 'vue';
import store_login from './store/index-login.js';
import router from './router/index-login.js';
import my_vuetify from './vuetify.js';
import AuthRouter from './components/auth/AuthRouter.vue';
import AuthEntrypoint from './components/auth/AuthEntrypoint.vue';
const login_app = createApp({
data() {
return {
message: 'Hello root Component 1'
};
},
components: {
'auth-router': AuthRouter,
'auth-entrypoint': AuthEntrypoint,
},
});
login_app.use(store_login)
.use(router)
.use(my_vuetify)
.mount('#app-login');
My store
import {createStore} from 'vuex';
import auth from './auth/auth.js';
import loader from './util/loader.js';
import error from './util/error.js';
const store_login = createStore({
modules: {
auth,
loader,
error
},
state: {
errors: []
},
mutations: {},
getters: {},
actions: {}
});
export default store_login;
My router
import { createRouter, createWebHistory } from 'vue-router';
import auth from './auth.js';
import AuthRouter from '../components/auth/AuthRouter.vue';
import authResetPassword from './authResetPassword.js';
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/login',
props: true,
component: AuthRouter,
children: [...auth]
},
{
path: '/password',
props: true,
component: AuthRouter,
children: [...authResetPassword]
}
]
});
export default router;
Then Vuetify
import {createVuetify} from 'vuetify';
import 'vuetify/styles' // Global CSS has to be imported
const my_vuetify = createVuetify({
iconfont: 'mdi', // 'md' || 'mdi' || 'fa' || 'fa4'
theme: {
options: {
customProperties: true
},
light: true,
themes: {
light: {
primary: '#9E9E9E',
secondary: '#b0bec5',
accent: '#8c9eff',
error: '#b71c1c',
background: '#fafafa'
}
}
}
});
export default my_vuetify;

Related

Storybook - Set and get Vuex state

I try to use Storybook in a Nuxt project. Story file looks similar to
import Chip from '~/components/UI/Chip.vue'
import store from '#/storybook/store';
export default {
title: 'Chips',
component: Chip,
}
const Template = (args, { argTypes }) => ({
store: store,
props: Object.keys(argTypes),
components: { Chip },
});
export const Primary = Template.bind({})
Primary.args = {
color: 'background-darken-4'
}
And Store
import Vue from 'vue'
import Vuex from 'vuex'
import themes from '~/components/PassporterUI/themes/index'
import ThemeCollection from '~/models/ThemeCollection'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
theme: undefined,
},
mutations: {
theme(state) {
const defaultTheme = themes.find(
(theme) => theme.name === 'passporter-light'
)
if (defaultTheme) {
state.theme = new ThemeCollection({
current: defaultTheme,
list: themes,
})
}
},
},
actions: {
setTheme({ commit }) {
commit('theme', state.theme)
},
},
})
Returns this multiple errors
Do, anyone knows what is the right way to fix this?

Uncaught Error: [vuex] getters should be function but "getters.products" in module "prods" is []

I've reduced this code to the bare minimal, but I'm still not sure where this problem is coming from, but this is the first sentence of the error:
Uncaught Error: [vuex] getters should be function but "getters.products" in module "prods" is []
This is my main.js:
import { createApp } from 'vue';
import router from './router.js';
import storage from './store.js';
import App from './App.vue';
const app = createApp(App);
app.use(router);
app.use(storage);
app.mount('#app');
This is my router.js:
import { createRouter, createWebHistory } from 'vue-router';
import ProductsList from './ProductsList.vue';
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', redirect: '/products' },
{ path: '/products', component: ProductsList },
]
});
export default router;
This is my store.js:
import { createStore } from 'vuex';
// import productsModule from './products.js';
const products = createStore({
namespaced: true,
state() {
return {
allProducts: [
{
id: 'p1',
image: "",
title: 'Books',
description: 'Books collection.',
price: 20
},
]
};
},
getters: {
products(state) {
return state.allProducts;
}
}
})
const store = createStore({
modules: {
prods: products,
},
});
export default store;
This is my App.vue minus the style:
<template>
<the-header></the-header>
<router-view></router-view>
</template>
<script>
import TheHeader from './TheHeader.vue';
export default {
components: {
TheHeader
},
}
</script>
This is my ProductsList.vue minus the style:
<template>
<section>
<ul>
<product-item
v-for="prod in products"
:key="prod.id"
:id="prod.id"
:title="prod.title"
:image="prod.image"
:description="prod.description"
:price="prod.price"
></product-item>
</ul>
</section>
</template>
<script>
import ProductItem from './ProductItem.vue';
export default {
// inject: ['products'],
components: {
ProductItem,
},
computed: {
products() {
return this.$store.getters['prods/products'];
}
}
};
</script>
And this is my ProductItem.vue minus the style:
<template>
<li class="product">
<div class="product__data">
<div class="product__image">
<img :src="image" :alt="title" />
</div>
<div class="product__text">
<h3>{{ title }}</h3>
<h4>${{ price }}</h4>
<p>{{ description }}</p>
</div>
</div>
<div class="product__actions">
<button>Add to Cart</button>
</div>
</li>
</template>
<script>
export default {
props: ['id', 'image', 'title', 'price', 'description'],
};
</script>
My code including the styles and the workable products.js can be found at:
https://github.com/maxloosmu/vue-complete/tree/main/15/vuex-0012/src
Could someone help point me to why this way of using Vuex getters is wrong? Or is it due to another problem with Vuex?
I've discovered an answer to my question. In my store.js, I do not use createStore twice, but just once. That will resolve the problem:
import { createStore } from 'vuex';
const products = {
namespaced: true,
state() {
return {
allProducts: [
{
id: 'p1',
image: "",
title: 'Books',
description: 'Books collection.',
price: 20
},
]
};
},
getters: {
products(state) {
return state.allProducts;
}
}
}
const store = createStore({
modules: {
prods: products,
},
});
export default store;

[Vue warn]: Error in render: "TypeError: Cannot read property 'getters' of undefined"

this is my app.js
Have I defined the items correctly?
I think I did my job right! In accordance with the vuex document
import store from "./store";
require('./bootstrap');
window.Vue = require('vue').default;
import vuetify from "./vuetify";
import router from "./router";
import AppComponent from "./components/AppComponent";
import Store from "./store"
const app = new Vue({
el: '#app',
vuetify,
router,
Store,
components:{
"app-component":AppComponent,
}
});
this is my store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const departmentRoute= [
{ icon: 'mdi-account-badge-outline', text: 'مدیریت مطالبات ' ,link:'demands'},
{ icon: 'mdi-account-badge-outline', text: 'مدیریت گزارشات ' ,link:'reports'},
];
const SuperAdminRoute= [
{ icon: 'mdi-account-group-outline', text: ' مدیریت کاربران ' ,link:'users'},
{ icon: 'mdi-account-badge-outline', text: 'مدیریت مطالبات ' ,link:'demands'},
{ icon: 'mdi-account-badge-outline', text: 'مدیریت گزارشات ' ,link:'reports'},
{ icon: 'mdi-account-badge-outline', text: 'آمار و ارقام ' ,link:'demands'},
];
const studentRoute= [
{ icon: 'mdi-account-group-outline', text: 'آخرین مطالبات به رای گذاشته شده' ,link:'selfDemand'},
{ icon: 'mdi-account-group-outline', text: 'مطالبات من ' ,link:'selfDemand'},
{ icon: 'mdi-account-badge-outline', text: ' پیگیری مطالبه ' ,link:'addReport'},
{ icon: 'mdi-checkbox-marked-circle-outline', text: 'تایید حساب کاربری' ,link:'verify'},
];
export default new Vuex.Store({
state: {
level: localStorage.getItem('role')
},
getters: {
items: state => {
switch (state.level) {
case "super-admin":
return SuperAdminRoute;
case "department":
return departmentRoute;
default:
return studentRoute;
}
}
}
})
and this is my app component script:
<script>
import { mapGetters } from 'vuex'
export default {
name: "MainDashboard",
props: {
source: String,
},
computed: {
...mapGetters(['items'])
},
data: () => ({
drawer: null,
title:'فاد | فارغ التحصیلی ناد',
}),
methods:{
logout() {
axios.post('/api/logout').then(res=>{
localStorage.removeItem('token');
localStorage.removeItem('role');
this.$router.push('/login');
}).catch(err=>{
});
}
}
}
</script>
when i use map getters in my componenet i can get my getters in vuex tab but i can't get it in component computed property !
why ?
How can I troubleshoot?Could this error be due to invalid import vuex ?
Vuex Tab :
component :
You must use store in app.js or main.js like this:
import Vue from "vue";
import App from "./App.vue";
import store from "./store";
Vue.config.productionTip = false;
new Vue({
render: (h) => h(App),
store
}).$mount("#app");
if you use like import {store} from "./store"; you get this error.
i changed this line from
import Store from "./store"
to :
import store from "./store"
and my problem was solved !

Error when calling method from mounted Property 'function' does not exist on type

I get this error "Property 'load' does not exist on type '{ name: string; components: { IonHeader:"
When I'm trying to call the function load from mounted().
Message shows in console but I get this error.
<script lang="ts">
import {
IonHeader,
IonToolbar,
IonTitle,
IonContent,
//IonIcon,
//IonButtons,
IonButton,
alertController,
} from "#ionic/vue";
import { logOut, add } from "ionicons/icons";
import { mapActions, mapGetters } from "vuex";
import { useRouter } from "vue-router";
import "../style/Home.scss";
export default {
name: "ListDatos",
components: {
IonHeader,
IonToolbar,
IonTitle,
IonContent,
IonButton,
},
data() {
return {
msg: "",
datos: [],
};
},
setup() {
const router = useRouter();
return {
add,
};
},
mounted() {
console.log("Test mounted");
this.load();
},
methods: {
load(){
console.log("function load()");
},
},
};
</script>
That is because TypeScript is trying to guess the type and since you are doing: export default {...all your code...} for TS that is just an object, you need to indicate that it is not just an object and in fact it is a Vue component, here is the code extracted from the docs (check the docs here)
import Vue from 'vue'
const Component = Vue.extend({
// type inference enabled
})
As you can see on that code, the component definition is wrapped in Vue.extend() so you could have your code:
export default Vue.extend({
//...your component...
})

Camera mobile used for progressive web app

I realize a progressive application web app under view and I have a problem for the use of the mobile camera. I have a blank page. Here is my file seen for the camera:
<template>
<div class="container" id="app">
<router-link class="waves-effect waves-light btn" to="/livreur" #click.native="hideMenu"><i class="material-icons">arrow_back</i>
</router-link>
<div class="camera-modal">
<video ref="video" class="camera-stream"/>
</div>
</div>
</template>
<script>
var constraints = {
audio: false,
video: {
facingMode: {exact: 'environment'}
}
}
export default {
mounted () {
navigator.mediaDevices.getUserMedia(constraints)
.then(function (mediaStream) {
var video = document.querySelector('video')
video.srcObject = mediaStream
video.onloadedmetadata = function (e) {
video.play()
}
})
.catch(function (err) {
console.log(err.name + ': ' + err.message)
})
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>
My file main.js:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import Axios from 'axios'
import VueSignature from 'vue-signature-pad'
Vue.prototype.$http = Axios
const token = localStorage.getItem('user-token')
if (token) {
Vue.prototype.$http.defaults.headers.common['Authorization'] = token
}
Vue.use(VueSignature)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
My router.js file:
import Vue from 'vue'
import Router from 'vue-router'
import store from './store.js'
import Home from '#/components/Home'
import Delivered from '#/components/Delivered'
import Absent from '#/components/Absent'
import Refused from '#/components/Refused'
import Livreur from '#/components/preprations/Livreur'
import Prepa from '#/components/preprations/Prepa'
import Scan from '#/components/preprations/Scan'
import Login from '#/components/Login'
Vue.use(Router)
let router = new Router({
routes: [
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/delivered',
name: 'delivered',
component: Delivered
},
{
path: '/absent',
name: 'absent',
component: Absent
},
{
path: '/refused',
name: 'refused',
component: Refused
},
{
path: '/livreur',
name: 'livreur',
component: Livreur
},
{
path: '/prepa',
name: 'prepa',
component: Prepa
},
{
path: '/scan',
name: 'Scan',
component: Scan
}
]
})
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (store.getters.isLoggedIn) {
next()
return
}
next('/login')
} else {
next()
}
})
export default router
I tried to change the constraints but nothing helps, I try the default values ​​but it does not work.
I do not see where it's blocking at all. Thank you for your help.