Get the value for a query parameter re-actively - vue.js

Hello I want to pass the value of my reactive data to the query parameter, but I don't know how?
<template>
<div id="app">
<div id="nav">
<router-link :to="{ name: 'HomeRoute', query: { lang: language } }">{{
$t("home")
}}</router-link>
|
<router-link to="/about">About</router-link>
</div>
<router-view />
</div>
</template>
<script>
import i18n from "./i18n";
export default {
data() {
return {
language: i18n.locale,
};
},
</script>
In this example, I want to set the value of the query parameter (lang) to be the same as i18n.local, which is store to a variable called language. I really appreciate if someone can help me with it.

In your data you can make a route object and simply pass it to your :to property
<template>
<div id="app">
<div id="nav">
<router-link :to="home_route">{{
$t("home")
}}</router-link>
|
<router-link to="/about">About</router-link>
</div>
<router-view />
</div>
</template>
<script>
import i18n from "./i18n";
export default {
data() {
return {
home_route : { name: 'HomeRoute', query: { lang: i18n.locale } }
};
},
</script>

Related

Cant Display img when using props to store src on vue js

so on this project i was trying to make an image component to display an image from a string props.
here is my component code
this is the component
<template>
<div class="Img-grid">
<div class="container">
<div class="col">
<img :v-bind:src="recipeImage" alt="image-photo">
<p>{{recipeName}}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ImgGrd'
props: {
recipeImage: String,
recipeName: String
}
}
</script>
this is my where the component display
<template>
<div class="RecipeByYou">
<div class="container">
<ImgGrid recipeName="a" v-bind:recipeImage="imgUrl" />
</div>
</div>
</template>
<script>
import ImgGrid from '../components/Image_Grid.vue'
export default {
name: 'RecipeImage',
components: {
Header,
ImgGrid
},
data () {
return {
imgUrl: 'https://media.sproutsocial.com/uploads/2017/02/10x-featured-social-media-image-size.png'
}
}
}
am i doing anything wrong? because when i inspect the web element it shows this thing, so i was confuse where did i do wrong, is this the correct method?
<img data-v-366ed4fa="" v-bind:src="https://media.sproutsocial.com/uploads/2017/02/10x-featured-social-media-image-size.png" alt="image-photo">
change this code <img :v-bind:src="recipeImage" alt="image-photo"> to <img v-bind:src="recipeImage" alt="image-photo">.
or you can change <img :v-bind:src="recipeImage" alt="image-photo"> to <img :src="recipeImage" alt="image-photo">.
: is shorthand of v-bind, your code :v-bind:src="recipeImage" means v-bind:v-bind:src="recipeImage"

Nested routes don't follow the defined pattern. VUEjs

I'm facing a new issue with nested routes. I've 2 levels of nested routes, and they're not working correctly.
Here are the routes object:
import Login from './components/auth/Login.vue';
import Dashboard from './components/dashboard/Dashboard.vue';
import Signup from './components/auth/Signup.vue';
import Home from './components/shared/Home.vue';
import ProductsHome from './components/dashboard/Products/ProductsHome.vue';
import ProductOverview from './components/dashboard/Products/ProductsOverview.vue';
import CreateProduct from './components/dashboard/Products/CreateProduct.vue';
import CreateCategory from './components/dashboard/Category/CreateCategory.vue';
import EditCategory from './components/dashboard/Category/EditCategory.vue';
import {store} from './store/store.js';
export const routes = [
{path: '/', component: Home},
{ path: '/login', component: Login },
{ path: '/registrarse', component: Signup },
{
path: '/dashboard',
component: Dashboard,
name: 'dashboard',
beforeEnter: (to, from, next) => {
if(to.name === 'dashboard') {
if(store.state.User.credentials.tokenId === null) {
next('/');
//TODO, Hacerlo global y verificar que el dashboard y sus hijos no accedan.
} else {
next();
}
}
next();
},
children: [
{
path: 'productosHome',
component: ProductsHome,
children: [
{
path: '',
component: ProductOverview
},
{
path: 'crearProducto',
component: CreateProduct
},
{
path: 'crearCategoria',
component: CreateCategory
},
{
path: 'editarCategorias',
component: EditCategory
}
]
}
]
}
];
The thing is with the dashboard. When I enter the dashboard or any of its sub-routes (with its router-link component) they don't follow the proper URL path. For example: If a visit the 'productosHome' the URL it's just '/productosHome' and not '/dashboard/productosHome. This same problem applies for every productosHome's child route.
Now, let me show to you my templates:
Dashboard.vue
<template>
<div>
<div class="container is-fluid has-background-light">
<h1 class="title has-text-centered pt-3">Dashboard</h1>
</div>
<section class="section py-3 has-background-light prueba section-dashboard">
<div class="container is-fluid remove-padding dashboard">
<aside class="nav-aside has-background-white">
<div>
<!--El anchor sera nuestro router-link-->
<!-- aside-link-active -->
<a href="#" class="aside-link">
<span class="icon">
<i class="fas fa-users"></i>
</span>
<span class="aside-link-text">Clientes</span>
</a>
</div>
<div>
<router-link class="aside-link"
active-class="aside-link-active"
to="productosHome">
<span class="icon">
<i class="fas fa-tags"></i>
</span>
<span class="aside-link-text">Productos</span>
</router-link>
</div>
<div>
<a href="#" class="aside-link">
<span class="icon">
<i class="fas fa-boxes"></i>
</span>
<span class="aside-link-text">
Pedidos
</span>
</a>
</div>
</aside>
<div class="main-content has-background-white">
<router-view></router-view>
</div>
</div>
</section>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.aside-link.aside-link-active:hover {
color: white;
}
</style>
ProductsHome.vue
<template>
<div>
<div class="tabs is-medium pt-2 mb-0">
<ul>
<!-- is-active -->
<router-link to="crearProducto"
active-class="is-active"
tag="li">
<a>Crear</a>
</router-link>
<li><a>Editar</a></li>
<li><a>Buscar</a></li>
<router-link to="crearCategoria"
active-class="is-active"
tag="li">
<a>| Crear categoría</a>
</router-link>
<router-link to="editarCategorias"
active-class="is-active"
tag="li">
<a>Editar categoria</a>
</router-link>
</ul>
</div>
<div class="main-content__content block p-2">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
Note that Products Home also have children.
Also, I'm debugging routes with the famous Vue plugin and see what says:
'/' is marked has active, Is that correct?
I'm confused :D
The routes file is correct. The issue is with the router link on both files. there are 2 ways you can define router-link>to.
Absolute / Relative Path.
Absolute Path(From any file)
<router-link to="/dashboard/productosHome/">Products Home</router-link>
Relative Path(From dashboard page)
<router-link to="productosHome">Products Home</router-link>
Route object. (From any file)
<router-link :to="{ path: `/dashboard/productosHome/`}">Products Home</router-link>
No 2 gives you a bit more control. you can now name the route and use them. Like you did for dashboard main route. name: 'dashboard',. Now you can name the subroute.
{
path: 'crearProducto',
component: CreateProduct,
name: 'crearProducto'
},
router link will be
<router-link :to="{ name: 'crearProducto'}">Crear Producto</router-link>
Check Documentation for more https://router.vuejs.org/api/#to
When declaring paths in the to attribute of router-link, you need to define the full path including the root "/". E.g.: "/dashboard/productosHome"

Vue how to customize global navbar at view level

Im super new to Vue.
i have a Vue-CLI app, which have a navbar and content.
Navbar is common to all pages, but i want to customize in each page whit some additional content.
Example:
Common-> home | about
View home -> home | about | your are in view home
View about -> home | about | your are in view about
router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';
import NavBar from '#/components/NavBar.vue';
Vue.use(VueRouter);
Vue.component('nav-bar', NavBar);
//...
components/navbar.vue
<template>
<div>
<b-nav-item to="/">home</b-nav-item>
<b-nav-item to="/about">about</b-nav-item>
{{customContent}}
</div>
</template>
<script>
export default {
name: 'NavBar',
props: {
customContent: {
type: String,
default: 'default Content',
},
},
};
</script>
App.vue
<template>
<div id="app">
<nav-bar />
<div class="container-fluid">
<router-view />
</div>
</div>
</template>
views/home.vue
<template>
<div class="row">
<div class="col-12">
<image-card :images="images"/>
</div>
</div>
</template>
<script>
//how can i customize here the navbar by adding for example 'your are in view home'???
</script>
Thanks so much!
There are a few ways in which you can solve this problem. I'll list two of them.
1. Update NavBar by $route
In this approach, the NavBar component already contains all of the possible combinations, and will display the relevant portion(s) depending on what $route contains.
Here's some pseudo code:
navbar.vue
<template>
<div class="navbar">
<div class="navbar-left>
APPNAME
</div>
<div v-if="name === 'landing'">
...
</div>
<div v-else-if="name === 'room'">
...
</div>
</div>
</template>
App.vue
<template>
<div id="app">
<NavBar :name="$route.name"/>
<main>
<router-view/>
</main>
</div>
</template>
In this example, the NavBar component is very rigid, and doesn't really lend itself to much reuse. However, it does encapsulate all the relevant code relating to the nav bar.
2. Extensible NavBar with slots
In this approach, the NavBar only provides the bare-minimum to create a nav bar. The rest of the route-specific elements are to be filled in by the views.
navbar.vue
<template>
<div class="navbar">
<div class="navbar-left">
<div class="navbar-brand">
APPNAME
</div>
<slot name="left"></slot>
</div>
<div class="navbar-right">
<slot name="right"></slot>
</div>
</div>
</template>
App.vue
<template>
<div id="app">
<router-view/>
</div>
</template>
landing.vue
<template>
<div>
<header>
<NavBar>
<template slot="right">
<span>
<div class="navbar-item">
<div class="buttons">
<button class="button" #click="...">Start Watching</button>
</div>
</div>
</span>
</template>
</NavBar>
</header>
<main>
...
</main>
</div>
</template>
This approach has a bit of repetition in terms of DOM elements, but gives you an extremely flexible NavBar that can be customized by each view.
The approach you want to use depends on what is important to you.
If strict encapsulation is what you want, then you may want to use approach 1, as all of the NavBar-related code is contained within a single file.
However, if you believe that there is a potential for reuse, or if you would like all view-related code to live in one place, then it makes sense to use slots instead and extend the NavBar as required by each view.
I use a breadcrumb to achieve a similar thing. Just an idea but Vue router allows you to add meta data to the current route which you always have access to
router.js
path: '/add',
name: 'add',
component: () => import(/* webpackChunkName: "add" */ '../../views/Add.vue'),
meta: {
breadCrumb: [
{ name: 'Add New' }
]
},
Notice the meta object attached to the route.. this will be used to describe the current view.
Breadcrumb.vue component
<template>
<div class="breadcrumb">
<ul class="d-flex m-0 p-0"
<li
v-for="(breadcrumb, idx) in breadcrumbList"
:key="idx">
{{ breadcrumb.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Breadcrumb',
data () {
return {
breadcrumbList: []
}
},
mounted () { this.updateList() },
watch: { '$route' () { this.updateList() } },
methods: {
routeTo (pRouteTo) {
if (this.breadcrumbList[pRouteTo].link) this.$router.push(this.breadcrumbList[pRouteTo].link)
},
updateList () { this.breadcrumbList = this.$route.meta.breadCrumb },
formatPath(path) {
const newPath = path.replace(/\//g, " > ")
return newPath
}
}
}
</script>
And then you can import the breadcrumb into your navbar or where ever you would like to place it
<Breadcrumb class="breadcrumb" />
import Breadcrumb from '#/components/Breadcrumb.vue'
components: {Breadcrumb}
So basically the breadcrumb will always watch your current route and change the data based on the meta data you provide in your router.js file
You can access to router name like this:
<div v-if="this.$route.name == 'home'">
<HeaderTransparent />
</div>
<div v-else>
<HeaderWhite />
</div>

Laravel 5.4 Vue Declarative Rendering

In a laravel 5.4 environment I want to render the text "Example" in the .panel-heading of Example.vue. After doing npm run watch I get the following Vue warn:
'Property or method "message" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.'
app.js
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example', require('./components/Example.vue'));
const app = new Vue({
el: '#app',
data: {
message: 'Example'
}
});
Example.vue
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading" >{{ message }}</div>
<div class="panel-body">
I'm an example component!
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
app.blade.php
<html>
<!-- ... -->
<body>
<div id="app">
<example></example>
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
Your Example.vue component doesn't have access to its parent's properties. You need to define message within the same scope of the component you are trying to use it in.
You can do this by adding message as a data property in your Example component:
// Example.vue script
export default {
data() {
return {
message: 'Example',
}
},
}
Or you can pass it in as a prop:
// Example.vue script
export default {
props: ['message'],
}
In your case, you would pass a value for the message prop like this:
// in app.blade.php
<example message="Example"></example>
Here's the documentation on Vue Component props.

Vuejs 2 Sending props to xxx.vue file

Normally you send props like this way
Vue.component('child', {
// camelCase in JavaScript
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
How can i achieve with require:
Vue.component('lw-login', require('./components/login.vue'));
Laravel Blade Template:
<lw-login
heading="Login"
action="{{ route('login') }}"
email="E-mailadres"
passwordrequest="{{ route('password.request') }}"
></lw-login>
login.vue:
See {{ heading }}
I am getting this error:
[Vue warn]: Property or method "heading" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
(found in at C:\Code\cms\resources\assets\js\components\login.vue)
<template>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">{{ heading }}</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" :action="action">
etc .....
<script>
export default {
mounted() {
props: ['heading','action','passwordrequest']
}
}
</script>
Changed this:
<script>
export default {
mounted() {
props: ['heading','action','passwordrequest'],
}
}
</script>
To this :)) :
<script>
export default {
props: ['heading','action','passwordrequest'],
mounted() {
}
}
</script>