Components are not rendering in quasar project with no error - vue.js

I created Vue 3, quasar project. everything worked fine till the moment I add new component. everything is rendering except the new component which I built and added it to the project. please help me with this problem if you can.
Here is my code:
index page:
<template>
<q-page class="flex flex-center">
<!-- section one-->
<SectionOne />
</q-page>
</template>
<script>
import { defineComponent } from "vue";
import SectionOne from "components/MainPage/SectionOne.vue";
export default defineComponent({
components: {
SectionOne,
},
name: "IndexPage",
});
</script>
Component:
<template>
<div class="q-pa-md q-gutter-md">
<div class="row justify-between">
<q-parallax src="https://cdn.quasar.dev/img/parallax2.jpg">
<h1 class="text-white">Basic</h1>
</q-parallax>
</div>
</div>
</template>

Not sure about your project structure, but try this (missing "./")
import SectionOne from "./components/MainPage/SectionOne.vue";

You can also import from the root 'src' like this:
import SectionOne from "src/components/MainPage/SectionOne.vue";

Related

How can I wrap every v-if in my Vue code in a transition?

The task of having to write
<transition name="fade">
<div v-if="condition">
</div>
</transition>
Is manual labour. Is there any shortcut way of wrapping every v-if with a transition?
You can create a custom Vue component:
// AppTransition.vue
<template>
<transition name='fade'>
<div v-if='show'>
<slot />
</div>
</transition>
</template>
<script>
export default {
props: {
show: Boolean
}
}
</script>
and then use it as follows:
<template>
<AppTransition :show='condition'>
<div>Hello, world</div>
</AppTransition>
</template>
<script>
// You can avoid importing it everywhere by making it a global component, see https://vuejs.org/guide/components/registration.html
import AppTransition from './AppTransition'
export default {
components: { AppTransition }
}
</script>

Vue layout with named slots

Is it possible?
I have something like this:
<template>
<my-layout>
<template #header>
Some header html goes here
</template>
Body html here
</my-layout>
</template>
<script>
import MyLayout from './MyLayout.vue'
export default {
layout: MyLayout,
components: {
//MyLayout
}
}
</script>
And template like that
<template>
<div>
<slot name="header"/>
</div>
<slot/>
</template>
The default slot works, but "header" slot doesn't display itself (unless using MyLayout as standard component).
I believe there is a problem with the closing tags on the template you have given and it should be like the following:
<template>
<div>
<slot name="header"> </slot>
</div>
</template>
After that, layout property only excepts strings or functions that return strings, so parent should be like the following:
<template>
<my-layout>
<template #header>
Some header html goes here
</template>
Body html here
</my-layout>
</template>
<script>
import MyLayout from "./MyLayout.vue";
export default {
layout: "MyLayout",
components: {
//MyLayout
}
};
</script>
I hope this solves your problem and have a nice day :)

Passing props to vue instance from .blade.php file using createElement and render function

