How do I overcome error 'Avoid using JavaScript keyword as "v-on" value' - vuejs2

How do I get rid of this error in my App.vue component?
Failed to compile.
./src/App.vue
Module Error (from ./node_modules/eslint-loader/index.js):
C:\xampp2\htdocs\exchproto\src\App.vue
15:69 error Avoid using JavaScript keyword as "v-on" value: "" vue/valid-v-on
✖ 1 problem (1 error, 0 warnings)
I tested the whole code (including sub-components) with CDN pull of vuejs/vuetify css/js etc and all worked well. This error only comes up as I am breaking down the code into components and doing everything by "yarn install". Been poking at it for some time with no luck.
<template>
<v-app>
<v-app-bar app>
<v-app-bar-nav-icon #click="drawer = !drawer"></v-app-bar-nav-icon>
<v-spacer></v-spacer>
<v-menu :offset-y="true">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on">
<v-icon>mdi-dots-horizontal</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item v-for="(item, i) in rightMenuitems" :key="i" #click="">
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-app-bar>
<!--router-view></!--router-view-->
</v-app>
</template>
<script>
export default {
name: 'App',
components: {},
data() {
return {
drawer: false,
rightMenuitems: [
{ title: 'Choice 1' },
{ title: 'Choice 2' },
{ title: 'Choice 3' },
{ title: 'Choice 4' }
],
}
}
}
</script>

You can't have an empty #click="" You must have the click point to a function:
<v-list-item
v-for="(item, i) in rightMenuitems"
:key="i"
#click="doSomething($event, i)"
>
<v-list-item-title>
{{ item.title }}
</v-list-item-title>
</v-list-item>
// ...
methods: {
someFunction(event, i) {
console.log("clicked item " + i);
}
}
// ...

Remove 'click event' and add to property in v-list-item where v-for is being used.
Note:
You can bind links with the to props, and also links in every objects of rightMenuitems.
Here is an example:

Related

Vuetify How to update component data when list item group select changed

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.

Remove active class from v-list-item when v-list-group item is selected

Using Vuetify v-list-item directive (outside) with others v-list-item inside the v-list-group for routing website's pages I'm encountering this issue:
The routing works fine, but every time I click on one of the submenues the index item is still active
When Index is selected
When another item is selected
I want to know if there is something I can do to deactivate the active class of index menu v-list-item when I select a v-list-item inside the v-list-group
Here is my code:
DOM:
<v-navigation-drawer v-model="drawer" app dark>
<v-list>
<div
v-for="item in pages"
:key="item.title"
>
<!-- Index -->
<v-list-item
v-if="!item.items"
link
:to="item.href"
v-on="on"
>
<v-list-item-icon>
<v-icon color="info">
{{item.icon}}
</v-icon>
</v-list-item-icon>
<v-list-item-title class="info--text" v-text="item.title">
</v-list-item-title>
</v-list-item>
<!-- group menues -->
<v-list-group
v-if="item.items"
item-color="primary"
no-action
>
<template v-slot:activator>
<v-icon color="info" style="padding-right:32px">
{{item.icon}}
</v-icon>
<v-list-item-content>
<v-list-item-title class="info--text" v-text="item.title"></v-list-item-title>
</v-list-item-content>
</template>
<v-list-item
item-color="primary"
v-for="child in item.items"
:key="child.title"
link
:to="child.href"
style="padding-left:40px"
>
<v-list-item-icon>
<v-icon color="info">mdi-circle-medium</v-icon>
</v-list-item-icon>
<v-list-item-content v-on="on">
<v-list-item-title class="info--text" v-text="child.title"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-group>
</div>
</v-list>
</v-navigation-drawer>
Script:
data: () => ({
drawer: true,
pages: [
{
icon: 'mdi-home',
title: 'Index',
href: '/main'
},
{
icon: 'mdi-bell',
items: [
{
title: 'submenu1',
href: '/main/menu1/submenu1'
},
{
title: 'submenu2',
href: '/main/menu1/submenu2'
}
],
title: 'menu1'
},
{
icon: 'mdi-cog-outline',
items: [
{
title: 'submenu3',
href: '/main/menu2/submenu3'
}
],
title: 'menu2'
},
{
icon: 'mdi-text-box-outline',
items: [
{
title: 'submenu4',
href: '/main/menu3/submenu4'
}
],
title: 'menu3'
}
] })
Thank you!
I found out what the problem was. I was misunderstanding the concept of routing using Vue.
The index item was routing to /main (/main/index), and the others pages included 'main' on their routes, like so: /main/submenu1. Vue understood /main/submenu1 as if it was over main, so /main was "active" too as it contained the same name in the route.
I fixed this by changing the /main route to /main/home. By forcing the route path to be different from the others. I tried using /main/index because Vue was pointing to index the whole time but it didn't work. I just needed to change the page name and the route path.

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 can I solve the issue with redirection?

I am setting up a new project on nuxt and I've made one new layout for a login page, and created a page login.
In my default layout I am setting middleware: 'auth' and in my middleware I am checking for a token and if not authenticated I am redirecting the user to the login page.
The funny thing is that when I've just set it up it worked fine but after some time (I tried to go back with my code to find the issue) I started to receive an Error Redirected when going from "/" to "/login" via a navigation guard.
I don't have any redirects but the one in the auth middleware.
What can be a problem here that I cannot see?
// middleware/auth.js
export default ({ app, error, redirect }) => {
const hasToken = !!app.$apolloHelpers.getToken()
if (!hasToken) {
error({
errorCode: 503,
message: 'You are not allowed to see this'
})
return redirect('/login')
}
}
// layouts/default.vue
<template>
<v-app dark>
<v-navigation-drawer
v-model="drawer"
:mini-variant="miniVariant"
:clipped="clipped"
fixed
app
>
<v-list>
<v-list-item
v-for="(item, i) in items"
:key="i"
:to="item.to"
router
exact
>
<v-list-item-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title v-text="item.title" />
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar :clipped-left="clipped" fixed app>
<v-app-bar-nav-icon #click.stop="drawer = !drawer" />
<v-btn icon #click.stop="clipped = !clipped">
<v-icon>mdi-application</v-icon>
</v-btn>
<v-toolbar-title v-text="title" />
<v-spacer />
</v-app-bar>
<v-main>
<v-container>
<nuxt />
</v-container>
</v-main>
<v-footer :absolute="!fixed" app>
<span>© {{ new Date().getFullYear() }}</span>
</v-footer>
</v-app>
</template>
<script>
export default {
middleware: ['auth'],
data() {
return {
clipped: false,
drawer: true,
fixed: true,
items: [
{
icon: 'mdi-apps',
title: 'Welcome',
to: '/',
},
{
icon: 'mdi-account-group-outline',
title: 'Clients',
to: '/clients',
},
{
icon: 'mdi-briefcase-check-outline',
title: 'Orders',
to: '/orders',
},
{
icon: 'mdi-briefcase-clock-outline',
title: 'Pending Orders',
to: '/pending-orders',
},
],
miniVariant: false,
right: true,
rightDrawer: false,
title: 'Title',
}
},
}
</script>
// layouts/login.vue
<template>
<v-app dark>
<v-main>
<v-container>
<nuxt />
</v-container>
</v-main>
</v-app>
</template>
<script>
export default { }
</script>
// pages/login.vue
<template>
<div>test login</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
Sorry) apparently I removed layout property from the login page component

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