Vue.js 2.0 Dynamic Props Docs - vuejs2

js 2.0 and I'm stock in dynamic props.
See Image attached
My HTML code like this:
<div id="app">
<div>
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
</div>
</div>
My Component code:
Vue.component('child', {
props: ['myMessage'],
template: '<p>{{ myMessage }}</p>',
})
var app = new Vue({
el: "#app",
});
I know that data should be a function but how I'm going to implement it. I get this error on the console.
Property or method "parentMsg" is not defined on the instance but referenced during render

I think message is clear. "parentMsg" is not defined on the instance. You have to define parentMsg at parent level. like following:
var app = new Vue({
data: {
"parentMsg": ""
}
el: "#app"
});
You can have a working fiddle here.

Related

VueJs: bind `v-on` on a custom component to replace an existing one

In order to ease the styling of my page, I'd like to create a bunch of mini components like, and exploit how attributes are merged in VueJs. So for example, here is a minimal js file also hosted on this JSFiddle:
Vue.component('my-button', {
template: '<button style="font-size:20pt;"><slot></slot></button>'
})
var app = new Vue({
el: "#app",
data: {
message: "world",
},
methods: {
sayHello: function () {
alert("Hello");
}
}
})
and then in my html I just want to use <my-button> instead of button:
<div id="app">
Hello {{message}} <my-button #click="sayHello" style="color:red;">Style works, but not click</my-button> <button v-on:click="sayHello" style="color:red;">Both works</button>
</div>
Unfortunately, it seems that attributes are merged, but not listeners, so it means that I can't do v-on:click on my new button... Any way to make it possible?
Thanks!
-- EDIT --
I saw the proposition of Boussadjra Brahim of using .native, and it works, but then I found this link that explains why it's not a great practice and how to use v-on="$listeners" to map all listeners to a specific sub-button. However, I tried, to just change my template with:
template: `<button style="font-size:20pt;" v-on="$listeners"><slot></slot></button>`,
but I get an error:
Vue warn: Property or method "$listeners" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option."
Here is the JSFiddle.
Your fiddle didn't work because you were using an old version of Vue, $listeners was added in Vue 2.4.0.
Here's a demo:
Vue.component('my-button', {
template: '<button style="color: red" v-on="$listeners"><slot/></button>'
})
new Vue({
el: '#app',
methods: {
sayHello() {
alert('Hello')
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<my-button #click="sayHello">Custom Button</my-button>
<button #click="sayHello">Ordinary Button</button>
</div>

How to pass data into components in vue.js?

I have this
<template id="vButton">
<button v-bind:title="name">{{name}}</button>
</template>
<div id="app">
<ti-button></ti-button>
</div>
js
Vue.component('ti-button', {
props: ['name'],
template: '#vButton'
});
var vm2 = new Vue({
el: '#app',
data: {
name : 'hi'
}
});
I want the button to have innerText and title attribute to say 'hi'. But it does not. Does anyone know why?
Ref: https://v2.vuejs.org/v2/guide/components.html
Thanks
Vue.component('ti-button', {
props: ['name'],
template: '#vButton'
});
var vm2 = new Vue({
el: '#app',
data: {
name: 'hi'
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<script type="text/x-template" id="vButton">
<div>
<button>{{name}}</button>
<button>{{$root.name}}</button>
</div>
</script>
<div id="app">
<ti-button name="first_button"></ti-button>
</div>
UPD:
Do you mean you don't see this?
You are doing things mostly right, you just need to pass your data to your prop using a v-bind:
<ti-button v-bind:name="name"></ti-button>
Static values can be passed without v-bind but for dynamic values like you are attempting to pass you need to bind the prop. Check out the static/dynamic prop documentation for more information.
And here is a working demo: https://codepen.io/egerrard/pen/qJpzMQ

Why Vue binding does not work in a sample?

Please have a look at example
http://jsfiddle.net/g77uv054/
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.10.5/vue.min.js"></script>
<div id="todo">
<h1>My Test</h1>
Sample 1 <span v-text="form.title"></span>
Sample 2 <b><span v-text="'' +form.title"></span></b>
</div>
<script>
var form = new Vue({
data: {
title: "My Form"
}
});
var app = new Vue({
el: '#todo',
data: {
form : form
}
})
</script>
For some reason, binding in "Sample 1" does not show nothing and Sample 2 works fine. Can someone please explain why adding '' to string makes any difference ?
I don't believe you can use a vue instance inside another vue instance.
Normally you either define form as a component or as a class.
I attached fiddles for the two approaches:
http://jsfiddle.net/DarkFruits/g77uv054/1/
<div id="todo">
<h1>My Test</h1>
Sample 1<span v-text="form.title"></span><br/>
Sample 2<span v-text="'' +form.title"></span>
</div>
class formĀ {
constructor() {
this.title = 'My Form'
}
}
var app = new Vue({
el: '#todo',
data: {
form : new form()
}
})
http://jsfiddle.net/DarkFruits/g77uv054/2/
<template id="my-form">
<span v-text='title'></span>
</template>
<div id="todo">
<h1>My Test</h1>
Sample 1<my-form v-bind:title='title'></my-form><br/>
</div>
Vue.component('my-form', {
template: '#my-form',
props: ['title']
})
var app = new Vue({
el: '#todo',
data: {
title : 'My Form'
}
})
Edit:
FYI, in the second fiddle I removed vue as an external resource and added it in the javascript settings. This also gives you better error messages in the console.

How can i bind input to object in vue.js

Is there a way to bind input to objects instead of single variables.
I know we can do this simple trick
<input v-model="name">
But the following doesn't work:
<input v-model="user.name">
That's what i was used to in Angular, is there a way to achieve this in vue.js?
you can bind directly to data, code as follow:
var demo = new Vue({
el: "#demo",
data: {
user: {
name: "please enter"
}
}
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="demo">
<input v-model="user.name">
<span>{{user.name}}</span>
</div>
This works in Vue as well, make sure to define complete object in data which will make it reactive, Here is a working fiddle.
Vue Code:
var demo = new Vue({
el: '#demo',
data: function(){
return {
user: {
name: 'This is working fine'
}
};
}
})

How get data from from Vue Template?

I have got next HTML:
<div id="app">
<component :is="currentView"></component>
</div>
Vue code:
var GuestMenu = Vue.extend({
template: `
<input v-model="username">
`});
Vue.component('guestmenu', GuestMenu);
var App = new Vue ({
el: '#app',
// template: '<usermenu></usermenu>',
data:
{
currentView: "guestmenu",
username: ""
}
})
I need to get username from v-model. The problem that all examples show how to get it's directly, but my data placed in template...
http://jsfiddle.net/u9L569ku/
I believe that this is what you want to achieve. Basically, there is a parent-child realtionship in your example but the communication was not set up correctly. The username in your component was not bound to the username in the Vue instance's data.
jsfiddle
html
<div id="app">
<component :username.sync="username" :is="currentView"> </component>
{{username}}
</div>
javascript
var GuestMenu = Vue.extend({
props : ['username'],
template: `<input v-model="username">`
});
Vue.component('guestmenu', GuestMenu);
var App = new Vue ({
el: '#app',
data: {
currentView: "guestmenu",
username: ""
}
})