Lets say my application is a cut-down spreadsheet built in Vue. The key components are TableCollection
, Table
, Row
and Field
. The TableCollection
has an array with multiple Table
objects. Each Table
has an array with multiple Row
objects. Each Row
has an array with multiple Field
objects.
When using the row component in the table template I could bind a single row property (:row="row"
), or I could bind a separate property for each column (:col1="col1" :col2="col2" :col3="col3"
). Which is the preferred approach, and why?
Passing a single property is less verbose, but referring to it from within the row component is more verbose, so they (roughly) cancel each other out. One advantage of the single property is that I could then add a Field dynamically by pushing to the array.
Are there other factors to consider? For example, does it affect the getters and setters generated by Vue?
After re-reading the documentation and doing some tests, I found that there is an important difference between passing the props as an object versus object properties.
This page makes is clear that either is OK, https://vuejs.org/v2/guide/components-props.html#Passing-an-Object
If you pass the object however, then any changes you make in the component will be reflected in the parent too. This makes sense, per the comment at the bottom of this section, https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow
It reads:
Note that objects and arrays in JavaScript are passed by reference, so if the prop is an array or object, mutating the object or array itself inside the child component will affect parent state.
To prove this, you put the following code in a html page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue Test</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
Vue.component('propTest', {
props : ['scalar', 'object', 'other'],
template: `<div>Scalar is <input type="text" v-model="scalar"><br>
Object field 1 is <input type="text" v-model="object.field1"><br>
Object field 2 is <input type="text" v-model="other"></div>`
});
var app = new Vue({
el: '#app',
data: {
scalarVal : 'SCALAR',
objectVal : {
field1 : 'FIELD ONE',
field2 : 'FIELD TWO'
}
},
template : '<div><prop-test :scalar="scalarVal" :object="objectVal" :other="objectVal.field2"></prop-test></div>'
})
</script>
</body>
</html>
As you can see, it three props are passed to the child: a scalar value, an object, and an object property which is a scalar value. They all have two-way bindings in the child per v-model.
Update the three values on the web page then check your Vue dev tools to see that:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With