I'm trying to pass php/laravel data to my component from a custom global variable. I've seen examples of this going into the new Vue({}) area directly but I haven't seen any way to pass this by going into right into the component
<script>
var itemData = //json object
</script>
<custom-component item-data="ITEMDATAVAR"></custom-component>
I should specify that I do have item-data in my component props. The issue is that I'm not sure how to tell my component's html that I'm passing the value of the variable itemData and not the string "itemData"
I think you are referring to dynamic props
<custom-component v-bind:item-data="ITEMDATAVAR"></custom-component>
or use the shorthand syntax
<custom-component :item-data="ITEMDATAVAR"></custom-component>
You should add the item-data to the props array like this:
Vue.component('custom-component', {
props: ['item-data'],
...
}
You can research this Vue.js example
Create a variable
new Vue({
el: '#el',
data: yourJsonObject
})
In you component you have to write about props
Vue.component('custom-component', {
props: ['item-data']
...
}
Pass the data to the component the same way
<custom-component item-data="ITEMDATAVAR"></custom-component>
I have not tested how it will work, guided by the documentation.
Related
Hello everyone,
Let me give you a little bit of context about my problem :
I'm trying to create a system that can add charts on a page with the simple push of a button.
These charts are going to contain elements from a MySQL database.
I have a Chart.vue file that contains the template for a single HighChart element. It also contains a prop :
export default {
name : "Chart",
props : ["tableToDisplay"],
And then I have my main vue that is named "Test.vue".
It imports the Chart.vue from the component folder and then I basically just need to write :
<Chart :table-to-display="tableToDisplay"/>
to create an instance of a chart of the table contained within the variable : this.tableToDisplay.
But this is not what I want to do : I want to create a chart with the push of a button, so I made some changes :
<div>
<button #click="createGraph">Add a graph</button>
<Chart :table-to-display="tableToDisplay"/>
</div>
And with it, I created the method:
createGraph(event)
{
let ChartClass = Vue.extend(Chart)
console.log(ChartClass)
let graphInstance = new ChartClass({
props:{
"tableToDisplay": this.tableToDisplay
}
})
graphInstance.$mount()
let divContainer = event.target.parentElement
divContainer.append(graphInstance.$el)
},
That is where my problem is.
Within that method, I want to send a table to display to the newly created Chart, but it seems that I can't manipulate the props value in that way.
I thought that this piece of code was the solution :
let graphInstance = new ChartClass({
props:{
"tableToDisplay": this.tableToDisplay
}
})
But It turns out that it is not.
When I click the button, an empty chart does appear but the prop "tableToDisplay" is undefined.
I looked at the console and I get a "[Vue warn]: Error in the mounted hook: "TypeError: ciphertext is null".
It doesn't matter if I put an argument or not in the ChartClass, I always have this error on the graphInstance.$mount() line.
First, I think you don't need to programatically instantiate your Chart components. A simple v-for loop will do the trick:
<template>
<Chart v-for="table of chartTables :table-to-display="table"/>
</template>
<script>
...
data() {
chartTables: []
},
methods: {
createChart() {
// Adding a new table to the array will create a new Chart component.
this.chartTables.push(this.tableToDisplay)
}
}
</script>
If this solution suits your needs, go ahead in that way!
That said, if you really need to instantiate a Vue component yourself, you have to use the propsData parameter to pass your props.
const instance = new ChartClass({
parent: this, // The parent is your current component
propsData: {
tableToDisplay: this.tableToDisplay,
},
})
let divContainer = event.target.parentElement
instance.$mount(divContainer)
The parent option is really important: it adds your component to the Vue component dependency tree. Without it, your component won't have inherited properties (such as the Vuex store, plugins etc.).
I have a component called ShowComment and a component called EditComment.
In ShowComment there is a variable this.CommentRecID. I want to use this variable in the component EditComment.
The problem is that a console.log(this.CommentRecID); shows that the variable is undefined in EditComment, but defined in ShowComment, but I don't know why it's undefined:
I used this to "use" this.CommentRecID in EditComment, but I don't know if this is the correct way to do it because it's related to jquery:
import * as $ from "jquery";
import DatePicker from "vue2-datepicker";
export default {
props: ["CommentRecID"],
components: { DatePicker },
Here's the full ShowComment component: https://pastebin.com/fcy4PCq0
Here's the full Editcomment component: https://pastebin.com/uik7EwD1
I'm fairly new to Vue.js. Does someone know how one can solve this issue?
You should not use jQuery and Vue.js at the same time.
You should try to use props to send data from parent to child.
You could add EditComment as an element in your ShowComment something like this:
<EditComment CommentRecID="this.CommentRecID" v-if="showEdit" />
And toggle the showEdit flag from the editItem method
editItem() {
this.showEdit = true
}
If you want to show a modal, then your EditComment component is probably up the tree so you could either use EventBus or use Vuex.
It seems like you are already using Vuex in your project, so add a mutation that stores the CommentRecID and use it in a similar manner to show the dialog.
You can use Vue Props to easily solve this problem, you have to send the variable from parent component to child component, please check this PROPS documentation out, its self explanatory:
Props Vuejs documentation
please let me know if you find trouble in using props
i set a property in window Object for using it globally, like this:
window.configs.foo=true;
but when use it like this:
<v-btn v-if="window.configs.foo">go</v-btn>
in console, i get this error:
[Vue warn]: Property or method "window" 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.
how i can use window object in vueJs template?
Because v-if is intended to be used on properties of your component. You cannot v-if over variables in global scope, or outside your component data or properties.
What you can do, instead, if to setup a computed property on your component that targets window.configs.foo:
new Vue({ // or maybe a component, this depend on how you're using it
template: `<div>
<v-btn v-if="showMyButton">...</v-btn>
</div>`
computed: {
showMyButton() {
return window.configs && window.configs.foo;
}
}
})
UPDATE:
If you have to reuse this in a lot of sites, there are two things that you can do:
Vuex
Using vuex to set the showMyButton as a vuex state. Then you can access it via:
v-if="$store.state.showMyButton"
And you can modify it via standard vuex mutations.
Mixins
Maybe for some reason you don't want to use vuex. Then a way to reuse logic across many components is to use mixins.
const configAwareMixin = {
computed: {
showButton() {
return window.configs.foo;
}
}
}
// And then in your component:
Vue.component('stuff', {
mixins: [buttonAwareMixin],
template: `<div><v-btn v-if="showButton"></v-btn></div>`
})
Well, Alternate is to use $root in Vue. Define foo at your vue instance and it will be available in all the component with this.$root.foo.
Here is the official docs
Hope this helps
The only easiest solution is Vue.prototype.$window = window; in main.js from folder src and use can use window as $window inside your template. Hope can help you all.
I solved it by replacing the 'vue.js' with 'vue.min.js'! I don't know why.
I'm trying to use the <component> element to dynamically display a chosen component. Each of these displayed components can take one of any number of data objects. Something like:
<div id="containers">
<component v-bind:is="currentView"></component>
</div>
var myVue = new Vue({
el:"#containers",
data:{
currentView: "my-component-one",
currentData: {...}
},
method: {
changeView: function(){
//change this.currentView
//change this.currentData
}
}
});
However, the Vue documentation says the v-bind:is attribute can be used to pass either a component name or the options object.
It is unclear how I would conditionally get an object of values for that component to use and also conditionally change which component is shown.
I am very green with using Vue (coming fresh off a knockout kick) so perhaps I am simply misunderstanding the intention of the component tag.
you can simply use v-bind
html
<component v-bind:is="currentView" v-bind="data"></component>
script
data()
{
return {
data: {
currentData: "example"
}
}
}
and it will pass currentData down to child. You can also add other properties along with it, including is.
If you need to change the component along with props, then you just change the data property, or whatever you want to call it.
https://codesandbox.io/s/7w81o10mlx
This example might help you understand it. https://jsfiddle.net/jacobgoh101/mLbrj5gd/
For passing Component Name
If the component is global, you can pass the component name to v-bind:is
for e.g.,
Vue.component('test1', {
template: `<div>test1</div>`
})
HTML
<component is="test1"></component>
For passing option
A Vue component is literally just a Javascript object with specific properties
for e.g.,
<component v-bind:is="{
template: `<div>test2</div>`
}"></component>
Basically I want to be able to access some centralized data by setting up a dataBus as a vue instance object, and then access and tweak this data from different components.
I cant seems to access by data from my componenets, even basic string interpolation is not getting rendered to the DOM.
export const dataBus = new Vue({
data: {
numQuotes: 4,
stringVar: 'Hellow There'
}
});
I also tried setting up my data as the return of the function data(). But being as my data bus is an actual vue instance I don't think this is correct. (I could be wrong). Following is the component in which I import my dataBus and try to output my data.
<template>
<div>
<h1>Quotes Added</h1>
<div id="trackerBar">
<div id="trackerBarActual">
<h2>{{numQuotes}}/10</h2>
</div>
</div>
</div>
</template>
<script>
import { dataBus } from '../main.js';
export default{
}
</script>
I am getting the following error: Property or method "numQuotes" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
Am I missing something obvious? Is it even possible to access data this way? Or do I have to access it as a method?
You're missing the part where you assign data to your component. Try
<script>
import { dataBus } from '../main.js';
export default{
data () {
return dataBus.$data
}
}
</script>
You should definitely look into Vuex for state management though.