How do I declare reactive properties in Vue.js - javascript

This is a part of a Vue-routes application, in one of the routes I have two properties, bga and bgb that will be used to change the colors of divs. I do not know how to declare them correctly, how do I do that?
I get this messages in the Chrome console:
vue.js:597 [Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions.
warn # vue.js:597
vue.js:597 [Vue warn]: Property or method "bga", "bgb" 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. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
ColorPage.js
const ColorPage = {
props:
['bga', 'bgb'],
data: {
bga: {
backgroundColor: ''
},
bgb: {
backgroundColor: ''
}
},
template: `
<div id="middle">
<label id="colorLabel"><h2>'Change Colors By Typing Their Names:'</h2></label>
</br>
<input type="text" class="colorInput" v-on:input="bga.backgroundColor = $event.target.value" placeholder="here...">
</br>
<input type="text" class="colorInput" v-on:input="bgb.backgroundColor = $event.target.value" placeholder="... and here!">
</div>
`
,
};
export default ColorPage
This should be used to change the colors of the "container" div and the "top" div:
Index.html
<div id="container" v-bind:style="bga">
<div class="top" v-bind:style="bgb">
<div id="app">
<h1 id="vueHead">Vue routing</h1>
<h2 class="menu">
<router-link to="/">Color</router-link>
<router-link to="/main">Main</router-link>
<router-link to="/settings">Settings</router-link>
<router-link to="/vue">Vue</router-link>
</h2>
</div>
</div>
<router-view></router-view>
</div>
Vue routes is place in index.js:
import MainPage from '../components/mainPage.js'
import ColorPage from '../components/colorPage.js'
const routes = [
{path: '/', component: ColorPage},
{path: '/main', component: MainPage},
];
const router = new VueRouter({
routes // short for `routes: routes`
});
var vm = new Vue({
el: '#container',
router,
});

When you're creating a component there's slight differences between some of the typical syntax with Vue. For instance Data Must Be a Function.
..
data: {
reactive: true,
}
..
In a standard Vue instance the above is perfectly fine. However when you create a component the data property needs to be a function that returns an object:
..
data() {
return { reactive: true }
}
..
Additionally props are available to you just the same as any other property in data.

Related

Vue.js component: Props as object doesn’t work with x-template

To simplify the markup of a Vue component, I’m trying to use an object for the props.
When defining the template of the component as described in the code example on Components Basics — Vue.js all works fine. But trying to define the template as an x-template, I’m getting an error saying, that the property 'title' of undefined cannot be read.
Here’s the code:
<div id="app">
<script type="text/x-template" id="post-template">
<div class="blog-post">
<h3>{{ post.title }}</h3>
<div v-html="post.content"></div>
</div>
</script>
<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post"></blog-post>
</div>
const data = {
posts: [
{
title: "Hello World",
content: "Bar"
}
]
};
let postComponent = {
props: ['post'],
template: 'post-template'
}
const vue = new Vue({
el: '#app',
components: {
'blog-post': postComponent
},
data() {
return data;
}
});
Is it not possible to access object properties in a x-template or is there something wrong with my code?
Two things:
Take the x-template outside of your app div. Vue is going to replace all the content in the div, so that template will be lost
postComponent should refer to template with a selector, so #post-template instead of post-template
Here's a demo of it working: https://jsfiddle.net/vzj5g2sn/

Params not being passed throug router link on Vuejs

I am trying to pass properties to a component through a router-link on Vuejs, but the component is not recieving them properly. I have a main menu and a secondary menu, which is where I want to pass the properties, when a main menu button is clicked:
const Sidebar = {
name:'sidebar',
template:`
<div>
Sidemenu
<router-link v-for="route in routes" v-key="route" :to="route">{{route}}</router-link>
</div>`,
props: {
routes:{
type: Array,
required: true,
default: function(){return []}
}
}
}
const AppMenu = {
name:'app-menu',
template:`
<div>
<router-link :to="{name:'project', params:{routes: projectMenus}}">Project</router-link>
<router-link :to="{name:'assets', params:{routes: assetsMenus}}">Assets</router-link>
</div>`,
data: function(){
return{
projectMenus: ['overview', 'settings'],
assetsMenus: ['landscapes', 'characters']
}
}
}
const App = {
template:`
<div>
<app-menu/>
<router-view name="sideview"/>
<router-view name="sectionview"/>
</div>`,
components:{AppMenu}
};
const Routes= [
{path: '/', name:'home', redirect: 'project'},
{path:'/project', name:'project', components:{sideview:Sidebar}, props:{sideview:true}},
{path:'/assets', name:'assets', components:{sideview:Sidebar}, props:{sideview:true}}
]
The Sidebar component is rendering, because I can see "Sidemenu" on the page, but the console throws [Vue warn]: Missing required prop: "routes" on Sidebar, so my submenu links are not shown. I've searched on the docs, and many similar issues in many forums, but I can't find what I'm doing wrong.
When you make props an object in the vue routes definitions, it will replace the components props. You are setting them as {sideview: true} which overrides all props in your Sidebar component.
At least that is my understanding from https://router.vuejs.org/guide/essentials/passing-props.html#object-mode

passing props data to component which i can only access with routes

My router file
import DomainAction from './components/domainaction/DomainAction.vue'
...
{ path: '/domainaction' , component: DomainAction },
...
router link File
...
<router-link to="/domainaction" tag="li" class="list-group-item "class-active="active" exact > Domain Action</router-link>
...
From another routes going to the domainaction Route like this
...
itemAction(action,data){
if(action=='Suspend'){
this.$router.push('/domainaction')
}
}
...
My Actual DomainAction component
<template>
.......
</template>
<script>
export default {
props:['data'],
data(){
return{
.........
</script>
I want to pass data props from itemAction function .
How do i achieve this ?
I'm new to vue js .Sorry if my question is not very complete.
Well if you just need to pass a property (a value) to the component, you just need to use data passing via the router's props: https://router.vuejs.org/guide/essentials/passing-props.html#function- mode.
And receive using this.$router within the component.
Alternatively you can use the Vuex for data passing.
https://vuex.vuejs.org/
So that you can make a communication between components outside this form that was informed, both components have to be parent and child, ie, 1 calls the other inside it, so yes you can pass the values, otherwise it should be used, or the data path via route, or via vuex which is the vue status manager.
There is also the following possibility, as requested in this question.
Passing props to Vue.js components instantiated by Vue-router
Note that sosmii is right about using a Vuex to share data across components.
But if you're looking into pass soma data as params using routes, you have to change a little bit how you're defining the components routes. Using a routers params you would be able to pass props, then you can push the route and add params. See example below.
And related question:
Passing props with programmatic navigation Vue.js
const DomainActionA = {
props: ['dataProp'],
template: '<div>A data: {{dataProp}}</div>'
}
const DomainActionB = {
props: ['dataProp'],
template: '<div>B data: {{dataProp}}</div>'
}
const routes = [
{
path: '/DomainActionA/:dataProp',
name: 'domainA',
component: DomainActionA,
props: true },
{
path: '/DomainActionB/:dataProp',
name: 'domainB',
component: DomainActionB,
props: true
}
]
const router = new VueRouter({
routes
})
const app = new Vue({
router,
methods: {
goToA() {
this.$router.push({name: 'domainA', params: {dataProp: "blah"}})
},
goToB() {
this.$router.push({name: 'domainB', params: {dataProp: "bleh"}})
}
}
}).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<h1>Hello Router!</h1>
<div>
<button #click="goToA()">Go A with params: { data: "blah" }</button>
<button #click="goToB()">Go B with params: { data: "bleh" }</button>
</div>
<div>
<h2>router view</h2>
<router-view></router-view>
</div>
</div>
you should use vuex
props are designed to pass variables from a parent component to child components,
so it is unusual to use it when you want to share data between pages.
an example of right usage of prop:
parent.vue
<child-component :data="data">
<child-component :data="anotherData">
so, if you want to share variables between pages, use vuex (store pattern) instead.
similar question:
https://stackoverflow.com/a/40955110/10440108

How to pass params from div to single page component in Vue.js?

I have such code on different pages:
<div id="contact-us" class="section md-padding bg-grey">
<div id="contact"></div>
<script src="/dist/build.js"></script>
</div>
I have main.js:
import Vue from 'vue'
import Contact from './Contact.vue'
new Vue({
el: '#contact',
render: h => h(Contact)
})
And Contact.vue with a template
I want to know from which page component was used. So I need to pass param from div like <div id="contact" page="main"></div> . How can I implement this?
How to pass params from div to single page component in Vue.js?
You can't pass params from a div since it's a html tag and a not custom component, you should define your own component that accepts the properties you want to pass.
So first you should define your component and define the property is allow to receive, then you use your component, take a look to the below example, and you may find more information about passing props here.
Vue.component('your-component', {
props: ['property'],
template: '<h3>{{ property }}</h3>'
})
new Vue({
el: '#app'
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<your-component :property="'Hello props'" />
</div>
Example using Single File Component structure.
Parent component:
<template>
<ChildComponent :property="propValue" />
</template>
<script>
import childComponent from './childComponent.vue';
export default {
components: {
ChildComponent: childComponent
},
data() {
return {
propValue: 'Hello prop'
}
}
}
</script>
Children component:
<template>
<h3>{{ property }}</h3>
</template>
<script>
export default {
props: ['property'] // You can add more properties separeted by commas
}
</script>

Vue-Routes is not functioning when a template in one of the routes is referring to the same ID

I am developing a Vue application with Vue-routes. One of the routes has a function, that is meant to change the background colors of two divs by writing the wanted colors in re respective input fields. But there are two problems. The router is not working since I wrote this color changing function and the color change doesn't work either. So it's is basically a "fail-fail" situation. I am receiving this message from the console in Google inspection: "vue.js:597 [Vue warn]: Cannot find element: #container".
I am sure that these problems are intertwined, the question is how do I solve them?
HTML
<div id="container" v-bind:style="bga">
<div class="top" v-bind:style="bgb">
<div id="app">
<h1 id="vueHead">Vue routing</h1>
<h2 class="menu">
<router-link to="/">Color</router-link>
<router-link to="/main">Main</router-link>
</h2>
</div>
</div>
<!-- component matched by the route will render here -->
<router-view></router-view>
</div>
index.js (routes)
import MainPage from '../components/mainPage.js'
import ColorPage from '../components/colorPage.js'
var urlend;
const routes = [
{path: '/', component: ColorPage},
{path: '/main', component: MainPage},
];
const router = new VueRouter({
routes // short for `routes: routes`
});
var vm = new Vue({
el: '#container',
router
});
colorpage.js
const ColorPage = {
template: `
<div id="middle">
<label id="colorLabel"><h2> {{ info }} </h2></label>
</br>
<input type="text" class="colorInput" v-on:input="bga.backgroundColor = $event.target.value" placeholder="here...">
</br>
<input type="text" class="colorInput" v-on:input="bgb.backgroundColor = $event.target.value" placeholder="... and here!">
</div>
`
};
var color = new Vue({
el: '#container',
data: {
info: 'Change Colors By Typing Their Names:',
bga: {
backgroundColor: ''
},
bgb: {
backgroundColor: ''
}
}
});
export default ColorPage
In colorpage.js you have new Vue(). This creates a new Vue instance. What you're likely looking for is creating a new component.
For the component you don't need to define where to mount it with el, but rather Vue router takes care of it. Inside your Vue application you should define el only once and that's where the Vue instance mounts itself. After the Vue instance has mounted itself, routing happens inside Vue.

Categories

Resources