Unable to pass data to vue template - javascript

I am trying to pass the name from data to my settingTemplate.
However, I have not been able to make it work. Could anyone advice how I should approach this? I am new to Vue.
app.js
var app = new Vue({
el: '#app',
components: {
settingTemplate
},
data: {
name: 'Elon'
}
})
setting-template.js
const settingTemplate = {
template:
`<div class="d-flex flex-column text-md-center">
<div class="p-2">
<b-btn id="popoverButton-disable" variant="primary"></b-btn>
</div>
<div class="p-2">
<b-popover :disabled.sync="disabled" target="popoverButton-disable" title="{{name}}">
<a>Profile</a> | <a>Logout</a>
</b-popover>
</div>
</div>`
,
data() {
return {
disabled: false
}
},
methods: {
disableByRef() {
if (this.disabled){
this.$refs.popover.$emit('enable')
}else{
this.$refs.popover.$emit('disable')
}
}
},
props: ['name']
}

You should pass name to your component by attribute, not by data:
<div id="app">
<setting-template name="Elon" />
</div>
Here you can check working example:
https://codepen.io/anon/pen/dwrOqY?editors=1111
data is component private data - it's not passed to child components.
If you still need name in your main component data you can pass it to the child component like this:
<div id="app">
<setting-template :name="name" />
</div>
var app = new Vue({
el: '#app',
components: {
settingTemplate
},
data: {
name: 'Leon'
}
})
https://codepen.io/anon/pen/qLvqeO?editors=1111

Related

Vue bind child component data from parent

I need to bind my child component data (inputData) from parent component but it's not working i cannot find where is my mistake
app.js
let vm = new Vue({
el: "#app",
components: {
'modal-panel': modal,
'rich-select': richSelect,
'file-upload': uploader,
},
data(){ return {
isModalActive: false,
inputData: null
}} ,
methods: {
toggleModal(){
this.isModalActive = !this.isModalActive
},
modalData(){
this.inputData = 'Example Data'
}
}
});
Modal.vue
<template>
<input type="text" :value="inputData" >
</template>
export default {
name: 'modal',
props: ['inputData'],
mounted(){
console.log('modal Mounted')
}
};
inside my blade i'am calling modal component like this
<div class="container" id="app">
<modal-panel v-if="isModalActive" #close="toggleModal" :inputData="inputData"></modal-panel>
</div>
when i test that code all methods are working but inside Modal.vue input still not binding
You've to use the prop with kebab-case format as follows :
<modal-panel v-if="isModalActive" #close="toggleModal" :input-data="inputData"></modal-panel>

Vue: component failed to update $parent