EDIT: Some more information:
I have a main-page.blade.php file, with this:
//main-page.blade.php where vue instance will mount
<div id="main-page" class=" bg-uoi-green">
<main-page :data=['one'] ></main-page>
</div>
There is also a main.js file importing the app.js file of Vue, where the instance for main-page is defined ( I have installed vue-loader and template compiler).
The app.js for Vue is:
//app.js of Vue
import Vue from 'vue'
import './assets/tailwind.css'
//
// import MainPage from './components/MainPage.vue'
// const mainpage_inst=new Vue({
// el: '#main-page',
// components: {
// MainPage,
// },
// props: ['data'],
// });
Vue.config.productionTip = false
export default {
mainpage_inst,
}
Compiling for my application was giving me exactly what was needed. But then, if I try to also check the Vue directory using vue client, I get an empty page; this was to be expected since the vue-cli does not use the full-build. But even when I changed
// import Vue from 'vue'
to
import Vue from 'vue/dist/vue.js';
I was getting a blank page when visiting localhost:8080 from vue-cli.
I was able to fix it by using the render function of vue. So now, the instance became:
import MainPage from './components/MainPage.vue'
// Main page instance
const mainpage_inst = new Vue({
render: h => h(MainPage),
}).$mount('#main-page')
But, no matter how I try to pass props as before, my main application cannot see them, in contrast to the previous writing where it was able, but vue-cli was producing a blank page.
For clarification: I have a Vue-app inside a different app that is loaded with all the required( I think) modules to read and compile .vue files. But I would also like to be able to run the Vue-app using the vue-cli.
So, is my main-app missing a module and is not able to get the props? Or is there some other way to make 'understand'?
Thanks again.
In the past, I was using the following code to create the application instance :
// const mainpage_inst=new Vue({
// el: '#main-page',
// components: {
// MainPage,
// },
// props: ['data'],
// });
and I was calling the MainPage component from a .blade.php file by passing the props:
<main-page :data=" {{ $data_to_send_as_props }}" > </main-page>
Now I want to use the following code:
import MainPage from './components/MainPage.vue'
// Main page instance
const mainpage_inst = new Vue({
render: h => h(MainPage),
}).$mount('#main-page')
but if I try to define the props as before, the application does not recognizes them. What is the correct way to write the above excerpt of code, so that props will be passed ? In other words, how and were should I add the props definition on the instance above (note also that I should implement also the change mentioned in the answer of Daniel)
Edit:
This is a simplified version of the MainPage.vue component
<template>
<div class=" h-screen w-screen md:text-2xl text:2xl " id="main-page ">
<div class=" flex flex-shrink text-4xl md:text-9xl font-bold md:ml-20 md:my-5 md:py-0 py-10 title">
A Title
</div>
<div class="flex flex-col flex-grow h-1/3 ">
<div v-for="(item,index) in slicedArray " v-bind:key="item.id" >
<div class=" flex flex-col md:flex-row md:flex-grow w-full hover:bg-uoi-green px-10 border-black border-2 transition duration-500 cursor-pointer ease-in-out bg-opacity-70 transform hover:bg-opacity-95" :class="{active: isActive === item.id}">
<div class=" date-font h-full w-1/6 md:flex-grow px-2 py-4"> {{item.date}} — </div>
<div class=" h-full w-2/3 md:flex-grow px-2 py-4 text-left"> {{item.title}} </div>
<div class=" date-font h-full w-1/6 md:flex-grow px-2 py-4 text-right"> {{item.exp_date}} </div>
</div>
<div class=" bg-white py-10 px-20" v-if="isActive === item.id">
<div > {{item.text}} </div>
<div class='file'> <a href=''> Σχετικό αρχείο </a>
<!-- <img src="../assets/curved-up-arrow-.png" class="arrow"/> -->
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name:'MainPage',
props: ['data'],
data(){
return{
isActive: null,
newsToShow: 3,
totalnews: 0,
array:[],
slicedArray:[],
}
},
mounted(){
this.newsToShow=3;
this.array=this.data;
this.totalnews = this.array.length;
// console.log(this.array)
this.slicedArray=this.array.slice(0,this.newsToShow)
},
}
</script>
<style scoped>
</style>
One of the breaking changes in Vue 3 was that the Global Vue API was changed to use an application instance. To create a vue app, use the createApp function to create the instance.
a-new-global-api-createapp
The render function (h) is not provided by the render function, so you need to import it. docs
so your instantiation should look something like this:
import { h, createApp } from 'vue'
import MainPage from './components/MainPage.vue'
// Main page instance
const mainpage_inst = new createApp({
render: () => h(MainPage),
}).$mount('#main-page')

VueJS extends component with slots

I have a BaseModal Component like this :
<template>
<div class="base-modal" :class="{open: isOpen}">
<div class="modal">
<h2 class="modal-title">
<slot name="title"></slot>
</h2>
<div class="modal-content">
<slot name="content"></slot>
</div>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
#Component({})
export default class BaseModal extends Vue {
public isOpen: boolean = false;
// Some methods
}
</script>
I want to create an other modal component that will extend this one and pass it the content for the named slots. Here is where I am :
<template>
// How to give slots content here
</template>
<script lang="ts">
import BaseModal from "#app/components/BaseModal.vue";
import { Vue, Prop, Component } from "vue-property-decorator";
#Component({
extends: BaseModal,
})
export default class OtherDropdown extends Vue {
}
</script>
The extends is working but I can't figure out how to pass content to the named slot of the extended component. Not to have to write again all the BaseModal template.
Thanks
I'm using VueJS 2.6.8
You would want to use components named slots like this:
<template>
<BaseModal>
<template v-slot:title>
Some Title
</template>
<template v-slot:content>
Some content goes here
</template>
</BaseModal>
</template>
You can read more about named slots here: https://v2.vuejs.org/v2/guide/components-slots.html#Named-Slots
Hope this helps!

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?