![](/img/trans.png)
[英]Correct way to pass props to all children through slot-scope in Vue.js
[英]What's the correct way to pass props as initial data in Vue.js 2?
所以我想將道具傳遞給 Vue 組件,但我希望這些道具將來會從該組件內部更改,例如當我使用 AJAX 從內部更新該 Vue 組件時。 所以它們僅用於組件的初始化。
我的cars-list
Vue 組件元素,我將具有初始屬性的道具傳遞給single-car
:
// cars-list.vue
<script>
export default {
data: function() {
return {
cars: [
{
color: 'red',
maxSpeed: 200,
},
{
color: 'blue',
maxSpeed: 195,
},
]
}
},
}
</script>
<template>
<div>
<template v-for="car in cars">
<single-car :initial-properties="car"></single-car>
</template>
</div>
</template>
我現在這樣做的方式是,在我single-car
組件中,我在created()
初始化掛鈎this.initialProperties
分配給我的this.data.properties
。 它有效並且是反應性的。
// single-car.vue
<script>
export default {
data: function() {
return {
properties: {},
}
},
created: function(){
this.data.properties = this.initialProperties;
},
}
</script>
<template>
<div>Car is in {{properties.color}} and has a max speed of {{properties.maxSpeed}}</div>
</template>
但我的問題是我不知道這是否是正確的方法? 這不會給我帶來一些麻煩嗎? 或者有更好的方法嗎?
感謝這個https://github.com/vuejs/vuejs.org/pull/567我現在知道答案了。
將初始道具直接傳遞給數據。 就像更新文檔中的示例一樣:
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
但請記住,如果傳遞的 prop 是在父組件狀態中使用的對象或數組,則對該 prop 的任何修改都將導致該父組件狀態的更改。
警告:不推薦使用此方法。 它會讓你的組件變得不可預測。 如果您需要從子組件設置父數據,請使用 Vuex 之類的狀態管理或使用“v-model”。 https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components
如果您的初始道具是一個對象或數組,並且您不希望子狀態的更改傳播到父狀態,那么只需使用例如Vue.util.extend
[1] 來制作道具的副本,而不是將其直接指向子數據, 像這樣:
props: ['initialCounter'],
data: function () {
return {
counter: Vue.util.extend({}, this.initialCounter)
}
}
您還可以使用擴展運算符來克隆道具。 Igor 答案中的更多詳細信息: https ://stackoverflow.com/a/51911118/3143704
但請記住,舊瀏覽器不支持傳播運算符,為了更好的兼容性,您需要轉換代碼,例如使用babel
。
[1] 請記住,這是一個內部 Vue 實用程序,它可能會隨着新版本而改變。 您可能想使用其他方法來復制該道具,請參閱“https://stackoverflow.com/questions/728360/how-do-i-correctly-clone-a-javascript-object”。
我在哪里測試它的小提琴: https ://jsfiddle.net/sm4kx7p9/3/
伴隨@dominik-serafin 的回答:
如果您要傳遞一個對象,您可以使用擴展運算符(ES6 語法)輕松克隆它:
props: {
record: {
type: Object,
required: true
}
},
data () { // opt. 1
return {
recordLocal: {...this.record}
}
},
computed: { // opt. 2
recordLocal () {
return {...this.record}
}
},
但最重要的是要記住使用 opt。 2 如果您傳遞的是計算值,或者超過異步值。 否則本地值不會更新。
演示:
Vue.component('card', { template: '#app2', props: { test1: null, test2: null }, data () { // opt. 1 return { test1AsData: {...this.test1} } }, computed: { // opt. 2 test2AsComputed () { return {...this.test2} } } }) new Vue({ el: "#app1", data () { return { test1: {1: 'will not update'}, test2: {2: 'will update after 1 second'} } }, mounted () { setTimeout(() => { this.test1 = {1: 'updated!'} this.test2 = {2: 'updated!'} }, 1000) } })
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> <div id="app1"> <card :test1="test1" :test2="test2"></card> </div> <template id="app2"> <div> test1 as data: {{test1AsData}} <hr /> test2 as computed: {{test2AsComputed}} </div> </template>
我相信您做對了,因為這是文檔中所述的內容。
定義一個使用 prop 的初始值作為其初始值的本地數據屬性
我第二次或第三次遇到這個問題,回到一個舊的 vue 項目。
不知道為什么它在 vue 中如此復雜,但我們可以通過watch完成:
export default {
props: ["username"],
data () {
return {
usernameForLabel: "",
}
},
watch: {
username: {
immediate: true,
handler (newVal, oldVal) {
this.usernameForLabel = newVal;
}
},
},
就像另一種方法一樣,我通過子組件中的觀察者來做到這一點。
這種方式很有用,特別是當你傳遞一個異步值,並且在你的子組件中你想將傳遞的值綁定到 v-model 時。
此外,為了使其具有反應性,我在另一個觀察者中將本地值發送給父級。
例子:
data() {
return {
properties: {},
};
},
props: {
initial-properties: {
type: Object,
default: {},
},
},
watch: {
initial-properties: function(newVal) {
this.properties = {...newVal};
},
properties: function(newVal) {
this.$emit('propertiesUpdated', newVal);
},
},
這樣我就有了更多的控制權和更少的意外行為。 例如,當父級傳遞的 props 是異步的時,它可能在創建或掛載生命周期時不可用。 所以你可以像@Igor-Parra 提到的那樣使用計算屬性,或者觀察道具然后發出它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.