I need to have a custom layout or remove default layout for my signIn page. Based on Nuxt3 docs you can set layout with definePageMeta({layout: "custom"}) or remove definePageMeta({layout: false}) however when I set it to false or "custom" I get a TypeError.
The definePageMeta does change the layout. However, there are instances where when you first load the signIn page it doesn't show anything and shows the TypeError above. Any advice on how to solve this issue is greatly appreciated!
Btw, I just recently started using nuxt3, never had this issue in nuxt2.
// sign in page
<template>
<div>
<NuxtLayout name="custom">
<v-row>Sign In Page</v-row>
</NuxtLayout>
</div>
</template>
<script lang="ts" setup>
definePageMeta({
layout: 'custom',
})
</script>
// layout custom.vue
<template>
<v-app>
<v-main>
<v-container fluid>
<slot />
</v-container>
</v-main>
</v-app>
</template>
To create layout in nuxt 3 you must add slot.
// custom layout
<template>
<div class="custom-layout">
<slot/>
</div>
</template>
and then in your page component add layout: 'custom' in definePageMeta in setup script.
<template>
// YOUR PAGE
</template>
<script setup lang="ts">
definePageMeta({
layout: "custom",
});
</script>
if you need app.vue you must add NuxtLayout to it
// app.vue
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
Related
How do I pass a slot or a prop to a layout component in inertia?
For example, heres a ForgotPassword component:
<template>
<slot name="title">Forgot Password</slot>
Forgot pw stuff goes here...
</template>
<script>
import CardLayout from "#/Layouts/CardLayout";
export default {
layout: CardLayout,
}
Here is the CardLayout component:
<template>
<h1>{{ $slots.title }}</h1>
<slot/>
</template>
Nothing shows up inside the h1 tag...
Adding this here as the solution above does not work. You can pass data to the Layout component by setting a prop value
layout: (h, page) => h(Layout, { somePropDataDefinedInLayout: value }, () => page)
// CardLayout
<template>
<h1><slot name="title" /></h1>
<slot />
</template>
// ForgotPassword
<template>
<template #title>Forgot Password</template>
Forgot pw stuff goes here...
</template>
I know this question is being asked several times, but I couldn't find any solution to my problem.
I have two vue components on my laravel project. The first one is the laravel default component called "ExampleComponent.vue" and the second one is my own new component called "multi.vue".
I use them in a section.blade.php file like below:
#extends('layouts.app')
#section('content')
<example-component></example-component>
<multi></multi>
#endsection
but only the "example-component" works and for the "multi" component, it gives me the following error:
Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
here is my app.js code:
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('multi', require('./components/multi.vue').default);
const app = new Vue({
el: '#app',
});
Here is my components codes:
ExampleComponent.vue:
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
And my multi.vue:
<template>
<div>
I am multi component!
</div>
</template>
<script>
export default {
mounted() {
console.log('multi mounted.')
}
}
</script>
<style>
</style>
And the route is:
Route::get('/section',function(){
return view('section');
});
For solving this problem, all you need to do is to run "run npm watch".
After running that command, it will recomplie your vue code whenever you make a change in your code and save it.
Keep it in a separate terminal, and run "php artisan serve" in another terminal.
From https://v2.vuejs.org/v2/style-guide/#Multi-word-component-names-essential:
Component names should always be multi-word, except for root App
components, and built-in components provided by Vue, such as
<transition> or <component>.
This prevents conflicts with existing and future HTML elements, since
all HTML elements are a single word.
I'm wondering If I can setup a v-app-bar from Vuetify in the shared layout file and from the other layout send info, like for example the page title.
This is the shared layout
<template>
<v-app>
<v-navigation-drawer app permanent dark color="secondary">
//nav items in here
</v-navigation-drawer>
<v-content>
<v-container fluid>
<slot></slot>
</v-container>
</v-content>
</v-app>
</template>
The other layout file will be placed in the <slot></slot> tag, this is the other layout file where the app bar is
<template>
<v-app>
<layout>
<v-app-bar absolute fixed color="white" elevate-on-scroll>
<h2>Categories</h2>
<v-spacer></v-spacer>
<v-btn>New</v-btn>
</v-app-bar>
</layout>
</v-app>
</template>
I'm not familiar with Vuetify, I'm trying to learn so is there a way to do this? Also should I have the <v-app></v-app> in both files or only the shared layout?
Your usual setup would be that you initiate everything from your App.vue, which is basically your source file. From here on you can load all the components you need. If you use vue-router (recommended), then you can insert the <router-view /> tag to display the current content of the page you're in. That way you will always have the same content (app-bar, nav drawer) above and below (footer) the <router-view />.
You could remove the MyNavDrawer component and just put the v-navigation-drawer in there directly but I feel like most navigation-drawers take up a lot of markup and having it abstracted away in a component looks a lot cleaner.
// App.vue
<template>
<v-app>
<MyNavDrawer />
<v-content>
<v-container fluid>
<!-- If you use vue router -->
<router-view />
<!-- If you just want to display other components, add them -->
<MyOtherComponent />
</v-container>
</v-content>
<!-- Maybe add a footer here -->
<MyFooter />
</v-app>
</template>
<script>
import MyNavDrawer from "/path/to/myNavDrawer.vue";
import MyOtherComponent from "/path/to/myOtherComponent.vue";
import MyFooter from "/path/to/myFooter.vue";
export default {
components: {
MyNavDrawer,
MyOtherComponent,
MyFooter
}
}
</script>
// myNavDrawer.vue
<template>
<v-navigation-drawer app permanent dark color="secondary">
//nav items in here
</v-navigation-drawer>
</template>
I am fairly new to Vue and currently am working on the first project with it.
I have encountered this problem which I cannot seem to find a solution for, I have "AuthPage.vue" component which has a slot for the message and default slot for content, once I put custom componen in my login.blade.php it should be prefilled in that slot but it says that custom element does not exist. If I replace slot inside .vue file with custom element it seems to be working perfectly. I am not sure what I am doing wrong.
AuthPage.vue
<template>
<div>
<div class="page-brand-info"></div>
<div class="page-login-main">
<img class="brand-img" src="/assets/global/images/logo.jpg">
<h3 class="font-size-24 text-center"><slot name="title"></slot></h3>
<slot name="message"></slot>
<slot></slot>
<footer class="page-copyright">
<p>© {{ moment().year() }}. All RIGHT RESERVED.</p>
</footer>
</div>
</div>
</template>
<script>
import LoginForm from './LoginForm.vue';
import ResetPasswordForm from './ResetPasswordForm.vue';
export default {
components: { LoginForm, ResetPasswordForm }
}
</script>
login.blade.php
#extends('backoffice.layout.auth')
#section('content')
<auth-page>
<template v-slot:title>Sign In</template>
<login-form></login-form>
</auth-page>
#endsection
Thank you for your help!
Eddie
You'll need to register the LoginForm component globally in order for it to be passed into the AuthPage component as a slot (when passed in directly from a view). This is because, outside the scope of your component, Vue doesn't know what <login-form> is.
Since you're using laravel, in your resources/js/app.js file add the following:
import LoginForm from './path/to/LoginForm.vue';
Vue.component('login-form', LoginForm);
So I'm trying to dynamically generate a paper-dropdown-menu populated from an AJAX data source, which is working great using the code below:
<polymer-element name="my-element" attributes="selected">
<template>
<core-ajax auto url="/api/items/" response="{{items}}" handleAs="json"></core-ajax>
<paper-dropdown-menu selected="{{selected}}">
<template repeat="{{items}}">
<paper-item name="{{id}}" label="{{name}}"></paper-item>
</template>
</paper-dropdown-menu>
</template>
But if I set the initial selected item to be either the value of the published attribute, or a value that I set in the 'ready' callback, the dropdown menu item does not get selected when the items are loaded:
<script>
Polymer({
publish: {
selected: null
}
});
</script>
</polymer-element>
I understand that this is happening because the 'selected' property is being set before the template in the dropdown gets bound, but my question is whether there is a way to either 1) defer the 'selected' property change until after the template is bound or 2) otherwise reliably set an initially selected value for the dropdown menu?
One option would be to not render the dropdown until the data is available.
ex: http://jsbin.com/piyogo/13/edit
<polymer-element name="foo-drop">
<template>
<core-ajax auto
url="http://www.json-generator.com/api/json/get/bJMeMASvTm?indent=2"
response="{{items}}"
handleas="json">
</core-ajax>
<template if="{{items}}">
<paper-dropdown-menu selected="{{selected}}">
<template repeat="{{item in items}}">
<paper-item label="{{item.name}}"></paper-item>
</template>
</paper-dropdown-menu>
</template>
</template>
<script>
Polymer({
publish: {
selected: null
}
});
</script>
</polymer-element>
<foo-drop selected="2"></foo-drop>
For Polymer 1.0 (and later), the same can be achieved with the following code:
<iron-ajax auto url={{url}} handle-as="json" last-response="{{items}}"></iron-ajax>
<template is="dom-if" if="{{items}}">
<paper-dropdown-menu-light label="[[label]]" no-animations selected-item="{{selected}}">
<paper-listbox class="dropdown-content">
<template is="dom-repeat" items="[[items]]">
<paper-item>[[item.name]]</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu-light>
</template>