簡體   English   中英

Vue 子道具不會在父項中的綁定值更改時更新

[英]Vue child prop is not updated on bound value change in parent

我正在使用 vue-property-decorator lib。 我有 2 個組件: parentchildchild是一個具有 prop 'modalHeader'的組件:

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component({
    name: "modal"
})
export default class Modal extends Vue {
    @Prop({default: "Header"}) public modalHeader!: string;
}
</script>

子組件的模板:

 <template> <div class="modal fade" id="detailsModal" tabindex="-1" role="dialog" aria-labelledby="detailsModalLabel" aria-hidden="true" > <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="detailsModalLabel"> {{ modalHeader }} </h5> </div> ... </div> </div> </div> </div> </template>

我的組件中有一個屬性“buttonPressed” ,我想將其屬性綁定到子道具,因此每次根據按下的按鈕,我都會獲得不同的模態標題:

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import Modal from '../modal/Modal.vue';

interface ControlButtonSetting {
    id: string,
    name: string,
    enabled: boolean,
    isDanger: boolean,
    okText?: string,
    componentType?: IModalComponent,
}

@Component({
    name: "admin-dashboards-page",
    components: {
        "modal": Modal
    }
})
export default class AdminDashboardsPage extends Vue {

    private buttonsArray: ControlButtonSetting[] = [
        { id: "removeButton", name: "Remove", enabled: false, isDanger: true, okText: "Remove" }
    ];

    public buttonPressed!: ControlButtonSetting;

    private showModal = false;

    created(): void {
        this.buttonPressed = this.buttonsArray[0];
    }

    public controlButtonClicked(button: ControlButtonSetting): void {
        this.buttonPressed = button;
        this.showModal = true;
    }
}
</script>

父組件的模板:

 <template> <div> ... <!-- Modal --> <modal :modal-header.sync="buttonPressed.name" <template v-slot:modalBody> <component :is="displayComponent()" :dashboard-id="selectedListItemId"> </component> </template> </modal> </div> </template>

但是, 'modalHeader'值僅在頁面加載時設置一次,但是當'selectedButton'對象更改時,子組件上的'modalHeader'值不會更新。

幫助我的是將對象定義為Prop()

@Prop() public buttonPressed!: ControlButtonSetting;

這樣,每當更新組件的 prop時,子組件的 prop就會更新。 但是我開始在控制台中看到此消息:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "buttonPressed"

我不確定這里有什么問題。 你能幫我嗎?

PS 我的一個猜測是我沒有改變 parent 中的綁定屬性,而是用新對象替換它,這就是父子綁定可能不起作用的原因。 要去檢查一下

簡而言之:您的buttonPressed數據不是反應性的,因為它沒有被初始化。 Vue 必須正確初始化它才能將其標記為響應式。

public buttonPressed!: ControlButtonSetting; // not initialised

您有兩個選項可以正確初始化它:

#1 在聲明后直接給它一個適當的默認值,甚至是空的。

public buttonPressed: ControlButtonSetting = {
  id: "",
  name: "",
  enabled: false,
  isDanger: false,
  okText: ""
}

#2 如果你想讓它的默認值依賴於其他數據/道具,使用data工廠。 (不要為此使用created鈎子)

public buttonPressed!: ControlButtonSetting; // use !: to tell typescript it's declared but in another place

// Even using `vue-property-decorator`, this will work and merge both data() and class properties
data () {
  return {
     buttonPressed: this.buttonsArray[0],
  }
}

不要將buttonPressed標記為道具,因為它不是。 並且 Vue 道具不能從孩子那里更新,它會破壞父母的反應性。


注意:Vue props 應該總是提供一個類型。 即使使用vue-property-decorator ,您也必須指定它。

@Prop({ type: String, default: 'Header' }) <- Vue prop type, only for runtime
readonly modalHeader!: string // <- typescript type, only for build time

(我建議你使用readonly關鍵字告訴 Typescript 這個屬性不能更新,因為在 Vue 中 props 是不可變的)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM