Sadly I'm not that familiar with Vue and hope someone can help me a bit...
I have this in my index.html:
<xyz :isHidden="hidden">...</xyz>
Now, I have my xyz component:
Vue.component('graph', {
props: ['isHidden'],
watch: {
isHidden() {
doSomething(this.isHidden);
}, ...
}
....
}
Then, I have my Vue app:
let app = new Vue({
el: '#root',
methods: {
action() {
this.hidden = !this.hidden;
}, ...
}, ....
data: { hidden: false }
})
Now, as I understand the :hidden="isHidden" part should bind the two variable in the different part together, right? So when I change isHidden it should also change hidden and therefore call the watched function which does something. But as it turns out it doesn't.. already when my component is loaded hidden is undefined..
Did I forget something? Or is my mistake probably in the part "..." part of my code? .-.
Oh, wait.. now I feel stupid....
Well, anyone else struggling: no big letters (camelCase) in Vue-HTML..
fixed HTML:
<xyz :is-hidden="hidden">...</xyz>
the rest can stay the same..
data section should be a function:
data () {
return {
isHidden: false
}
}
you forget use components prop and tag name and component name is should be same
new Vue({
el: '#app',
components: {
'xyz': xyz,
}
})
component name
Vue.component('xyz', {
props: ['hidden'],
watch: {
hidden() {
doSomething(this.hidden);
}, ...
}
....
}
this link should help you: https://v2.vuejs.org/v2/guide/components-registration.html
Related
I'm just playing around with some component instance rendering within a Vue application and I was wondering, when pushing components to an array - how do we then access the data() from that given instance of the component?
So say I have something like this in App.vue (the "Grandfather" of all of my components). I have managed to push instances of both the CodeBlock and QuoteBlock components to the pageBlocks array (i.e., my front end app appends the component where I want it to be). Here is a snippet of my App.vue file:
components: {
CodeBlock,
QuoteBlock
},
data () {
return {
pageBlocks: []
}
},
methods: {
addPageBlock (componentNomen) {
this.pageBlocks.push({ componentName: componentNomen })
},
saveDraftPage () {
for (let pageBlock of this.pageBlocks) {
console.log(pageBlock.data)
}
}
}
And here is an example of my CodeBlock data (the Quote block is "modelled" almost like for like except for a few variable name changes to distinguish it inside the component):
export default {
name: 'CodeBlock',
props: [ 'type' ],
computed: {},
data () {
return {
debug: true,
codeBlock: null,
codeBlockRows: [{
'id': 1,
'text': '$ click to edit this code block'
}],
}
},
}
I've stripped out most of this component to keep things simple.
So, my question is, if the pageBlocks array in App.vue contains instances of the above exported component...how do I access the data within?
In my naiavity I thought it would be as simple as something like this:
for (let pageBlock of this.pageBlocks) {
console.log(pageBlock.data);
}
But, alas, no luck yet...any tips?
I am using this library: https://github.com/cristijora/vue-notifyjs
The documentation on the above page states: component: { //is rendered instead of notification message thus I am trying to give it dynamic component so I can handle custom events. This is my code:
Vue.use(vueNotifyjs)
new Vue({
el: '#app',
methods: {
addNotification(verticalAlign = 'top', horizontalAlign = 'right') {
this.$notify({
component: function(){
return {
template: '<h1>Hello</h1>'
};
},
horizontalAlign: horizontalAlign,
verticalAlign: verticalAlign,
type: "success"
})
}
}
})
This is my jsfiddle: https://jsfiddle.net/z11fe07p/2706/
But the word Hello is not getting rendered in the notify. Any ideas what am I missing?
I think the component key should be have an instance of Vue Component.
In your scenario, create a vue component as follows
Vue.component('custom-message',{
template:`<div>Hello World</div>`
})
I have modified the fiddle with the above in this link.
Hope it helps
someone to help me with this strange issue?
I have the following vue component:
<template lang="pug">
div
p.alert.alert-info {{value}}
button(#click="onChange") Change
</template>
<script>
import Vue from 'vue';
export default {
name: 'z-temp',
props: {
value: {
required: true
}
},
watch: {
value(val) {
console.log(val);
}
},
methods: {
onChange() {
this.$emit('input', Random.id());
}
}
};
</script>
I want to use v-model, but when I use <z-temp v-model="myDataField">, the myDataField changes with success when I click in the Change button, but when I make the inverse and put some value in myDataField, like myDataField: "foo" the custom component gets this.value as undefined instead as foo.
Can anyone help me please?
I am guessing that myDataField is not reactive so the problem is in the parent.
Can you clarify the problem, seems like it is working as it should, ie. the component does not seem to be the problem.
zTemp = Vue.component('ztemp', {
template: '#ztemp',
props: {
value: {
required: true
}
},
watch: {
value(val) {
console.log(val);
}
},
methods: {
onChange() {
this.$emit('input', Math.random());
}
}
});
new Vue({
el: '#app',
components: {
zTemp
},
data: {
myinput: '0.2'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
{{myinput}}<br/>
<input v-model="myinput"/><br/>
<ztemp v-model="myinput"/><br/>
</div>
<script type="text/x-template" id="ztemp">
<div>
<p>{{value}}</p>
<button #click="onChange">Change</button>
</div>
</script>
thanks for helping, but I'm using meteor with vue-meteor, the problem was related to vue-meteor.
I changed the project structure to use separated Vue project in a .client folder and the problem gones. It was not a problema with component, but with vue-meteor package. Anyway, thank you guys.
In my template I have one click event
<span v-on:click="showGalery()">
And I am using one method for it
export default {
name: 'osaka',
data: function () {
return {
galery: false,
}
},
methods: {
showGalery () {
this.galery = true
}
}
}
Is it possible to trigger this method from App.vue template where is my nav and router links is located?
I am using vue-webpack template.
I have components, router.js, App.js and main.js structure.
Remember Vue has a one way data flow, so if you want to set something on the component you can simply pass a prop and use a watcher to trigger the change:
Vue.component('gallery', {
template: `<div v-show="gallery">Gallery</div>`,
props: {
show: {
type: Boolean,
default: false
}
},
created() {
this.gallery = this.show;
},
watch: {
show(val) {
this.gallery = val;
}
},
data() {
return {
gallery: false
}
}
});
Then in the parent you would have:
new Vue({
el: '#app',
data: {
showGallery: false
}
});
And use the following markup:
<gallery :show="showGallery"></gallery>
See this JSFiddle: https://jsfiddle.net/yx1uq370/
Incidentally, if you just want to show hide the entire component, then you can just use v-show on the component itself which
Vue.component('gallery', {
template: `<div>Gallery</div>`
});
new Vue({
el: '#app',
data: {
showGallery: false
}
});
Then your markup:
<gallery v-show="showGallery"></gallery>
And here's the fiddle for that: https://jsfiddle.net/gfr9kmub/
One final thing, are you sure that you really need to trigger this from your nav? I would assume that your nav would display the views and the views themselves would take care of this type of state management. Otherwise you may want to look at vuex to handle this situation
I'm trying to create a Quill.js editor instance once component is loaded using mounted() hook. However, I need to set the Quill's content using Quill.setContents() on the same mounted() hook with the data I received from vuex.store.state .
My trouble here is that the component returns empty value for the state data whenever I try to access it, irrespective of being on mounted() or created() hooks. I have tried with getters and computed properties too. Nothing seems to work.
I have included my entry.js file, concatenated all the components to make things simpler for you to help me.
Vue.component('test', {
template:
`
<div>
<ul>
<li v-for="note in this.$store.state.notes">
{{ note.title }}
</li>
</ul>
{{ localnote }}
<div id="testDiv"></div>
</div>
`,
props: ['localnote'],
data() {
return {
localScopeNote: this.localnote,
}
},
created() {
this.$store.dispatch('fetchNotes')
},
mounted() {
// Dispatch action from store
var quill = new Quill('#testDiv', {
theme: 'snow'
});
// quill.setContents(JSON.parse(this.localnote.body));
},
methods: {
setLocalCurrentNote(note) {
console.log(note.title)
return this.note = note;
}
}
});
const store = new Vuex.Store({
state: {
message: "",
notes: [],
currentNote: {}
},
mutations: {
setNotes(state,data) {
state.notes = data;
// state.currentNote = state.notes[1];
},
setCurrentNote(state,note) {
state.currentNote = note;
}
},
actions: {
fetchNotes(context) {
axios.get('http://localhost/centaur/public/api/notes?notebook_id=1')
.then( function(res) {
context.commit('setNotes', res.data);
context.commit('setCurrentNote', res.data[0]);
});
}
},
getters: {
getCurrentNote(state) {
return state.currentNote;
}
}
});
const app = new Vue({
store
}).$mount('#app');
And here is the index.html file where I'm rendering the component:
<div id="app">
<h1>Test</h1>
<test :localnote="$store.state.currentNote"></test>
</div>
Btw, I have tried the props option as last resort. However, it didn't help me in anyway. Sorry if this question is too long. Thank you for taking your time to read this. Have a nice day ;)
I copied your code and tested it ( of-course I created my own dummy notes so I could remove the get request ) and I was able to get the notes display on a page.
A couple of things that I realized from your code, you may need to add a store property as there are places in your component ( test ) where you are referencing it, yet you only define it on the 'app' component. So in this section of your code modify as shown below:
props: ['localnote'],
data() {
return {
localScopeNote: this.localnote,
store : store
}
},
The key difference is the definition of the 'store' property. Please note that, what you have done, defining a "store" property in your app component, is correct, but the very same needs to be defined in "test" component as I have shown in the above code snippet above.
Second thing is, you are using $store and I guess that gives you undefined, unless as you said, in the libraries that you included this resolves accordingly, but on my side I had to remove all references of "$store" and replace it with just "store" (without the dollar sign).
Lastly for testing purposes, I would advise you to also