use props with laravel and vuejs2 - javascript

hi im using laravel with vuejs2
and this is my App.vue code
<template>
<div>
<Navbar></Navbar>
<Applications></Applications>
{{page_title}}
<router-view></router-view>
</div>
</template>
<script>
import Navbar from '../components/Navbar'
import Applications from '../components/Applications'
export default {
name: 'App',
components: {
Navbar, Applications
},
data: function () {
return {
page_title: 'Main',
}
}
}
</script>
every thing working so good so far ..
so in my routes.js i did this code
{ path: '/settings', component: Settings},
and in my Settings.Vue i did this code
<template>
<div>
setting components
{{page_title}}
</div>
</template>
<script>
export default {
props: ['page_title'],
name: 'Settings',
}
</script>
but i cant access page_title from the props what i want i access page_title from App.vue in Settings.vue
thanks a lot

You must pass data to <router-view>:
const Page = {
template: "<div>Title: {{page_title}}</div>",
props: ["page_title"]
};
const router = new VueRouter({
routes: [{
path: "/",
component: Page
}]
});
const app = new Vue({
router,
template: "<router-view :page_title='page_title'></router-view>",
data() {
return {
page_title: "It's magic!"
};
}
}).$mount("#app");
<script src="https://unpkg.com/vue#2.6.11/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-router#3.1.6/dist/vue-router.min.js"></script>
<div id="app"></div>

Related

keep-alive not works in vue.js

My vuejs version is 3.
I implement both of these ways to use keep-alive in my app.
1
<template>
<div id="nav" classs="container is-max-desktop"></div>
<keep-alive>
<router-view />
</keep-alive>
</template>
<style>
#import "~bulma/css/bulma.css";
</style>
2
import { createRouter, createWebHistory } from "vue-router";
import Index from "../views/Index.vue";
import Create from "../views/Create.vue";
import Edit from "../views/Edit.vue";
const routes = [
{
name: "Index",
path: "/",
component: Index,
meta: { KeepAlive: true },
},
{
name: "Edit",
path: "/edit/:id",
component: Edit,
meta: { KeepAlive: true },
},
{
name: "Create",
path: "/create",
component: Create,
meta: { KeepAlive: true },
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue"),
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
Simply, I apply many filters on my page but when I came back to that page they are gone. Help me to solve this problem. Thank you.
Keep alive caches components when dynamically switching them which will retain the data's in that particular component while switching. Use the below code for integration,
Maincomponent.vue
<script>
import Component1 from './Component1.vue'
import Component2 from './Component2.vue'
export default {
components: { Component1, Component2 },
data() {
return {
current: 'Component1'
}
}
}
</script>
<template>
<div class="demo">
<label><input type="radio" v-model="current" value="Component1" /> A</label>
<label><input type="radio" v-model="current" value="Component2" /> B</label>
<KeepAlive>
<component :is="current"></component>
</KeepAlive>
</div>
</template>
Component1.vue
<script>
export default {
data() {
return {
count: 0
}
}
}
</script>
<template>
<div>
<p>Current component: A</p>
<span>count: {{ count }}</span>
<button #click="count++">+</button>
</div>
</template>
Component2.vue
<script>
export default {
data() {
return {
msg: ''
}
}
}
</script>
<template>
<div>
<p>Current component: B</p>
<span>Message is: {{ msg }}</span>
<input v-model="msg">
</div>
</template>

Issue when trying to use Nested routes in Vuejs?

main.js
import Vue from "vue";
import App from "./App.vue";
import VueRouter from "vue-router";
import HelloWorld from "./components/HelloWorld";
import User from "./components/User";
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{
path: "/",
name: "HelloWorld",
component: HelloWorld,
children: [{ path: ":id", name: "User", component: User }]
}
]
});
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App)
}).$mount("#app");
HelloWorld.vue
<template>
<div>
<div v-for="item in items" :key="item.id">
<b> id: {{ item.id }}</b>
<router-link :to="`/HelloWorld/${item.id}`">
{{ item.title }}
</router-link>
</div>
<!-- end v-for -->
<router-view></router-view>
</div>
</template>
<script>
import { router } from "./router";
export default {
name: "HelloWorld",
components: {},
data() {
return {
items: [],
};
},
mounted() {
router().then((r) => {
this.items = r.data;
});
},
};
</script>
codesandbox:- https://codesandbox.io/s/combined-logic-api-forked-oq808t?file=/src/main.js
in main.js routing file, if i change from path:'/' to path:'/HelloWorld' then output is not displaying. Not sure why and where it is linked with api call..
The reason why i changed from path:'/' to path:'/HelloWorld' because path:'/' in my project, it will consider as login page. So tried changing but getting blank screen.
You should change
const router = new VueRouter({
routes: [
{
path: "/HelloWorld/",
name: "HelloWorld",
component: HelloWorld,
children: [{ path: ":id", name: "User", component: User }]
}
]
});
to
const router = new VueRouter({
mode: 'history',
routes: [
{
path: "/HelloWorld/",
name: "HelloWorld",
component: HelloWorld,
children: [{ path: ":id", name: "User", component: User }]
}
]
});
(So, add mode: history, to the router.)
More on mode: history in Vue Router v3 here

