搜尋

首頁  >  問答  >  主體

Vue 2 - 關於改變 props 的警告

我開始了 https://laracasts.com/series/learning-vue-step-by-step 系列。我因以下錯誤而停止了Vue、Laravel 和 AJAX 課程:

vue.js:2574 [Vue warn]:避免直接改變 prop,因為只要父元件重新渲染,該值就會被覆寫。相反,根據 prop 的值使用資料或計算屬性。正在改變的道具:「list」(在組件中找到)

我在main.js中有這段程式碼

Vue.component('task', {
    template: '#task-template',
    props: ['list'],
    created() {
        this.list = JSON.parse(this.list);
    }
});
new Vue({
    el: '.container'
})

我知道當我覆寫 list 屬性時,問題出在 created() 中,但我是 Vue 的新手,所以我完全不知道如何解決它。有誰知道如何(並請解釋原因)修復它?

P粉818306280P粉818306280415 天前627

全部回覆(2)我來回復

  • P粉715274052

    P粉7152740522023-10-14 09:15:14

    Vue 模式是 props 向下,events 向上。聽起來很簡單,但在編寫自訂元件時很容易忘記。

    從 Vue 2.2.0 開始,您可以使用 v -model(帶有計算屬性)。我發現這種組合在組件之間創建了一個簡單、乾淨且一致的介面:

    • 傳遞給元件的任何 props 都會保持回應狀態(即,它不會被克隆,也不需要 watch 函數在偵測到變更時更新本機副本)。 < /里>
    • 變更會自動傳送給父級。
    • 可與多個層級的元件一起使用。

    計算屬性允許單獨定義 setter 和 getter。這允許 Task 元件重寫如下:

    Vue.component('Task', {
        template: '#task-template',
        props: ['list'],
        model: {
            prop: 'list',
            event: 'listchange'
        },
        computed: {
            listLocal: {
                get: function() {
                    return this.list
                },
                set: function(value) {
                    this.$emit('listchange', value)
                }
            }
        }
    })

    model 屬性定義關聯的 propv-model,以及變更時將發出哪個事件。然後,您可以從父元件呼叫此元件,如下所示:

    <Task v-model="parentList"></Task>

    listLocal 計算屬性在元件內提供了一個簡單的 getter 和 setter 介面(將其視為私有變數)。在#task-template 中,您可以渲染listLocal 並且它將保持反應性(即,如果parentList 更改,它將更新Task< /代码> 元件)。您也可以透過呼叫 setter(例如 this.listLocal = newList)來變更 listLocal,它會將變更傳送給父級。

    此模式的優點在於,您可以將listLocal 傳遞給Task 的子元件(使用v-model),並進行變更來自子元件的內容將傳播到頂級組件。

    例如,假設我們有一個單獨的 EditTask 元件,用於對任務資料進行某種類型的修改。透過使用相同的 v-model 和計算屬性模式,我們可以將 listLocal 傳遞給元件(使用 v-model):

    <script type="text/x-template" id="task-template">
        <div>
            <EditTask v-model="listLocal"></EditTask>
        </div>
    </script>

    如果EditTask發出更改,它將適當地呼叫listLocal上的set(),從而將事件傳播到頂層。同樣,EditTask 元件也可以使用 v-model 呼叫其他子元件(例如表單元素)。

    回覆
    0
  • P粉268654873

    P粉2686548732023-10-14 00:33:06

    這與以下事實有關:在本地改變 prop 是被認為是 Vue 2 中的反模式

    如果您想要在本機上改變prop,您現在應該做的是在data 中宣告一個使用props 的欄位code> value 作為其初始值,然後變更副本:

    Vue.component('task', {
        template: '#task-template',
        props: ['list'],
        data: function () {
            return {
                mutableList: JSON.parse(this.list);
            }
        }
    });

    您可以在 Vue 上閱讀更多相關資訊.js官方指南


    註1:請注意您不應該propdata,即:

    data: function () { return { list: JSON.parse(this.list) } } // WRONG!!

    註2:我覺得關於propsreactivity 存在一些混亂,我建議您看看線程

    回覆
    0
  • 取消回覆