ES-Lint complains on used props values, when it's in use - vuejs3

Given this following Vue3 sfc code:
<template>
<div>{{msg}}</div>
</template>
<script setup>
const props = defineProps({
msg: {
type: String,
default: 'Hello world'
}
})
</script>
ES-Lint is complaining that the props is assigned a value but never used. We know also that the options passed to defineProps ('msg' in this case) will be hoisted out of setup into module scope, so the syntax is correct.
I don't want to disable the no-unused-vars ES-lint rule, nor do I wish to dismiss it by using an ES-lint ignore comment, so how can I fix this?

It seems like this error was caused due to incompatibility between my devenvironment and ESLint's current parsing capabilities.
To fix this (plus some other eslint errors that occured), I added the following package to the project:
yarn add -D babel-eslint
then added this Parsing option til my .eslingrc.js file:
parser: 'babel-eslint'

Related

What is the benefit to use useNuxtApp() on Nuxt3?

I'd like to know about new Nuxt3 feature called useNuxtApp.
Official document says, to use provide, you can do like below.
const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => `Hello ${name}!`)
console.log(nuxtApp.$hello('name')) // Prints "Hello name!"
However it seems like you can also still use provide/inject.
For instance, I define the method 'hello' on parent component, then I also want to use it on child component, I can provide 'hello' for child from parent component and inject it.
You can still do same things by using provide/inject, so does anyone know what is the benefit using useNuxtApp?? And what is the difference between provide/inject and useNuxtApp except for syntax??
useNuxtApp built-in composable of Nuxt3
It is used to access shared runtime context of Nuxt available in server / client side, like: Vue App Instance, Runtime Hooks, Runtime Config Variables, Internal States etc.
Example:
i) ssrContext,
ii) payload,
iii) helper methods etc.
Values getting by this composable will be available across all composables, components, plugins (all files of .vue)
In Nuxt 2, this was referred to as "Nuxt Context"
Let's see an example how it can be use in Nuxt Plugin and by extending the plugin how it will give us a helper method and how we can use that helper method to get value to the rest of Nuxt Application.
say, we have a plugin in ~/plugins/my-plugin.js, where returning "provide" option as helper method.
in ~/plugins/my-plugin.js file
export default defineNuxtPlugin(() => {
...
return {
provide: {
hello: (msg: string) => `Hello ${msg}!`
}
}
...
})
in any template (pages, components or any .vue file of the Nuxt App)
<template>
<div>
{{ $hello('world') }}
</div>
</template>
<script setup>
const { $hello } = useNuxtApp()
</script>
// or
<script setup>
const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => `Hello ${name}!`)
console.log(nuxtApp.$hello('name')) // Prints "Hello name!"
</script setup>

Vue3 issue when trying to use Auth0 plugin's useAuth0 in setup block

I am trying to learn Vue3 on a hobby project and have an issue when trying to set up Auth0 using their SDK in the App.vue file and I'm hoping someone can explain the issue!
I've followed the docs but converted (I think) the code to use the <script setup>...</script> syntax but I am getting an error when using the useAuth0 function in my setup. Vue is warning that inject() can only be used inside setup() or functional components..
If I call inject directly in the setup block it works, and if I copy the code for useAuth0 in to a file in my application and import and call it resolves it and the login method works.
I don't understand why the provided implementation doesn't work when copying the code does - could anyone please explain that?
When copying the code the loginWithRedirect function works but the other items on on the auth0 client don't seem to (it seems to be stuck as isLoading: true
Here's the relevant code
I've registered the plugin in the main.ts and then trying to use it in app.vue to add a login button - there seemed to be a type issue with the plugin hence the any cast for now
main.ts
const auth0Plugin = createAuth0({
domain: "dev-9vwsdbs4.us.auth0.com",
client_id: "HtmGSIyIGplusxDGTo1VwWVXebgOfIVM",
redirect_uri: window.location.origin,
});
app.use(auth0Plugin as any);
app.vue
<script setup lang="ts">
import { RouterView } from "vue-router";
import { useAuth0 } from "#auth0/auth0-vue";
const { loginWithRedirect, isLoading } = useAuth0();
</script>
<template>
<RouterView />
<p>{{ isLoading }}</p>
<button #click="loginWithRedirect">Login</button>
</template>
This is the output in the console:
[Vue warn]: inject() can only be used inside setup() or functional components.
runtime-core.esm-bundler.js:38 [Vue warn]: Unhandled error during execution of setup function
App.vue:4 Uncaught TypeError: Cannot destructure property 'loginWithRedirect' of 'useAuth0(...)' as it is undefined.

