当Vuejs中的props值更改时,DOM不会更新

时间:2018-04-26 05:50:39

标签: vue.js vuejs2 vue-component

我有父母和孩子。在父母我传递3个变量作为道具给孩子。在Child中,我使用 watch()来查找可变更改。当第一次创建子项时,监视按预期工作,但是当更新道具中的数据时,子项的DOM不会更新。正在寻找变量数据变化的监视功能根本没有运行。

这是我的代码。它有点冗长所以请耐心等待。

Parentcomponent.vue

 <template>
 <div>


 <button type="button" v-on:click="LoadCatalog()">Click me!! </button>

 <div v-if="displayCategoryList" class="row">
    <h3>Select Category Men</h3>
    <select v-model="menCategory" v-on:change="passDataToChild()">
        <option v-for="item in categoriesfordisplay.men"  v-bind:key="item">
            {{ item }}
        </option>
    </select> 
    <h3>Select Category Women</h3>
    <select v-model="WomenCategory" v-on:change="passDataToChild()">
        <option v-for="item in categoriesfordisplay.women" v-bind:key="item">
            {{ item }}
        </option>
    </select> 
 </div>

 <div v-if="displayData" class="row">

        <div v-for="item in data_to_show_on_mainpage"  v-bind:key="item" >
            <button v-on:click="newfunction(item.cat,item.gender)" >
                <img v-bind:src="item.data.image"> </img>
                <p >{{ item.cat }}</p>
            </button>
         </div>



 </div>

 <category-items v-if="displayCategoryData" v-bind:gender="gender" v-bind:catsgory="catsgory" v-bind:catlog="catlog" ></category-items>





 </div>
 </template>


<script>
  import axios from 'axios'
  import CategoryItems from './CategoryItems'
   export default {
   name:  'GetCategoryItemsAndDisplayOne',
   props: ['categoriesfordisplay','ismainpage', 'catalogselected'],

components:{
    CategoryItems,
    },
    data(){
    return {
        IsMainPage_1 : "",
        data_to_show_on_mainpage : [],
        cat :[],
        displayData : true,
        menCategory : "",
        WomenCategory : "",
        displayCategoryList: true,
        displayCategoryData : false,
        CategoryFromImage : "",
        //dataSentToChild : {}
        gender : "",
        catsgory : "",
        catlog : ""


    }
  },
     methods:{
    passDataToChild(){
        if(this.menCategory != ""){

            this.catsgory = this.menCategory
            this.gender = "men"
            this.catlog = this.catalogselected
            this.menCategory = "" 

        }else if(this.WomenCategory != ""){
            this.catsgory = this.WomenCategory
            this.gender = "women"
            this.catlog = this.catalogselected
            this.WomenCategory = ""
        } 
        this.displayData = false
        this.displayCategoryData = true
    },
    changevalue(){
        this.data_to_show_on_mainpage = []
    },
    CatlogService(catlog_name,category,gender,mainpage){


        let url = "http://localhost:5000/xyz/" + (this.catalogselected).replace(/'/g,"%27") +"/api/"+ (gender) + "/catalogvis/" + (category) +"/items"

        axios.get(encodeURI(url)).then((resp)=>{
            var jsonData = {"data": resp.data.response.Results.results[0] , "cat": category , "gender" : gender}
            )
            this.data_to_show_on_mainpage.push(jsonData)

        })
        .catch(err => {
            console.log("we got an error the url is " + url)
            console.log(err);
        })
    },

    GetItemsToShowonMainPage(){
        this.changevalue()


        if(this.categoriesfordisplay.men_for_display.length>0){
            for(let i =0;i<this.categoriesfordisplay.men_for_display.length;i++){
                let category = this.categoriesfordisplay.men_for_display[i].replace(/"/g,"%27");
                console.log(category)
                this.CatlogService(this.catalogselected,category,'men',this.ismainpage)
            }

        }
        if(this.categoriesfordisplay.women_for_display.length>0){

            for(let i = 0;i<this.categoriesfordisplay.women_for_display.length;i++){
                let category = this.categoriesfordisplay.women_for_display[i].replace(/"/g,"");

                this.CatlogService(this.catalogselected,category,'women',this.ismainpage)
            }

        }
    },
    LoadCatalog(){
        this.displayCategoryData = false
        this.GetItemsToShowonMainPage()
        this.displayData = true
        this.displayCategoryList = true

    },
    newfunction(Cats,gender){
        this.displayCategoryData = true
        this.displayData = false
        this.catsgory = Cats
        this.gender = gender
        this.catlog = this.catalogselected
    }



},
created(){

    this.GetItemsToShowonMainPage()
}



}
</script>

<style>

</style>

子组件CategoryItems.vue 位于

之下
<template>

<div>
    <h4>{{ genders }}</h4>
    <h4>{{ category }}</h4>
    <h4>{{ catalogue }}</h4>
</div>
</template>


<script>


export default{
name : 'CategoryItems',
props : ['gender','catsgory','catlog'],



data(){
    return {
        genders : "",
        category : "",
        catalogue : "",

    }
},
watch : {
    category : function(){

        this.GetProducts()
    }
},
methods:{
    GetProducts(){
    this.genders = this.gender
    this.category = this.catsgory
    this.catalogue = this.catlog

    }
},
created(){
    this.genders = this.gender
    this.category = this.catsgory
    this.catalogue = this.catlog


 }

 }
 </script>


 <style>
 </style>

正如您可以看到,当孩子中的 类别 变量发生变化时, GetProducts 应该会运行,但它不会发生。 它仅在创建子组件时执行。

我的逻辑出错了。 谢谢

2 个答案:

答案 0 :(得分:2)

您只在created挂钩中设置子组件的变量,因此它们不是被动的。

最好的方法是根据道具创建一个基于该属性的computed property反应数据:

computed: {
  category: function() {
    return this.catsgory;
  },
},

每当道具改变时,此计算将自动更新。

您也可以直接观看道具,并强制观察者立即触发(请查看the API)。

您孩子组件的观察者将如下所示:

watch : {
  category: {
    handler: function() {
        this.GetProducts();
    },
    immediate: true,
  },
},

答案 1 :(得分:0)

在我的情况下,如果初始道具值(数组)为undefind,即使道具发生变化,渲染也不会触发。

因此我将初始props值更改为空数组[]

然后问题解决了。