Vue3 Test error after the integration of vue-i18n - vue.js

I integrated vue18n into my vue3 application. Everythings works fine but when I try to execute my unit tests (I'm using Jest) I have an error:
TypeError: Cannot read properties of undefined (reading 'deep')
As I wrote, I have errors only during the testing phase.
During my analysis I discovered that, probably, the issue it's related to a nested component.
I start the test from a component 'list', I trigger the click on a list item in order to show this 'popup' component.
In my test I initialize the component 'list' using mount instead of the shallowMount.
In this nested component "popup" I have this template:
<template>
<full-screen-popup ref="popup">
<div class="confirm-dialogue-container">
<div class="dialog-header">
<h1 id="confirm-title-lbl" v-t="titleKey"></h1>
<i18n-t :keypath="messageKey" tag="h2" id="confirm-message-lbl" scope="global">
<template v-slot:name>
<b id="confirm-name-lbl">{{name}}</b>
</template>
<template v-slot:surname>
<b id="confirm-surname-lbl">{{surname}}</b>
</template>
</i18n-t>
</div>
<div class="actions-container">
<button id="bt-confirm-delete" class="btn-action primary" v-t="confirmLblButton" #click="_confirm"></button>
<button id="bt-cancel-delete" class="btn-action " v-t="cancelLblButton" #click="_cancel"></button>
</div>
</div>
</full-screen-popup>
</template>
If I try to remove this content I don't have the error (obviously, I have other errors because the html dom will be empty).. but probably the issue it's related to this code.
I'm not able to understand the reason.
Any suggestions?

Related

The client-side rendered virtual DOM tree is not matching server-rendered content

Versions
nuxt: ^2.14.12
node: v14.15.4
Reproduction
Hello everyone and thank you in advance.
I have a strange issue that I don't really understand what's the problem and how to deal with it.
I have installed a fresh nuxt ssr project.
I'm getting the following warning
[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
I have three simple components: Form, Input, Button.
Form.vue
<template>
<form v-bind="$attrs" class="w-full" #submit.prevent="$emit('submitted')">
<div class="space-y-2 mb-4">
<slot name="fields" />
</div>
<slot name="button" />
</div>
</form>
</template>
<script>
export default {
computed: {
hasFields() {
return !!this.$slots.fields
},
},
}
</script>
Input.vue
<template>
<div class="relative w-full">
<input class="form-input block w-full" />
</div>
</template>
<script>
export default {
inheritAttrs: false,
}
</script>
Button.vue
<template>
<button
type="submit"
class="relative btn inline-flex items-center justify-center transition ease-in-out duration-150"
>
Save
</button>
</template>
<script>
export default {}
</script>
I use my components in pages/index.vue like this:
<template>
<div>
<Form>
<template #fields>
<Input />
<Input />
</template>
<template #button>
<Button />
</template>
</Form>
<Form>
<template #fields>
<Input />
<Input />
</template>
<template #button>
<Button />
</template>
</Form>
</div>
</template>
<script>
export default {}
</script>
If i use the Form component only once in the view i don't get the warning.
If i use it twice i get it.
Steps to reproduce
Reproduction link
Install a fresh nuxt ssr project.
Create the components as in the reproduction link
What is Expected?
All the components to render normally without any warnings or errors.
What is actually happening?
I get the following warning.
[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
Some extra notes
I know that wrapping the whole thing inside a <client-only> fixes the problem but i want to understand why is this happening in order to avoid it in future cases.
Also if I remove components: true from nuxt.config.js and import the components normally again the warning is gone.
Changing the name of the components eg Button -> TheButton won't fix the problem. You can see the reproduction here.
<script>
import Input from '~/components/Input'
import Button from '~/components/Button'
import Form from '~/components/Form'
export default {
components: { Form, Button, Input}
}
</script>
There seems to be one or more components which are not supported in "Universal" Mode, i.e. they might have code which isn't being executed correctly on server end.
Please try finding that component which you think can cause an issue and wrap that component with .
Here's the link for more information: https://nuxtjs.org/docs/2.x/features/nuxt-components#the-client-only-component

Framework7 component not works in Vue2

I want to add f7-timeline component in my Vue app.
I added Framework7 and Framework7Vue in my app.js file. Other Framework7 components like <f7-button> and <f7-progressbar> works properly. But when I use <f7-timeline>, give this error in console :
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> at src/pages/timeline/timeline.vue
<F7View>
<F7App>
<App> at src/app.vue
<Root>
<template>
<f7-page>
<f7-timeline>
<f7-timeline-item day="21" month="DEC" inner content="Some text goes here"></f7-timeline-item>
<f7-timeline-item day="22" month="DEC" inner content="Another text goes here"></f7-timeline-item>
</f7-timeline>
<f7-button>Button Text</f7-button>
<f7-progressbar :progress="20"></f7-progressbar>
</f7-page>
</template>
Any help will greatly be appreciated.
f7-timeline is used by Framework7 Vue.js V1 and its deprecated. in the Latest Version (4.1.1) you can display your timeline using normal HTML like this:
<div class="timeline">
<div class="timeline-item">
<div class="timeline-item-date">21 <small>DEC</small></div>
<div class="timeline-item-divider"></div>
<div class="timeline-item-content">
<div class="timeline-item-inner">
<div class="timeline-item-time">12:30</div>
<div class="timeline-item-title">Title</div>
<div class="timeline-item-subtitle">Subtitle</div>
<div class="timeline-item-text">Text</div>
</div>
</div>
</div>
<div class="timeline-item">
... another timeline item ...
</div>
</div>
For more information, you can check the Framework7 Vue.js Kitchen skin for timeline demo.

What does it actually means - Use created + activated for keep-alive components in Vuejs

Initially, I am fetching data from api in the created hook which is perfectly working.
created() {
this.fetchInformation()
}
But I was having look over best practices for lifecycle hooks and I came to this line You need to fetch some data for your component on initialization. Use created (or created + activated for keep-alive components)
I also tried to look for relevant articles or information on the internet.
Url for reference - https://alligator.io/vuejs/component-lifecycle/
My component is rendering inside keep-alive so I tried this for the test purpose.
activated() {
this.fetchInformation()
}
Instead of created, now as expected everytime the component activates it execute the api call which is really cool. But I still want to understand what this actually created + activated as I am using activated or created but if I am correct just by reading that I should do them both.
Please let me know if anything else required to understand my question.
Thanks
Use correctly keep-alive!!
Incorrect:
<template>
<div>
<div v-if="canRender">
<keep-alive>
<my-component />
</keep-alive>
</div>
</div>
<template>
Incorrect:
<template>
<div>
<keep-alive>
<div v-if="canRender">
<my-component />
</div>
</keep-alive>
</div>
<template>
Correct:
<template>
<div>
<div>
<keep-alive>
<my-component v-if="canRender" />
</keep-alive>
</div>
</div>
<template>

Using v-for with v-on:click in a Vue Component

I have what I think is a basic question for Vue, but I'm trying to run a method on click while also running a v-for loop on a component.
I'm not sure why but I can't get anything to run on that click handler but I see nothing in the Vue documentation saying that this isn't possible. Right now I'd settle for getting my console log running.
<IconBox
v-for="step in steps"
:key="step.slug"
:step="step"
:formData="formData"
#click="console.log('click')"
/>
Here is the template for IconBox.vue:
<template>
<div class="icon-box">
<div
class="icon-holder"
:style="{ backgroundImage: 'url(' + step.image + ')' }"
>
</div>
<div class="text">
<div class="inner">
<h5>{{ step.name }}</h5>
<p v-if="step.description">{{ step.description }}</p>
{{ isSelected }}
</div>
</div>
</div>
</template>
I could run the click in the component itself but I need the parent well aware of what's happening to handle a selected boolean.
To use native events in component tags you should add .native modifier
<IconBox #click.native="yourMethod"/>
Check this guide.
To check it I suggest you to create a method and add console.log() inside it.
I have been playing around with Vue lately, and here's how I solved a similar problem in my project
<IconBox
v-for="step in steps"
:key="step.slug"
:step="step"
:formData="formData"
#click="console.log('click')"
/>
Changes to
<template v-for="step in steps">
<IconBox
:key="step.slug"
:step="step"
:formData="formData"
#click="console.log('click')"
/>
</template>

Safari shows a component error while the other browsers do not

I have some very simple vue code as shown below:
Vue.component('tabs', {
template: `
<div class="">
<div class="tabs">
<ul>
<li><a>Music</a></li>
<li><a>Videos</a></li>
<li><a>Documents</a></li>
</ul>
</div>
<div class="tab-detail">
<slot></slot>
</div>
</div>
`
});
new Vue ({
el: '#root'
});
and HTML code
<div id="root" class="container">
<tabs>
</tabs>
</div>
the problem I have is that the safari throws a warning:
[Vue warn]: Unknown custom element: <tabs> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
(found in <Root>)
I am a Vue beginner so I was looking for the solution but the answer I got was that I should just declare the new Vue after the component. That I did but I am still getting this error.
This is because Safari does not support es6 template string syntax ``. In order to fix it you should use Webpack or just a Babel to add support for new es6 features.