Display layout based on boolean from Vuex

I got Vue2 app with vue-router with routings configured like that:
export default {
path: "/",
redirect: "/dashboard",
component: AdminLayout,
meta: {
requiresAuth: true
},
children: [
{
path: "/dashboard",
name: "Dashboard",
component: Dashboard
},
{
path: "/add/user",
name: "InviteUser",
component: InviteUser
},
{
path: "/groups",
name: "Groups",
component: Groups
},
...
In app, we got two different types of users - admin and normal user. Some of those routings should be accessible for both, but the problem is that user should see different layout base on its type (permission) - AdminLayout for admins and UserLayout for normal users.
Is there any way to show app which template should user see based on boolean from vuex with keeping route path?
on /dashboard admin will see dashboard with AdminLayout
on /dashboard normal user will see dashboard with UserLayout
My main routing cofig:
import Vue from "vue";
import VueRouter from "vue-router";
import SessionRoutes from "./session.js";
import AdminRoutes from "./admin.js";
import defaultRoutes from "./default";
Vue.use(VueRouter);
const routes = [AdminRoutes, SessionRoutes, defaultRoutes];
const router = new VueRouter({
mode: "history",
routes
});
export default router;
you can set a condition in the layout part on the current page for example for when you use nuxt:
<script>
export default {
layout: (ctx) => (ctx.isAdmin ? 'adminLayout' : 'userLayout'),
}
</script>
but I opine you don't use Nuxt.js and I think below solution is suitable for your question:
Using the meta-object in our route
set dynamic component on app.vue page
code for about.vue page
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import LayoutA from '../layouts/LayoutA.vue'
import LayoutB from '../layouts/LayoutB.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: { layout: LayoutA }
},
{
path: '/about',
name: 'About',
component: About,
meta: { layout: LayoutB }
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router;
<!--app.vue page -->
<template>
<div id="app">
<component :is="this.$route.meta.layout || 'div'">
<router-view />
</component>
</div>
</template>
<script>
export default {
name: "App",
};
</script>
<!--about page-->
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<script>
export default {
name: "About"
};
</script>
To get a different layout working for the dashboard and all child routes your layouts have to use the router view component. I use a wrapper component to handle this in one of my projects following this approach.
Excerpt from my router config:
…
{
component: MainFrame,
name: 'main',
path: '/',
redirect: 'dashboard',
children: [
{
alias: 'dashboard',
component: Dashboard,
name: 'dashboard',
path: '', // Default child route → be equivalent to /dashboard
},
{
path: "add/user",
name: "InviteUser",
component: InviteUser
},
{
path: "groups",
name: "Groups",
component: Groups
},
],
},
…
In your MainFrame component you can wrap your layout in a dynamic component. So you can switch your layout easely based on a Vuex getter:
MainFrame.vue
<template>
<component :is="layout">
<!-- you can use slots too if you like -->
</component>
</template>
<script>
import AdminLayout from './AdminLayout'
import UserLayout from './UserLayout'
export default {
computed: {
layout() {
return this.$store.getters['isAdminUser'] ? AdminLayout : UserLayout
}
}
}
</script>
And your layouts have to use <router-view />. It works as a wrapper for all nested routes and therefore you have only one place to handle the layout for the dashboard and child pages:
AdminLayout.vue
<template>
<div class="auth-view">
<header>…</header>
<aside>…</aside>
<main>
<transition name="fade" mode="out-in">
<router-view />
</transition>
</main>
<footer>…</footer>
</div>
</template>
UserLayout.vue
<template>
<div class="guest-view">
<router-view />
</div>
</template>
EDIT:
This approach can be used for deeper nesting too. Assuming your user route should have another child routes you can solve this on the router config using a <router-view /> within a render function:
…
// Let's split down user related routes
{
component: { render: (h) => h('router-view') },
name: 'usersView',
path: 'users',
redirect: 'ListUsers',
children: [
// Show users
{
path: '', // route: /users/
name: 'ListUsers',
component: ListUsers
},
// Show a single user
{
path: ':id', // route: /users/{userId}
name: 'ViewUser',
component: ViewUser
},
// Invite new users
{
path: 'add', // route: /users/add
name: 'InviteUser',
component: InviteUser
},
]
}
…

How do I use the render function correctly in Vue?

I'm just starting to use the render function and came across
with one problem.
When rendering, the Home component does not display app routes
registered in
App.vue
<template>
<div>
<h1>Vue Router Demo App</h1>
<p>
<router-link :to="{ name: 'home' }">Home</router-link> |
<router-link :to="{ name: 'hello' }">Hello World</router-link>
</p>
<div class="container">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {}
</script>
there are no errors in the browser console.
app.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import App from './App'
import Hello from './views/Hello'
import Home from './views/Home'
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/hello',
name: 'hello',
component: Hello,
},
],
});
const app = new Vue({
el: '#app',
components: { App },
router,
});
Home.vue
with this configuration, the routes are not displayed
<script>
export default {}
import Vue from 'vue'
new Vue({
el: '#app',
render(createElement) {
return createElement("div", { class: "container" }, [
createElement("p", { class: "my-class" }, "Some cool text")
])
}
});
</script>
I just want to use the render function inside my components. Or understand how to use the render function correctly for two or more vue components.
How to configure the app correctly with switching between components
Home and Hello?
The components in Vue should be inherited from vue components and injected in the base component.
Vue.component('home', {
render(createElement) {
return createElement("div", { class: "container" }, [
createElement("p", { class: "my-class" }, "Some cool text")
])
}
})
new Vue({
el: '#app',
components: ['home'],
template: '<home/>'
})
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.11"></script>

