vue.js2.0中props数据绑定的报错疑问

在使用vue.js2.0做练习的时候,报错(数据是可以正确显示在页面中的):

[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: "products"

home.vue:

这是一个循环列表

<template>
    <div class="weui-panel product-preview-panel"
      v-for="item in shelfList" v-bind:key="item.id">

      <div class="weui-panel__bd">
        <div class="weui-media-box weui-media-box_text">
          <h3 class="weui-media-box__title product-preview-title">
            <span class="text english">{{item.english_name}}</span>
            <span class="text chinese">{{item.name}}</span>
          </h3>
          <div class="product-preview-list">
            
            <products v-bind:shelf-id="item.id"></products>

          </div>
        </div>
      </div>

    </div>
</template>

<script>
  import products from 'components/product-list';
  import api from 'src/pages/api/api-conf.js';

  export default {
    name: 'home',
    components: {
      banner,
      feature,
      shelf,
      products
    },
    data() {
      return {
        shelfList: [],
      }
    },
    created() {
      this.dataInit();
    },
    methods: {
      dataInit() {
        var _this = this;
        // 商品类目
        _this.$http.get(api.getShelf())
        .then((res) => {
          _this.shelfList = res.data.objects;
        });
      }
    }
  }
</script>
    

product-list.vue:

<template>
  <flexbox :gutter="0" wrap="wrap">
    <flexbox-item :span="1/2" v-for="item in products" >
      <div class="product-card">
        <a href="#">
          <div class="product-cover-image" 
          :style="{ backgroundImage: 'url(' + item.cover_image + ')' }"></div>
          <h4 class="product-title">{{item.title}}</h4>
          <p class="vendor-name">{{item.vendor.name}}</p>
          <strong class="price">¥{{item.price}}</strong>
          <span class="original-price">¥{{item.original_price}}</span>
        </a>
      </div>
    </flexbox-item>
  </flexbox>
</template>

<script>
  import { Flexbox, FlexboxItem } from 'vux'

  import api from 'src/pages/api/api-conf.js';

  export default {
    name: 'productList',
    components: {
      Flexbox,
      FlexboxItem
    },
    props: {
      shelfId: {
        type: Number,
        required: !0
      },
      products: {
        type: Array,
        "default": function() {
          return []
        }
      }
    },
    created() {
      this.getProducts();
    },
    methods: {
      getProducts() {
        var _this = this;
        _this.$http.get(api.getProductList(_this.shelfId))
        .then((res) => {
          _this.products = res.data.objects;
        });
      }
    }
  }
</script>

我想清楚这样的 warn 是什么原因造成的,查了下大概说是props使用错误,但还是不明白为什么。

阅读 39.8k
6 个回答

product-list.vue 中的 products 放到 data 中,props 中的属性应该是由父级传入的。

在Vue2中组件的props的数据流动改为了只能单向流动,即只能由组件外(调用组件方)通过组件的DOM属性attribute传递props给组件内,组件内只能被动接收组件外传递过来的数据,并且在组件内,不能修改由外层传来的props数据。

推荐文章:https://www.kysq.com/article/...

# 2个方法

第一个 :

// 父组件
<dialog-apply :visible.sync="dialogApplyVisible" />

// 子组件
<el-dialog
      :visible.sync="visible"
      title="申请"
      :before-close="onClose"
>

onClose() {
  this.$emit('update:visible', false)
}

第二个 :

// 父组件
<dialog-apply :visible.sync="dialogApplyVisible" @close='dialogApplyVisible = false' />

// 子组件
<el-dialog
      :visible.sync="visible"
      title="申请"
      :before-close="onClose"
>

onClose() {
  this.$emit('close')
}

这2个方法 , :before-close 是关键 ;

vue不推荐直接在子组件中修改父组件传来的prop的值,如果要避免这个抛出错误,需要通过事件派发来处理:
父组件
html
<products v-bind:shelf-id="item.id" @updateData="updateData"></products>
js
methods: {
updateData(data) {

this.products = data;

}
}
子组件
js
methods: {
getProducts() {

var _this = this;
_this.$http.get(api.getProductList(_this.shelfId))
.then((res) => {
  this.$emit('updateData', res.data.objects);
});

}
}

product-list.vue中给data定义一个product1

data () {
    return {
        product1: ''
    }
}

watch: {
        products(newVal) {
            this.product1= newVal;
            this.$emit('update:products', newVal);
        }
    },

vue2.3 新增的 https://cn.vuejs.org/v2/guide...

推荐问题
宣传栏