I'm trying to transfer data form my main vue js to a vue component. My project is built with laravel. I've app.js that mainly work for vue. And also have other components. I would like to transfer data between them.
Please check my code.
This is my app.js
require('./bootstrap');
import Vue from "vue";
import VueResource from 'vue-resource'
Vue.use(VueResource);
Vue.http.headers.common['X-CSRF-TOKEN'] = $('input[name="csrf-token"]').attr('value');
Vue.component('google-map', require('./components/GoogleMap.vue'));
const app = new Vue({
el: '#app',
data: {
lat: 0,
lng: 0,
center: { lat: 45.508, lng: -73.587 },
},
created(){
this.lat = 34.20;
this.lng = 100.36;
this.setCenter();
},
methods: {
setCenter(){
this.center.lat = parseFloat(this.lat);
this.center.lng = parseFloat(this.lng);
}
}
});
This is my GoogleMap.vue
<template>
<div>
</div>
</template>
<script>
export default {
name: "GoogleMap",
data() {
return {
center: { lat: 45.508, lng: -73.587 },
};
},
mounted() {
this.centerFun();
},
methods: {
centerFun(){
console.log(this.center);
}
}
};
</script>
This is my map.php
<html>
<head>
<title>Map</title>
</head>
<body>
<div id="app">
<label>Lat</label><input type="text" name="" v-model="lat" #keyup="testFun">
<label>Lng</label><input type="text" name="" v-model="lng" #keyup="testFun">
<google-map></google-map>
</div>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
You can see there are two "center" var.
Can I bind those to a single one? Or what can I do?
If I've multiple components, how can I transfer data form app.js to those components or those components to app.js?
Update GoogleMap.vue to this:
<template>
<div>
</div>
</template>
<script>
export default {
name: "GoogleMap",
props: ['center'],
data() {
return {
// center: { lat: 45.508, lng: -73.587 },
};
},
mounted() {
// this.centerFun();
},
methods: {
//centerFun(){
// console.log(this.center);
//}
}
};
</script>
...so that it can accept the center prop from the parent component. And then send center from your parent component to googlemap component like this:
<google-map :center="center"></google-map>
As #AlxTheRed mentioned, more info about how props work can be found at:
https://v2.vuejs.org/v2/guide/components-props.html
You can pass values from parent component to child component via props.
Declare the variables you want from the parent component as props in child component.
In parent component, where you are including your child component:
<child-comp var1="abc" :var2="xyz"></child-comp>
In child component's instance, declare these as props:
props: ['var1','var2'],
Now, in child component, you can directly access them as:
this.var1
Read more here:
https://v2.vuejs.org/v2/guide/components.html
If your structure contains many dependencies, I suggest you to use vuex.
Related
How can i pass variable to component in Vue.js (not via props)? Is that possible?
Here app.js:
import PlayingField from '../app/components/PlayingField'
import GameConfig from '../../gameConfig'
new Vue({
el: '#app',
components: {
playingfield: PlayingField,
},
data: {
gameConfig: GameConfig
}
});
In game config is json and there is key 'maxUniqueCards' and this value i want in component playingField... No in template but in attribute to next work with it... (generate cards, order.... just for usage in playingField component methods...)
You can use the $parent property:
<template>
<div>
App
<input type="text" v-model="propTest">
<Child />
</div>
</template>
<script>
import Child from '#/components/Child.vue';
export default {
name: 'App',
components: { Child },
data: () => ({
propTest: 'abc',
}),
};
</script>
<template>
<div>
child
<button #click="test">Test</button>
</div>
</template>
<script>
export default {
name: 'Child',
methods: {
test() {
console.log(this.$parent.propTest);
},
},
};
</script>
Be careful with this property, you must use in edge cases: https://v2.vuejs.org/v2/guide/components-edge-cases.html#Accessing-the-Parent-Component-Instance
I'm using vue to make an arc gis driven application, because the map's center can changed based on user location, I am setting the default location to some props then passing them into my map component to be called in the map components mounted() hook for rendering.
I think i'm pretty close to doing this correctly but when I log my props in my map component in the console it says they're undefined.
I'm not sure if my app code is at fault or my child component code?
as you can see in my app.vue I am even trying to pass in plain integers to test the values and they are still undefined.
app.vue
<template>
<div id="app">
<web-map v-bind:centerX="-118" v-bind:centerY="34" />
<div class="center">
<b-button class="btn-block" #click="getLocation" variant="primary">My Location</b-button>
</div>
</div>
</template>
<script>
import WebMap from './components/webmap.vue';
export default {
name: 'App',
components: { WebMap },
data(){
return{
lat: -118,
long: 34
}
},
};
</script>
webmap.vue
<template>
<div></div>
</template>
<script>
import { loadModules } from 'esri-loader';
export default {
name: 'web-map',
props:['centerX, centerY'],
data: function(){
return{
X: this.centerX,
Y: this.centerY
}
},
mounted() {
console.log(this.X,this.Y)
// lazy load the required ArcGIS API for JavaScript modules and CSS
loadModules(['esri/Map', 'esri/views/MapView'], { css: true })
.then(([ArcGISMap, MapView]) => {
const map = new ArcGISMap({
basemap: 'topo-vector'
});
this.view = new MapView({
container: this.$el,
map: map,
center: [this.X,this.Y], ///USE PROPS HERE FOR NEW CENTER
zoom: 8
});
});
},
beforeDestroy() {
if (this.view) {
// destroy the map view
this.view.container = null;
}
}
};
</script>
There is a typo. Change:
props:['centerX, centerY'],
to:
props:['centerX', 'centerY'],
I have a string (example, because it's an object with many key/values, want to loop and append to htmloutput) with a component name. Is it possible to render/build the component inside a method and display the html output?
Is that possible and how can i achieve that?
<template>
<div v-html="htmloutput"></div>
</template>
<script>
export default {
component: {
ComponentTest
},
data() {
return {
htmloutput: ''
}
},
methods:{
makeHtml(){
let string = 'component-test';//ComponentTest
//render the ComponentTest directly
this.htmloutput = ===>'HERE TO RENDER/BUILD THE COMPONENTTEST'<==
}
},
created(){
this.makeHtml();
}
</script>
You might be looking for dynamic components:
https://v2.vuejs.org/v2/guide/components-dynamic-async.html
Example:
<template>
<component :is="changeableComponent">
</component>
</template>
<script>
import FirstComponent from '#/views/first';
import SecondComponent from '#/views/second';
export default {
components: {
FirstComponent, SecondComponent
},
computed: {
changeableComponent() {
// Return 'first-component' or 'second-component' here which corresponds
// to one of the 2 included components.
return 'first-component';
}
}
}
</script>
Maybe this will help - https://forum.vuejs.org/t/how-can-i-get-rendered-html-code-of-vue-component/19421
StarRating is a sample Vue component. You can get it HTML code by run:
new Vue({
...StarRating,
parent: this,
propsData: { /* pass props here*/ }
}).$mount().$el.outerHTML
in Your method. Remember about import Vue from 'vue'; and of course import component.
What you're trying to do really isn't best practice for Vue.
It's better to use v-if and v-for to conditionally render your component in the <template> section.
Yes you can use the render function for that here is an example :
Vue.component('CompnentTest', {
data() {
return {
text: 'some text inside the header'
}
},
render(createElement) {
return createElement('h1', this.text)
}
})
new Vue({
el: '#app',
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<Compnent-test />
</div>
Or :
if you are using Vue-cli :
on your componentTest component :
export default {
render(createElement) {
return createElement('h1', 'sometext')
}
// Same as
// <template>
// <h1>sometext</h1>
// </template>
//
}
and on your root element (App.vue as default) :
export default {
....
component: {
ComponentTest
}
}
<template>
<div>
....
<Component-test />
</div>
</template>
example : codesandbox
you can read more about
Render Functions & JSX
<template>
<div id="app">
<Loading></Loading>
<Content></Content>
</div>
</template>
<script>
import Loading from './Loading.vue'
import Content from './Content.vue'
export default {
name: 'App',
components: {
Loading,
Content
}
}
</script>
What is the best and elegant way to handle a loading component and remove it (or vue component or change styles) when all page is loaded?
I tried with v-cloack, but I think its not working beyond data stuff.
I tried with mounted, but doesn't seems to work.
v-cloak is to hide un-compiled mustache bindings until the Vue instance is ready. So you can use v-if to show/hide loading component.
var child1 = Vue.extend({
template: "<div>Loading...</div>"
});
var child2 = Vue.extend({
template: "<div>After Component loaded</div>",
});
var app = new Vue({
el: "#vue-instance",
data: {
loading: true
},
mounted() {
var vm = this;
setTimeout(function() {
vm.loading = false;
}, 1000);
},
components: {
child1,
child2
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.1/vue.js"></script>
<div id="vue-instance">
<child1 :name="name" v-if="loading"></child1>
<child2 :name="name" v-if="!loading"></child2>
</div>
I want to know how to get data from Vue.component and send to
this >>var app = new Vue({ })<<
this is my code
Vue.component('my-form', {
template: '#my-form',
props:['ddTechtemp'],
data: function () {
return {
isCores: app.testCorres,
activeClass: 'isCorrespon',
errorClass: 'isTech',
tempData : {cell1 : "",
cell2 : "",
cell3 : "",
cell4 : "",
cell5 : "",
cell6 : ""
},
}
},
watch:{
tempData:{
handler:function(newVal,oldVal){
app.ddTechtemp = newVal;
},
deep:true,
}
},
methods:{
}});
I want to get data from above code and send to this code var app = new Vue({ data: Vue.component.data})
Anyone understand me please help.Thank you
In Vue.js parent-child relationship is run by
1) passing props from parent to child
2) emitting custom events from child to parent
So, if you need to pass some data from child to parent - use this.$emit to emit a custom event with your data, and listen for this event in parent component with v-on:myevent or #myevent shorthand. The data you pass with event is found in $event variable.
Example: https://jsfiddle.net/wostex/63t082p2/51/
<div id="app">
<myform #newdata="handleData($event)"></myform>
<p>name: {{ user.name }}</p>
<p>age: {{ user.age }}</p>
</div>
new Vue({
el: '#app',
data: {
user: { name: '', age: 0 }
},
methods: {
handleData: function(e) {
[this.user.name, this.user.age] = e;
}
},
components: {
'myform': {
template: `
<div>
<input type="text" v-model="formData.name" placeholder="Your name">
<input type="number" v-model.number="formData.age">
</div>`,
data: function() {
return { formData: { name: '', age: 0 } }
},
watch: {
formData: {
handler: function() {
this.$emit('newdata', [this.formData.name, this.formData.age]);
},
deep: true
}
}
}
}
});
Another way would be to work with advanced things like a Vuex store for ''state management'' but for simple implementations one additional reactive component would work as well.
in src/store/index.js
import { reactive } from 'vue';
export const store = reactive({
some_id : 0,
});
And in a component src/component/SelectComponent.vue
<script setup>
import { store } from "#/store";
</script>
<script>
export default {
name: "SelectComponent",
// rest of the component source here
}
</script>
<template>
<select v-model="store.some_id">
<option v-for="itm in list" :key=itm.id" :value="itm.id">{{ itm.text }}</option>
</select>
</template>
Using the component in src/views/SomeView.vue
<script setup>
import { store } from "#/store";
import SelectComponent from "#/components/SelectComponent"
</script>
<script>
//... use store.some_id in some method
</script>
You can store all your global variables in the store/index.js file and keep reactive. You might want to add watchers to observe the store variable(s).
WARNING: this is discouraged for large, complex Vue applications
NOTE: this is an easy approach for simple state management not requrring Vuex with all the actions and mutations, states and contexts - plumbing.