I'm currently working with VueJS 2, I would like to pass some params from the HTML to the VueJS component. Let me show you.
My Html Div looks like this :
<div id="app" :id="1"></div>
And my javascript :
new Vue({
store, // inject store to all children
el: '#app',
render: h => h(App)
});
My App Component:
<template>
<div>
{{ id }}
</div>
</template>
<script>
export default {
props: {
id: Number
}
}
</script>
I would like to get the id passed in the Html, in my App component.
How should I do ?
Here is one way.
<div id="app" data-initial-value="125"></div>
new Vue({
el: '#app',
render: h => h(App, {
props:{
id: document.querySelector("#app").dataset.initialValue
}
})
})
But you don't have to use a render function.
new Vue({
el: '#app',
template:"<app :id='id'></app>",
data:{
id: document.querySelector("#app").dataset.initialValue
},
components:{
App
}
})
Also, I'm using querySelector assuming you rendered initialValue (instead of id) to the page as an attribute, but you could just as easily put it somewhere else on the page like a hidden input or something. Really doesn't matter.
Related
I want to pass a value from my web component to the vue instance, I want to use it rails html.erb file,
Here is the element I am mounting the vue instance on:
<div id="app" :purchaseId="1">
pass it to a vue instance but it does not seem to work, the vue instance is declared in main.js like this:
export default new Vue({
store,
vuetify,
render: h => h(App),
data: {
purchaseId: null
},
methods: {
setJson(payload) {
console.log("payload", payload);
this.purchaseId = payload;
}
}
}).$mount("#app");
After this I want to pass to it's child component, can anyone tell me how can I do that
I see that you should bind that attribute to the method instead of data property and pass the data coming from rails as parameter :
1st solution:
<div id="app" :purchaseId="setJson(1)">
or
<div id="app" :purchaseId="setJson(<%= purchaseId %>)">
export default new Vue({
store,
vuetify,
render: h => h(App),
data: {
purchaseId: null
},
methods: {
setJson(payload) {
console.log("payload", payload);
this.purchaseId = payload;
}
}
}).$mount("#app");
2nd solution :
Try to use pure js to get that value by using $refs and getAttribute method:
<div id="app" ref="app" purchaseId="<%= purchaseId %>">
export default new Vue({
store,
vuetify,
render: h => h(App),
data: {
purchaseId: null
},
methods: {
setJson(payload) {
console.log("payload", payload);
this.purchaseId = payload;
}
},
mounted(){
let payload=this.$refs.app.getAttribute('purchaseId');
this.purchaseId = payload;
}
}).$mount("#app");
Using Vuu.js, I'm trying to pass a value from parent to child component. I have this working fine with a provided example. But when I change the name, it stops working. I can't figure out what i'm doing wrong. My understanding on props is limited, i'm still trying to get me head around it.
Working Example:
https://codepen.io/sdras/pen/788a6a21e95589098af070c321214b78
HTML
<div id="app">
<child :text="message"></child>
</div>
JS
Vue.component('child', {
props: ['text'],
template: `<div>{{ text }}</div>`
});
new Vue({
el: "#app",
data() {
return {
message: 'hello mr. magoo'
}
}
});
Non Working Example:
HTML
<div id="app">
<child :myVarName="message"></child>
</div>
JS
Vue.component('child', {
props: ['myVarName'],
template: `<div>{{ myVarName }}</div>`
});
new Vue({
el: "#app",
data() {
return {
message: 'hello mr. magoo'
}
}
});
In your parent template
<div id="app">
<child :myVarName="message"></child>
</div>
replace
<child :myVarName="message"></child>
with
<child :my-var-name="message"></child>
Additionally you can refer this to get insights of casing.
Leave everything as is in your updated example EXCEPT in the HTML change "myVarName" to "my-var-name" - this is done by default by Vue and within the js you can use the camelCased version myVarName still.
I am recently learning Vue and I have read documentation about Vue components. However, I still do not understand how I can pass data object to props and have it rendered in the component template.
Here is my jsfiddle link
Or see my code below.
Vue.component('greeting', {
template: `<h1>{{index}}</h1>`,
props: ['persons']
});
var vm = new Vue({
el: '#app',
data: {
persons: {
'Mike': 'Software Developer',
'Nikita': 'Administrator Assistant'
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<greeting v-bind:persons="persons" v-for="(value,key,index) in persons"></greeting>
</div>
A few things:
The template only has access to the props listed, not stuff from the parent scope which is why index is not available
You would bind :person="value" since that is the variable that is populated with the current iterated item of persons
Add another prop, 'role', so that you can bind the key of the person Object to it
See below:
Vue.component('greeting', {
template: "<h1>{{person}} is a {{role}}</h1>",
props: ['person', 'role']
});
var vm = new Vue({
el: '#app',
data: {
persons: {
'Mike': 'Software Developer',
'Nikita': 'Administrator Assistant'
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.min.js"></script>
<div id="app">
<greeting :person="value" :role="key" v-for="(value, key, index) in persons" :key="index"></greeting>
</div>
I'm learning Vue.js for my game and I was wondering if there is a way to dynamically add and remove components in Vue.js ?
Here's my current code
var vue = new Vue({
el: "#fui",
template: ``
})
const HelloCtor = Vue.extend({
props: ['text'],
template: '<div class="hello">{{ text }}</div>',
});
const vm = new HelloCtor({
data: {
text: 'HI :)'
}
});
/*
How can I do something like this?
vue.add(vm);
vue.remove(vm);
*/
The code basically speaks for himself
So, is it possible (and how?) to dynamically add and remove Vue.js components to a Vue?
You need a place to put vm in the template. Then you can $mount the component manually to an element with vm.$mount('el'). You can also delete the element with vm.$destroy(true). Destroy won't delete the element from the DOM. You'll need to do that manually with something like (vm.$el).remove()
I'm not 100% this is what you're looking for, and when you find yourself manually calling $destroy() you are probably not doing things right…but it does let you take control of the creating and destruction of components.
Something like this will let you create then destroy your component (note in this case once you destroy vm it's gone):
<div id="fui">
<button #click="make">Make</button>
<button #click="bye">destroy</button>
<div id="mountme"></div>
</div>
<script>
const HelloCtor = Vue.extend({
props: ['text'],
template: '<div class="hello">This has been {{ text }}</div>',
})
const vm = new HelloCtor ({
data: {
text: "Mounted"
}
})
var vue = new Vue({
el: "#fui",
template: ``,
methods: {
make: () => {
vm.$mount('#mountme')
},
bye: () => {
vm.$destroy(true);
(vm.$el).remove();}
}
})
</script>
Sup people!
I got this HTML code here:
// index.html
<div data-init="component-one">
<...>
<div data-init="component-two">
<button #click="doSomething($event)">
</div>
</div>
This basically references a Vue instance inside another Vue instance if I understood everything correctly. The respective JS code is split up in two files and looks like this:
// componentOne.js
new Vue(
el: '[data-init="component-one"]',
data: {...},
methods: {...}
);
// componentTwo.js
new Vue(
el: '[data-init="component-two"]'
data: {...}
methods: {
doSomething: function(event) {...}
}
);
Now, the problem with this is, that doSomething from componentTwo never gets called.
But when I do some inline stuff, like {{ 3 + 3 }}, it gets computed like it should. So Vue knows there is something. And it also removes the #click element on page load.
I tried fiddling around with inline-template as well, but it doesn't really work as I'd expect it to in this situation. And I figured it isn't meant for this case anyway, so I dropped it again.
What would the correct approach be here? And how can I make this work the easiest way possible with how it's set up right now?
The Vue version we use is 2.1.8.
Cheers!
The problem is that you have two vue instances nested to each other.
If the elements are nested, then you should use the same instance or try components
https://jsfiddle.net/p16y2g16/1/
// componentTwo.js
var item = Vue.component('item',({
name:'item',
template:'<button #click="doSomething($event)">{{ message2 }</button>',
data: function(){
return{
message2: 'ddddddddddd!'
}},
methods: {
doSomething: function(event) {alert('s')}
}
}));
var app = new Vue({
el: '[data-init="component-one"]',
data: {
message: 'Hello Vue!'
}
});
<div data-init="component-one">
<button >{{ message }}</button>
<item></item>
</div>
Separate instances work if they are independant of each other.
as follows:
https://jsfiddle.net/p16y2g16/
var app = new Vue({
el: '[data-init="component-one"]',
data: {
message: 'Hello Vue!'
}
});
// componentTwo.js
var ddd = new Vue({
el: '[data-init="component-two"]',
data: {
message: 'ddddddddddd!'
},
methods: {
doSomething: function(event) {alert('s')}
}
});
But when I do some inline stuff, like {{ 3 + 3 }}, it gets computed like it should. So Vue knows there is something.
Because you have parent instance 'componentOne'. It activated Vue for this template. If you need to set another instance inside, you have to separate part of template. Example (it can lag in snippet!) .
Alternative
https://jsfiddle.net/qh8a8ebg/2/
// componentOne.js
new Vue({
el: '[data-init="component-one"]',
data: {
text: 'first'
},
methods: {}
});
// componentTwo.js
new Vue({
el: '[data-init="component-two"]',
data: {
text: 'second'
},
template: `<button #click="doSomething($event)">{{text}}</button>`,
methods: {
doSomething: function(event) {
console.log(event);
}
}
});
<script src="https://vuejs.org/js/vue.min.js"></script>
<div data-init="component-one">
{{text}}
</div>
<div data-init="component-two">
</div>
The button element inside component-two is referenced as a slot in Vue.
The evaluation of the #click directive value happens in the parent component (component-one, which host component-two). Therefor, you need to declare the click handler over there (over component-one).
If you want the handler to be handled inside component-two, you should declare a click directive for the slot element in it's (component-two) template, and pass the handler function, for instance, as a pop.
good luck.
You're doing everything right except you've nested the 2nd Vue instance inside the 1st. Just put it to the side and it will work as expected.
Vue ignores binding more than once to the same element to avoid infinite loops, which is the only reason it doesn't work nested.
Use vue-cli to create a webpack starter app. vue init app --webpack
Then, try to structure your components this way. Read more: https://v2.vuejs.org/v2/guide/components.html#What-are-Components
This is main.js
import Vue from 'vue'
import ComponentOne from './ComponentOne.vue'
import ComponentTwo from './ComponentTwo.vue'
new Vue({
el: '#app',
template: '<App/>',
components: {
ComponentOne,
ComponentTwo
}
})
This is ComponentOne.vue
<template>
<div class="user">
<div v-for="user in users">
<p>Username: {{ user.username }}</p>
</div>
</div>
</template>
<script>
export default {
data () {
return {
users: [
{username: 'Bryan'},
{username: 'Gwen'},
{username: 'Gabriel'}
]
}
}
}
</script>
This is ComponentTwo.vue
<template>
<div class="two">
Hello World
</div>
</template>
<script>
export default {
}
</script>
<div th:if="${msg.replyFloor}">
<div class="msg-lists-item-left">
<span class="msg-left-edit"
th:classappend=" ${msg.unreadCount == 0} ? 'msg-all-read' ">您在</span>
<span th:text="${msg.topic.title}"
class="msg-left-edit-res"
th:classappend=" ${msg.unreadCount == 0} ? 'msg-all-read' ">问题回答</span>
<span th:text="${msg.type.name}"
class="msg-left-edit "
th:classappend=" ${msg.unreadCount == 0} ? 'msg-all-read' ">帖子相关</span>
<span class="msg-left-edit-number" >
产生了<span th:text="${msg.unreadCount} ? : ${msg.unreadCount} + '条新' : ${msg.unreadCount} + '条' "
th:class="${msg.unreadCount} ? : 'number-inner':''">2132条</span>回复
</span>
</div>
<div class="msg-lists-item-right">
<span th:text="${msg.lastShowTime}">2017-8-10</span>
</div>
</div>