[Vue warn]: Avoid mutating a prop directly...

[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.

中文:[Vue 警告⚠️]:避免直接更改屬性,因爲父組件重新呈現時將覆蓋該值相反,使用基於屬性值的數據或計算屬性。

我百度了很多的解決問題的帖子,都是直接貼出來英文的,翻譯一下會死啊,真的是,很多的問題我們都不是說不知道怎麼解決,其實是我們壓根沒看懂描述的是什麼意思,就像這個,看明白描述基本就知道怎麼修改了。我們在接收一個值之前需要使用一個當前頁面下面的data裏面定義的變量接收,這樣可以避免直接更改這個值。
我們寫個例子:

<template>
  <div class="back" v-on:click="back">
    <img src=".././common/imgs/fanhui.png" alt="">
    <span>返回</span><span>{{'剩餘'+overwrite_seconds_timeout+'秒'}}</span>
  </div>
</template>

<script>
  export default {
    name: "return",
    data() {
      return {
        time: '',
        overwrite_seconds_timeout: this.seconds_timeout
      }
    },
    props: {
      seconds_timeout: 0
    },
    /**
     * @created 頁面加載的時候進行頁面自減函數的間隔執行操作
     */
    created: function () {
      let that = this;
      that.time = setInterval(that.remain_sec, 1000)
    },
    methods: {
      /**
       * @remain_sec 進行秒數自減的操作
       */
      remain_sec() {
        let that = this;
        if (that.overwrite_seconds_timeout === 1) {
          that.$router.push({path: '/'});
        } else {
          that.overwrite_seconds_timeout--;
        }
      },
      /**
       * 這裏是返回,直接調用自定義組件的返回,自定義邏輯
       */
      back() {
        if (this.back) {
          this.$emit("comBack")
        }
      }
    },
    /**
     * @beforeDestroy  頁面銷燬前,將Interval清除
     */
    destroyed: function () {
      let that = this;
      clearInterval(that.time);
    }
  }
</script>

<style lang="less" scoped>
  .back {
    float: left;
    img {
      width: 43px;
      height: 34px;
      margin-left: 40px;
      float: left;
    }
    span {
      height: 25px;
      font-size: 26px;
      font-family: PingFangSC-Regular;
      font-weight: 400;
      color: rgba(255, 255, 255, 1);
      line-height: 40px;
      float: left;
      margin-left: 8px;
    }
  }

這是一個組件,倒計時就返回的組件,常用的場景是一個頁面進來以後我們提示用戶還有多少秒就會返回上一個界面,很常見的一個組件,那麼這裏就有一個需要接收父組件的值seconds_timeout,這個值我們在頁面是怎麼使用的呢?

  • 在main.js裏面將組件引入:
//將返回的組件引入
import back from "./components/back"

Vue.component("back-view",back)
<back-view @comBack="comBack()" :seconds_timeout="120"></back-view>

我們引用的時候直接將需要的值給,也就是120秒以後會返回,那麼這個時候我們如果直接在組件中接收seconds_timeout,會直接警告,就是我們今天的問題,怎麼解決呢?上面的例子在data裏面定義了一個新的值就是爲了解決這個問題。

  • 衍生知識
    我們在寫組件的時候,其實很多的時候我們是直接在組件中將一個功能直接實現的,其實我們大部分的組件都是可以自定義的,而不是一個固定死的一段代碼。怎麼說呢?就像我們這個組件,如果我們直接寫成60秒以後返回是不是可以的,當然是可以的,直接使用data定義一個60秒的倒計時,但是有一個問題就是很多的場景其實是根據實際情況來的,具體需要的時間或者說秒數是根據場景來的。那麼這個時候需要我們在定義一個組件的時候可以靈活一點,比如我們寫的這個頁面是120秒。還有一個就是我們說的函數,這個返回的組件可以做的事情其實是很多的,返回的哪一個頁面,很多人說肯定是上一個界面啊,很多的時候是不會直接到上一個界面的,所以我們需要自定義到哪一個頁面,那麼這個時候我們需要的是根據自己需要返回或者返回的時候需要清理一下什麼操作,那麼我們直接這樣寫就可以。
     /**
       * 這裏是返回,直接調用自定義組件的返回,自定義邏輯
       */
      back() {
        if (this.back) {
          this.$emit("comBack")
        }
      }

使用方式:

//這裏寫自己需要的一些處理邏輯
comBack() {
        this.$router.go(-1);
      }

到這裏一個組件的基本使用就可以了,有些人會問爲什麼標題不寫成組件的基本使用而是一個問題呢?其實我們自己在寫代碼的時候會發現很多時候我們學習一個東西不是因爲我們想學習,而是我們遇到了一個問題,不好解決的時候,我們會找到一些解決的方案,這個解決的問題的過程其實就是一種學習的過程,所以我習慣性的根據一個問題來引申出來一些存在的知識點,這樣做的好處是第一我們可以直接看到活生生的例子,第二是我們可以直接看到解決的思路,對我們解決的別的問題其實也是很有幫助的,最後就是一般有例子的時候才更有說服力,不然空談一些什麼東西是沒有任何意義的。喜歡的可以關注一下,一起交流學習進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章