link2055 link2056 link2057 link2058 link2059 link2060 link2061 link2062 link2063 link2064 link2065 link2066 link2067 link2068 link2069 link2070 link2071 link2072 link2073 link2074 link2075 link2076 link2077 link2078 link2079 link2080 link2081 link2082 link2083 link2084 link2085 link2086 link2087 link2088 link2089 link2090 link2091 link2092 link2093 link2094 link2095 link2096 link2097 link2098 link2099 link2100 link2101 link2102 link2103 link2104 link2105 link2106 link2107 link2108 link2109 link2110 link2111 link2112 link2113 link2114 link2115 link2116 link2117 link2118 link2119 link2120 link2121 link2122 link2123 link2124 link2125 link2126 link2127 link2128 link2129 link2130 link2131 link2132 link2133 link2134 link2135 link2136 link2137 link2138 link2139 link2140 link2141 link2142 link2143 link2144 link2145 link2146 link2147 link2148 link2149 link2150 link2151 link2152 link2153 link2154 link2155 link2156 link2157 link2158 link2159 link2160 link2161 link2162 link2163 link2164 link2165 link2166 link2167 link2168 link2169 link2170 link2171 link2172 link2173 link2174 link2175 link2176 link2177 link2178 link2179 link2180 link2181 link2182 link2183 link2184 link2185 link2186 link2187 link2188 link2189 link2190 link2191

[Vue.js] Accessing props in child vue component data function?

there is the below child component. The props are updated from an input selector in the parent. Why does level: this.globalForm.level not update the child’s level

Parent:

<template>
<div>
<div class=”form-container”>
<select class=”form-control” v-model=”level”>
<option v-for=”level in options” v-bind:key=”level”>{ level }</option>
</select>
<button @click=”submit()”>Create</button>
</div>
<child v-bind:globalForm=”globalForm”/>
</div>
</template>

<script>
inputFiled;
export default {
data() {
return {
level: “”,
globalForm: {
level: “”
},
options: [“level1”, “level2”, “level3”]
};
},
components: {
child
},
methods: {
submit() {
this.globalForm.level = this.level;
}
},
watch: {
level() {
this.globalForm.level = this.level;
}
}
};
</script>

Child:

<template>
<div class=”form-container”>
<option v-for=”level in options” v-bind:key=”level”>{ level }</option>
</div>
</template>

<script>
export default {
props: { globalForm: Object },
data() {
return {
options: [“level1”,”level2”,”level3”,],
level: this.globalForm.level //this does not update the child’s level component
};
}
};
</script>

Solution :

TLDR

level should be a computed property on the child so that you can detect changes in the prop. You are setting level in the data function, so updates to the prop never make it to level.

Below you’ll find a minimal example on what I think you want to achieve.

Vue.config.productionTip = false;
Vue.component(‘parent’, {
template: `
<div class=”parent”>
<b>PARENT</b>
<div class=”form-container”>
<select class=”form-control” v-model=”level”>
<option v-for=”level in options” v-bind:key=”level”>{ level }</option>
</select>
<button @click=”submit()”>Create</button>
</div>
<child v-bind:globalForm=”globalForm”/>
</div>
`,
data: () => ({
level: “”,
globalForm: {
level: “”
},
options: [“level1”, “level2”, “level3”]
}),
methods: {
submit() {
this.globalForm.level = this.level;
}
}
});

Vue.component(‘child’, {
template: `
<div class=”form-container child”>
<p><b>Child</b></p>
Level: { level }
</div>
`,
props: {
globalForm: Object
},
computed: {
level() {
return this.globalForm.level;
}
}
});

new Vue({
el: “#app”
})
.parent {
background-color: darkgray;
padding: .5em;
border: solid 1px black;
}
.child {
background-color: lightgray;
padding: .5em;
border: solid 1px black;
}
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”app”>
<parent></parent>
</div>

More Detailed explanation

There are couple of errors on the code that I’ll go through.

In the child component

When initializing the component, this is not available inside the data function, so this.globalForm will be undefined. An error is thrown in the console when reproducing it.

data() {
return {
options: [“level1”,”level2”,”level3”,], // this looks like duplicated code from the parent
level: this.globalForm.level // throws error
};
}

To fix that error, you can get the vm context from the parameters of data But this is not the solution for the question.

data(vm) { // note vm
return {
level: vm.globalForm.level // note vm
};
}

The real problem is that level: this.globalForm.level runs only once, in the component initialization, so level is undefined. When the globalForm prop changes, level has already been initialized and it will not change (data returns a new object so the reference to the prop is lost).

You want convert level to be a computed property so that changes to the prop can be detected and the inner value returned. See code snippet above.