How fix language change issues in production when no error in console using next-i18next?

my changeLanguage function is not working in production. Using the debug functionality of i18n i do not have any warning, more so the language change is detected correctly each time i click on the select menu.
i have log locale on the console and it returns undefined
Can someone explain to me what i do wrong, please? See below my changeLanguage
const changeLanguage = (e) => {
const locale = e.target.value;
i18n.changeLanguage(locale);
router.push(router.pathname, router.asPath, { locale });
};
You don't need to have a function to change the locale.
With nextjs you have router(), this fit perfectly to any cases.
Also, you have <Link> with locale property.
1st possible way - change locale with URL. So, you can .map your locales with links and then change it.
<Link href='/test' locale={router.locale} key="your_key">
<a>test</a>
</Link>
2nd possible way - change with function
router.push("/test", null, {locale: "your_desired_locale_or_variable"})
Your locales are defined in your config file, probably you have en locale and not en-us

Vue 3 components with slots in vendor folder

I have an issue where I want to extract all my components out into a separate repository but I want to load them in via composer instead of npm (business decision).
This was all working fine. Add it as a dependancy in the composer.json file and then add the following to the webpack.mix.js file;
mix.webpackConfig({
resolve: {
alias: {
'#ui' : path.resolve(__dirname, 'vendor/companyname/ui/src'),
}
}
});
And then use the following to import them in;
import PrimaryButton from "#ui/buttons/primary";
Which all worked fine!
Until I wanted to use slots. If I include a slot I get the following error;
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'nodeName')
at new create (svg.js?1929:3616)
at globalRef.SVG (svg.js?1929:31)
at Proxy.mounted (Editor.vue?721f:63)
at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:154)
at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:163)
at Array.hook.__weh.hook.__weh (runtime-core.esm-bundler.js?5c40:2909)
at flushPostFlushCbs (runtime-core.esm-bundler.js?5c40:357)
at flushJobs (runtime-core.esm-bundler.js?5c40:393)
In this example the component looks like this;
<template>
<button #click="click">
<slot></slot>
</button>
</template>
<script>
export default {
emits: ['click'],
methods: {
click() {
this.$emit('click')
}
}
}
</script>
Now, if I copy this component into the project repository and load it in that way, there is no error and works as intended!
Can anyone point me in the direction of where I am going wrong please.
Update
I have removed other components from view I'm rendering and now have a new error;
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'isCE')
at renderSlot (runtime-core.esm-bundler.js?c099:5832)
at Proxy.render (primary.vue?f782:3)
at renderComponentRoot (runtime-core.esm-bundler.js?5c40:1166)
at componentEffect (runtime-core.esm-bundler.js?5c40:5201)
at reactiveEffect (reactivity.esm-bundler.js?a1e9:42)
at effect (reactivity.esm-bundler.js?a1e9:17)
at setupRenderEffect (runtime-core.esm-bundler.js?5c40:5154)
at mountComponent (runtime-core.esm-bundler.js?5c40:5113)
at processComponent (runtime-core.esm-bundler.js?5c40:5071)
at patch (runtime-core.esm-bundler.js?5c40:4673)
Update
This is not the answer but the reason for this, from what I can tell is that there were two instances of Vue in play, one from the library and one in my application. I have no idea how to stop this but if I push the contents up to a repo and pull it in via npm then it works normally. Still would like to know how to get this running locally without using npm.

Automatic case transformation for events in vue3

I have a Vue3 component that emits multiple events. I want to pass the callbacks in a dedicated callback object like this:
// template section
<!-- emits event-a and event-b in kebap-case -->
<my-component v-on="myCallbacks" />
// script section
const myCallbacks={
'event-a': function() { // kebap-case does *not* work
...
},
eventA: function() { // camel-case works !
...
},
eventB: function() {
...
}
}
The docs state that in Vue3, unlike in Vue2, there is an automatic event name transformation (apparently into kebap-case).
Why can't I use the expected kebap-case in the callback?
Did I miss a more appropriate design pattern that could replace such a callback object and is still concise?
Is this name transformation on a callback object standard behavior or subject to change? Is it documented somewhere?
I hardly found anything in the docs about using v-on without the event specifier (i.e. v-on="callback" instead of v-on:event-a="eventA" v-on:event-b="eventB").
// Update
In the Vue2 doc and Vue3 doc, they mention that this is called the "object syntax" - however, nothing is written about case transformation.
<!-- object syntax (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

Resources