I want to update $parent data from child component. (I know it's bad but very conv for tightly bound component).
So I'm trying like is shown below, but it update field named 'undefined' instead:
Vue.config.productionTip = false;
const child = {
template: `
<div class="hello">
<input type="text" v-model="$parent.obj[this.field]">
<pre>{{ $props }}</pre>
</div>`,
props: ['field'],
}
new Vue({
el: "#app",
components: {
child,
},
data() {
return {
obj: {
f1: 111,
f2: 222
}
}
},
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<div id="app">
parent:
<pre>{{ $data }}</pre>
<hr>
child:
<child field="f1" />
</div>
You added this keyword to the property of $parent.obj. You don't need to use this keyword in template.
Here is the working code: codesandbox

how to render component from a component in vue js

I have a component with following template:
<div v-for:"item in store" v-bind:key="item.type">
<a>{{item.type}}</a>
</div>
I have another component called 'StoreComponent'
On click of a element in first component I want to clear the current component and show the StoreComponent and able to pass item.type to StoreComponent.
I don't want to use router-link or router.push as I don't want to create a new url but override the current component with the new one depending on the item.type value.
StoreComponent.vue
export default{
name: 'StoreComponent',
props: ['item'],
data: function () {
return {
datum: this.item
}
},
methods: {
//custom methods
}
}
You could use dynamic components and pass the item-type as a prop.
Vue.component('foo', {
name: 'foo',
template: '#foo'
});
Vue.component('bar', {
name: 'bar',
template: '#bar',
props: ['test']
});
new Vue({
el: "#app",
data: {
theComponent: 'foo', // this is the 'name' of the current component
somethingWeWantToPass: {
test: 123 // the prop we are passing
},
},
methods: {
goFoo: function() {
this.theComponent = 'foo';
},
goBar: function() {
this.theComponent = 'bar';
},
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<button #click="goFoo">Foo</button>
<button #click="goBar">Bar</button>
<component :is="theComponent" v-bind="somethingWeWantToPass"></component>
</div>
<template id="foo">
<div>
Foo
</div>
</template>
<template id="bar">
<div>
Bar
<div>This is a prop: {{ this.test }}</div>
</div>
</template>

Cannot render multiple components in Vue

I'm just starting with Vue and I have defined 2 components, however, I cannot render them in the same 'Vue' instance.
Here are my 2 components:
Vue.component('mat-example', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
Next, I do have the 'Vue' entry point defined:
var app = new Vue({
el: '#app'
});
And in my HTML, I do have the following code:
<div id="app">
<button-counter />
<mat-example />
</div>
The 'Vue' development tools does only show the 'button-counter' component:
If I remove the 'button-counter', the 'mat-example' is showed up in the Vue Developer Tools.
How does it come that I cannot render those 2 components in my Vue entry point?
this is going to work:
<div id="app">
<button-counter></button-counter>
<mat-example></mat-example>
</div>
demo:
Vue.component('mat-example', {
data: function() {
return {
count: 0
}
},
template:
'<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
Vue.component('button-counter', {
data: function() {
return {
count: 0
}
},
template:
'<button v-on:click="count++">You clicked me {{ count }} times</button>'
})
var app = new Vue({
el: '#app'
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<button-counter></button-counter>
<mat-example></mat-example>
</div>
Use this tag instead of using self closing tag
<div id="app">
<button-counter></button-counter>
<mat-example></mat-example>
</div>

Is it possible to append a component on a button press?

Here's a problem that I want to solve:
I have a button that when is pressed must append my-component to a dom.
If it is pressed 2 times there must be 2 <p> tegs. How can I achieve this?
js:
<script>
Vue.component('my-component', {
template: "<p>hello</p>",
})
var vue = new Vue({
el: "#App",
data: {},
methods: {
append: function() {
// unknown code here
}
}
})
</script>
html:
<div id = "App">
<button #click="append" class="btn btn-primary">Spawn stuff!</button>
</div>
Here is one way you could do that. This code iterates over a counter using v-for to iterate over a range.
Vue.component('my-component', {
template: "<p>hello</p>",
})
var vue = new Vue({
el: "#App",
data: {
hellocount: 0
},
methods: {
append: function() {
// unknown code here
this.hellocount++
}
}
})
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="App">
<my-component v-for="n in hellocount" :key="n"></my-component>
<button #click="append" class="btn btn-primary">Spawn stuff!</button>
</div>
This is a little atypical; normally you will drive the components rendered from actual data, as #RoyJ suggests in your comments.
From your comment below, you could build a form something like this.
Vue.component('my-input', {
props:["value", "name"],
data(){
return {
internalValue: this.value
}
},
methods:{
onInput(){
this.$emit('input', this.internalValue)
}
},
template: `
<div>
{{name}}:<input type="text" v-model="internalValue" #input="onInput">
</div>
`,
})
var vue = new Vue({
el: "#App",
data: {
form:{
name: null,
email: null,
phone: null
}
},
methods:{
append(){
const el = prompt("What is the name of the new element?")
this.$set(this.form, el, null)
}
}
})
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="App">
<my-input v-for="(value, prop) in form"
:key="prop"
v-model="form[prop]"
:name="prop">
</my-input>
<button #click="append">Add New Form Element</button>
<div>
Form Values: {{form}}
</div>
</div>
The code defines a form object and iterates over the properties of the form to render inputs for each property.
This is obviously extremely naive, handles only input texts, etc. But hopefully you get the idea.

Categories

Resources