Globally mocking data using Vue test utils - vue.js

I have a component in Vue which contains an img tag where the value of src is coming from props.
<template>
<div>
<img src="some url">
</div>
</template>
Similarly, this img tag is present in many of my components. For mocking it globally, I made a jest.init.js file where my code goes something like this
import VueTestUtils from "#vue/test-utils";
VueTestUtils.config.mocks["img"] = {src: "rytui"};
But it is not working. How should I do it?

some where. You need add setupFiles config in your jest.config.js like this
{
setupFiles: ["<rootDir>/jest.init.js"],
}

Related

Why does vue-plyr plugin keep loading on server side

I have a nuxt app which uses the vue-plyr plugin to play videos. I've registered the plugin like this
import Vue from 'vue'
import VuePlyr from 'vue-plyr/dist/vue-plyr.ssr.js'
import 'vue-plyr/dist/vue-plyr.css'
Vue.use(VuePlyr, {
plyr: {}
})
and added it to nuxt.config.js
plugins: [
{
src: '~/plugins/plyr.client.js',
mode: 'client'
}
],
but when I import it inside a component
import VuePlyr from 'vue-plyr'
I always get an error saying
document is not defined
The component itself is also wrapped in a <client-only></client-only> tag.
Am i missing something with my implementation?
Is there any other way to import the plugin
I'm using node-14.17.6 and nuxt-2.15.6
You don't need plyr.client.js but plyr.js if you already have mode: 'client'.
Also, why do you import it again if you have it as a plugin? It is globally available so you could start using it directly.
<template>
<client-only>
<vue-plyr>
<div class="plyr__video-embed">
<iframe
src="https://www.youtube.com/embed/bTqVqk7FSmY?amp;iv_load_policy=3&modestbranding=1&playsinline=1&showinfo=0&rel=0&enablejsapi=1"
allowfullscreen
allowtransparency
allow="autoplay"
></iframe>
</div>
</vue-plyr>
</client-only>
</template>
Depending on the code you're using below, you may also check that this is not being called server side as shown here: https://stackoverflow.com/a/67751550/8816585
Updated with a more explicit example.

Vue Js not displaying

This is my very beginning with Vue with Symfony. Problem is nothing is displayed in my page, I was expecting Hello to be print. I did all my configurations. I have created folder vue
Inside vue I have following 2 files.
App.vue
<template>
<div id="app">
<h1>Hello</h1>
</div>
</template>
index.js
import Vue from "vue";
import App from "./App";
new Vue({
components: { App },
template: "<App/>"
}).$mount("#app");
I have in my webpack.config.js
.addEntry('app', './assets/vue/index.js')
I did anything wrong here ?
You are mounting the Vue instance to something existing in the DOM with id app. But the component inside App.vue also contains a div with id app. Try to mount to anything else on the page that Symfony creates (you can't mount on body or html). I'm sure that page does not contain anything with id app.

Nested single file components - vue.js with electron-forge

I am trying electron for the first time and I am blown away by it. I have hit a wall, though, when trying to use single file vue.js components using electron-forge. My problem is the following:
I create a project using the vue.js template and run it. Works and looks great. I have a single file page with an index file that looks like this:
<div id="test"></div>
</body>
<script>
import Vue from 'vue';
import Test from './test';
const app = new Vue(Test).$mount('#test');
app.text = "Electron Forge with Vue.js!";
</script>
So far, so good. It imports Test, which is a single file component and renders it.
Now, I would like to have other single file components nested in this main component. For example, I would like to have the following, in my app file called test.vue
<template>
<h2>Hello from {{text}}</h2>
</template>
<script>
import About from './About.vue'
export default {
components: {
appAbout: About,
},
data () {
return {
text: 'Electron'
}
}
}
</script>
Again, so far so good. I can run the app with no errors so the component is being imported.
Here comes my problem: if I now try to render the component using <appAbout></appAbout>, as I have done before in web apps with vue.js, I get the following error.
It basically says that I am not using a single root element in my component, which is really strange because my component looks like this:
<template lang="html">
<div>Hello from component</div>
</template>
<script>
export default {
}
</script>
<style lang="css">
</style>
I am stuck. Can someone please help?
So I have tried a few different things with no success, like using or even as the component names.
I also have tried these two ways of starting the vue:
The way you get with electron-forge
const app = new Vue(App).$mount('#app')
and the way I learned
new Vue({el: '#app', render: h => h(App)})
Nothing seems to work...
Define your component like this :
export default {
components: {
'app-about': About
}
}
Then use it in template like this (with kebab-case) :
<app-about></app-about>
About your compiling template error you need to wrap everything in test.vue in a root element :
<template>
<div>
<h2>Hello from {{text}}</h2>
<app-about></app-about>
</div>
</template>

Component inside another component not working - webpack - Vue.js 2

I am totally new to Vue.js and hence I feel the issue is very simple. Here is my Test.vue component:
<template>
<p>Hello Worldd</p>
</template>
<script>
export default {
name : 'test'
}
</script>
I am trying to display this "Hello Worldd" in another component called UserDevices.vue. Here is the contents of that file:
<template>
<div>
<test></test>
<p>test</p>
</div>
</template>
<script>
import Test from './Test'
export default {
name: 'UserDevices',
components: {Test}
}
I am getting an error says:
[Vue warn]: Unknown custom element: <test> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <UserDevices> at src/components/UserDevices.vue
<App> at src/App.vue
<Root>
I am using webpack scaffold for vue as template. Isn't this the correct approach to do this?
You are using a .vue file, meaning that vue-loader is looking for a script section enclosed in <script> tags. But, because you are not closing the script tag with </script>, vue-loader will just ignore that section of the .vue file (without any warning).
The template of the Vue component will still get loaded, but the Vue instance's model (with all of its data properties, methods, component, etc.) will not. This is why Vue can't find the <test> component.

how to use a .vue file in a html?

I created a hello.vue file, now how to use this in a html file? I already setup a webpack,
<template>
<p>Hello</p>
<p>{{message}}</p>
</template>
<script>
module.exports = {
data: {
message: 'hello'
}
}
</script>
<style>
p {
font-size: 14px
}
</style>
How do you want to use it?
Taking demonstation from official example: vue-hackernews-2.0. This is a component, so you import the component in another vue file like this:
import Comment from '../components/Comment.vue'
and you add in the list of components in that vue instance:
components: { Spinner, Comment },
Than you can use it in HTML like this:
<comment v-for="id in item.kids" :key="id" :id="id"></comment>
You just have to include your bundled .js file in your HTML file and include mounter div - so Vue could know where to execute the app.
Your index file could looks something like this (showing only body section)
...
<body>
<div id="app"></div>
<script src="bundle.js">
</body>
...
Your main Vue file could looks like this:
import Vue from 'vue'
import Hello from 'hello.vue'
const app = new Vue({
render: (h) => h(Hello)
}).$mount('#app')
And in this way you can store all other components into the hello.vue.
This is probably way that you should use when you are building SPA.