Adding corresponding JS file to a new Vue.js component

I'm learning Vue.js and it's been really awesome so far but I ran into a problem trying to add another JS file. I have a Navigation.vue file and I'm trying to add a new Vue instance to corrsponde with it, but I'm not having any success.
Navigation.js
new Vue({
el: '#navigation',
data: {
active: 'home'
},
methods: {
makeActive: function(item) {
this.active = item;
}
}
});
Navigation.vue
<template>
<div id="navigation">
<nav v-bind:class="active" v-on:click.prevent>
Home
Projects
Services
Contact
</nav>
</div>
</template>
<script>
export default {
}
</script>
Application.js
import Vue from "vue/dist/vue.esm"
import App from '../app.vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css';
Vue.use(Vuetify)
document.addEventListener('DOMContentLoaded', () => {
document.body.appendChild(document.createElement('app'))
const app = new Vue({
el: 'app',
template: '<App/>',
components: {
App
}
})
console.log(app)
})
The Navigation.js file isn't working. I think it's because I haven't imported it right, but I'm not sure?
ERROR:
Property or method "active" is not defined on the instance but
referenced during render. Make sure that this property is reactive,
either in the data option, or for class-based components, by
initializing the property
What I'd expect to see is your Navigation component included in your App component.
App.vue
<template>
<div>
<Navigation/>
<!-- there's probably more than just this -->
</div>
</template>
<script>
import Navigation from 'path/to/Navigation.vue'
export default {
// snip
components: {
Navigation
}
// snip
}
</script>
Also, component data should be a function
Navigation.vue
<script>
export default {
data () {
return { active: 'home' }
},
methods: {
makeActive (item) {
this.active = item;
}
}
}
</script>
There's no need to include Navigation.js or have a separate Vue instance for your Navigation component

Categories