Vue - include Vue file into other Vue file - vue.js

I'm new to Vue.
I have created some elements (I'm using Element Components) and the code gets too long.
I would like to know if there is any way to create a several Vue files and include them all to one?
For exmaple, I have Navbar.vue, Header.vue , Footer.vue and Body.vue.
I want to include them all into one file.
Is it possible?

Sure. You import and use them like in my example. Don't forget to register them in the components as you can see.
This could be your app.vue file
<template>
<div id="app" class="container">
<the-header />
<!-- this could be <TheHeader /> depending on your setup -->
<the-navigation />
<!-- this could be <TheNavigation /> depending on your setup -->
</div>
</template>
<script>
import TheHeader from '#/components/the-header.vue'
import TheNavigation from '#/components/the-navigation.vue'
export default {
name: 'app',
components: {
TheHeader,
TheNavigation
}
</script>
<style lang="scss">
</style>

Related

Insert 2 components in nuxt.js page

i'm new of this framework :(
the problem is here because i've tried to put the component in another page and work it.
It sign error the component
this is my index.vue page
If you're using nuxt2.0, you should wrap them in a container but this is not needed in nuxt3.0.
<template>
<main>
<navbar />
<slideshow />
</main>
</template>
If this is nuxt2.0, then you should also import the component and register it but you haven't done it here. The path you've given to the component is not correct also.
<script>
import Slideshow from '~/components/slideshow.vue';
export default {
components: { Slideshow }
}
</script>
You need to wrap the into a div or any other tag (to not have multiple tags at the root of the template) like that
<template>
<div>
<navbar></navbar>
<slideshow></slideshow>
</div>
</template>
And you can also skip the import part because Nuxt is already doing that for you as explained here: https://nuxtjs.org/tutorials/improve-your-developer-experience-with-nuxt-components/

Should my header file be called from the 'store' folder in Nuxt instead of the 'components' folder?

I'm testing out the Vuex store implementation in Nuxt and wondered whether the Store folder is now the best way of sharing components and modules, rather than with the Components folder?
For example, I currently call the header from default.vue in the Layouts folder with this code referencing the Components folder:
<template>
<div class="container">
<Header />
<nuxt />
<Footer />
</div>
</template>
<script>
import Header from '~/components/appheader.vue'
import Footer from '~/components/appfooter.vue'
export default {
components: { Header, Footer }
}
</script>
But, as far as I understand, if header.vue is in the Store folder then it can simply be called with the filename, like this below with no need to import or export it. Have I understood that correctly?
<template>
<div class="container">
<appheader></appheader>
<nuxt />
<appfooter></appheader>
</div>
</template>
No, the store folder should not contains components. Put your components only in components folder.
The store folder is only for modularizing Vuex.
If you don't want to write your import statement in each components, you can use nuxt-global-base-components. But I'm not convinced this is a good practice...
Also, be careful with your components name. Header and Footer are html reserved words. Name them AppHeader and AppFooter instead.

nuxt code splitting doesn't work properly

I'm just starting with nuxtjs, i have 2 pages
-index
-map
map page has one component, which is client only
and the default layout has links to the 2 pages, just the basic setup
the production build generates code split for the vendor per page but both files loads at the first page, i can't find what am i missing.
map page
<div class="container">
<client-only>
<Map />
</client-only>
</div>
</template>
<script>
import Map from '~/components/Map.vue'
export default {
components: {
Map
}
}
</script>
<style>
</style>
index page
<template>
<div class="container">
<h1 class="h-1">test hello page index</h1>
</div>
</template>
<script>
export default {
components: {
}
}
</script>
<style>
</style>
default layout
<template>
<div>
<nuxt-link to="/">home</nuxt-link>
<nuxt-link to="/map">map</nuxt-link>
<nuxt />
</div>
</template>
<style>
</style>
This is because nuxt-link prefetches the page it is linked to when it appears inside the viewport.
It's for performance reason and should not impact the initial loading of the page, since the prefetching is done during idle time.
If you would like to verify that what you are seeing is because of the prefetching, you can disable prefetching on per link basis by adding a no-prefetch attribute to nuxt-link or configuring router in nuxt.config.js
// nuxt.config.js
export default {
router: {
prefetchLinks: false
}
}
This is done only if user is on good network connection and not using save data mode. And, since this is done in browser's idle time, I'd suggest, leave it like this. Should not hurt.

Using Nuxt.js alias in component attributes

I have a collection of images, audios and videos that should be displayed by a component one by one. All media is placed in assets sub-directories.
Given a simple Vue component for images like:
<template>
<img :src="src" :alt="src"></a>
</template>
<script>
export default {
name: "ImgDisplay",
props: ['src']
}
</script>
if I try to use it on some page:
<template>
<ImgDisplay src="~/assets/test.png"/>
</template>
the image is not actually displayed.
Vue component for MP3-files looks like this:
<template>
<vue-plyr>
<audio controls>
<source :src="src" type="audio/mp3"/>
</audio>
</vue-plyr>
</template>
<script>
export default {
name: "PlyrAudio",
props: ['src']
}
</script>
Then in document I have:
<template>
<div>
<article class="infobox">
<h6>Recording 1</h6>
<PlyrAudio src="~/assets/media/recording-1.mp3"/>
</article>
<article class="infobox">
<h6>Recording 2</h6>
<PlyrAudio src="~/assets/media/recording-2.mp3"/>
</article>
</div>
</template>
<script>
import PlyrAudio from "../components/media/PlyrAudio";
export default {
name: "PlyrAudioTest",
components: {PlyrAudio}
}
</script>
which does not work either, PlyrAudio component does not seem to find referenced mp3 files.
How can one use Nuxt.js aliases (~, ~~, #, ##) in component attributes? Is there some dedicated function to resolve ~ in <script> section of ImgDisplay and PlyrAudio or am I missing something?

How to import and use image in a Vue single file component?

I think this should be simple, but I am facing some trouble on how to import and use an image in Vue single file component. Can someone help me how to do this? Here is my code snippet:
<template lang="html">
<img src="zapierLogo" />
</template>
<script>
import zapierLogo from 'images/zapier_logo.svg'
export default {
}
</script>
<style lang="css">
</style>
I have tried using :src, src="{{ zapierLogo }}", etc. But nothing seems to work. I was not able to find any example too. Any help?
As simple as:
<template>
<div id="app">
<img src="./assets/logo.png">
</div>
</template>
<script>
export default {
}
</script>
<style lang="css">
</style>
Taken from the project generated by vue cli.
If you want to use your image as a module, do not forget to bind data to your Vuejs component:
<template>
<div id="app">
<img :src="image"/>
</div>
</template>
<script>
import image from "./assets/logo.png"
export default {
data: function () {
return {
image: image
}
}
}
</script>
<style lang="css">
</style>
And a shorter version:
<template>
<div id="app">
<img :src="require('./assets/logo.png')"/>
</div>
</template>
<script>
export default {
}
</script>
<style lang="css">
</style>
It is heavily suggested to make use of webpack when importing pictures from assets and in general for optimisation and pathing purposes
If you wish to load them by webpack you can simply use :src='require('path/to/file')' Make sure you use : otherwise it won't execute the require statement as Javascript.
In typescript you can do almost the exact same operation: :src="require('#/assets/image.png')"
Why the following is generally considered bad practice:
<template>
<div id="app">
<img src="./assets/logo.png">
</div>
</template>
<script>
export default {
}
</script>
<style lang="scss">
</style>
When building using the Vue cli, webpack is not able to ensure that the assets file will maintain a structure that follows the relative importing. This is due to webpack trying to optimize and chunk items appearing inside of the assets folder. If you wish to use a relative import you should do so from within the static folder and use: <img src="./static/logo.png">
I came across this issue recently, and i'm using Typescript.
If you're using Typescript like I am, then you need to import assets like so:
<img src="#/assets/images/logo.png" alt="">
You can also use the root shortcut like so
<template>
<div class="container">
<h1>Recipes</h1>
<img src="#/assets/burger.jpg" />
</div>
</template>
Although this was Nuxt, it should be same with Vue CLI.
These both work for me in JavaScript and TypeScript
<img src="#/assets/images/logo.png" alt="">
or
<img src="./assets/images/logo.png" alt="">
..when everything else fails, like in my case as i tried to import a placeholder i used several times in a multipaged Vuelectro-app - but this time inside a sub-subcomponent where none of the suggested solutions worked (as they usually do)..
<template>
<div id="app">
<img :src="image"/>
</div>
</template>
<script>
export default {
data() { return {image: null, ...} },
methods: {
solveImage(){
const path = require('path')
return path.join(process.cwd(), '/src/assets/img/me.jpg')
},
...
},
mounted: {
this.image = this.solveImage()
...
}
}
</script>
..should do it.
if it even works better in created-lifecycle-hook or you'd prefer to require path globally and just call
this.image = path.join(...)
in one of the hooks - you should test yourself.
I encounter a problem in quasar which is a mobile framework based vue, the tidle syntax ~assets/cover.jpg works in normal component, but not in my dynamic defined component, that is defined by
let c=Vue.component('compName',{...})
finally this work:
computed: {
coverUri() {
return require('../assets/cover.jpg');
}
}
<q-img class="coverImg" :src="coverUri" :height="uiBook.coverHeight" spinner-color="white"/>
according to the explain at https://quasar.dev/quasar-cli/handling-assets
In *.vue components, all your templates and CSS are parsed by vue-html-loader and css-loader to look for asset URLs. For example, in <img src="./logo.png"> and background: url(./logo.png), "./logo.png" is a relative asset path and will be resolved by Webpack as a module dependency.
For Vue 3 I had to use
<template>
<div id="app">
<img :src="zapierLogo" />
</div>
</template>
<script>
import zapierLogo from 'images/zapier_logo.svg'
export default {
...
data: function () {
return {
zapierLogo
}
}
}
</script>
Both src="#/assets/burger.jpg" and src="../assets/burger.jpg" didn't seem to work.
I'm also facing same problem to display the assets image. Finally this two way work fine for me-
<img src="#/assets/img/bg1.png" />
and
<img :src="require('#/assets/img/bg1.png')" />
in my case i have a base64 image and have to import for parse the mimeType and data from the image
this how the template look like
<template>
<img
#click="openCardDetail(item)"
class="thumbnailInfo"
width="80"
height="50"
:src="getImageToShow(item.stationeryThumbnail)"
/>
</template>
Here i imported the image
import image from '#/assets/noimage.png'
then i instantiated it
data: () => ({
...
image: image,
})
then i used only if there is no data in the item
getImageToShow(item) {
if(item != null && item?.mimeType !== '' && item?.base64ImageData !== '') {
return `data:${item?.mimeType};base64,${item.base64ImageData};`
}
return `${this.image}`;
}
it solved my problem