A solution to update the state by the vuex method in the parent component and not update and render in time by the child component

Scene:

What I actually use is that my parent component references the child component related, The parent component calls the method to get the page details, and updates the state value related. The child component renders the relevant news content according to the related value. However, when the page is opened, the child component always loads the child component first. The child component does not get the updated related value when rendering. Even if the value of watch changes in the child component, it still cannot render the relevant news content of the child component .

My solution:

The parent component transfers values like the child component. When the parent component executes the method of obtaining page details, the state value is updated, and then it is transferred to the child component. The child component renders again, and it can be acquired normally.

Parent component code:

<template>
  <div id="newsDetails">
    <mt-header title="details">
      <router-link to="/" slot="left">
        <mt-button icon="back"></mt-button>
      </router-link>
    </mt-header>
    <div class="details clearfloat">
      <h1 class="titleFont">
        {{ title }}
      </h1>
      <div class="clearfloat sourceWrap">
        <ul class="sourceFont">
          <li v-if="(pubNews==true)">
            <span class="source">{{pubName}}</span>
          </li>
          <li>
            <span class="authorName">{{authorName}}</span>
            <span class="time">{{createAt|formatTime}}</span>
          </li>
        </ul>
        <span  v-if="(pubNews==true)" class='btnFollow' @click="follow">follow</span>
      </div>
      <div class="bodyFont clearfloat" id="bodyFont" ref="bodyFont" :class="{bodyHeight:contentStatus}">
        <div v-html="content"></div>
        <div class="editor" v-if="editorName">Editor in charge:{{editorName}}</div>
      </div>
      <div class="contentToggle" @click="contentStatus=!contentStatus" v-if="contentStatus">Read the whole passage</div>
      <Related :related="related"></Related>
    <!--The point is that the parent component transfers values to the child component-->
 </div> </div> </template>
import { Toast } from 'mint-ui';
  import {mapState} from 'vuex'
  import Related from './Related.vue'
  import moment from 'moment';
  export default{
    name:"NewsDetails",
    components:{
      Related,
    },
    data(){
      return {
        id:this.$route.params.id,
        topicType:"news",
        contentStatus:false,
        curHeight:0,
        bodyHeight:5000,
        hotCommentScrollTop:0
      }
    },
    created(){
      this.id=this.$route.params.id;
      this.fetchData();
      moment.locale('zh-cn');
    },
    mounted(){
      setTimeout(()=>{
        this.contentToggle();
      },500)
    },
    watch: {
      '$route'(to,from){
        this.id=this.$route.params.id;
        this.fetchData();
      }
    },
    computed: {
      ...mapState({
        title: state => state.newsDetails.title,
        authorName: state => state.newsDetails.authorName,
        pubNews: state => state.newsDetails.pubNews,
        pubName: state => state.newsDetails.pubName,
        editorName: state => state.newsDetails.editorName,
        createAt: state => state.newsDetails.createAt,
        content: state => state.newsDetails.content,
        myFavourite: state => state.newsDetails.myFavourite,
        related: state => state.newsDetails.related,
      })
    },
    filters:{
      formatTime(time){
        return moment(time).fromNow();
      },
    },
    methods:{
      fetchData(){
        this.$store.dispatch('getDetails',this.id);
      },
      follow(){
        Toast('Follow after login');
        this.$router.push("/login");
      },
      contentToggle(){
        this.curHeight=this.$refs.bodyFont.offsetHeight;
        if(parseFloat(this.curHeight)>parseFloat(this.bodyHeight)){
          this.contentStatus=true;
        }else{
          this.contentStatus=false;
        }
//        this.hotCommentScrollTop=this.$refs.hotComment.height;
        console.log(this.hotCommentScrollTop);
      },
    }
  }

Subcomponent related.vue

<template>
    <div v-if="lists.length>0">
        <div class="tagTitle"><span>Related news</span></div>
        <div class="listItem" v-if="(item.type=='little')" v-for="(item,index) in lists" :to="{name:'details',params:{id:item.id}}" :key="index" @click="browserDetection()">
          <div class="listImg1">
            <!--<img :src="{lazy==loaded?item.thumb[0]:lazy==loading?'../../assets/images/little_loading.png':lazy==error?'../../assets/images/little_loading.png'}" alt="" v-lazy="item.thumb[0]">-->
            <img :src="item.thumb[0]" alt="" v-lazy="item.thumb[0]">
          </div>
          <div class='titleBox1'>
            <p class="listTitle">{{item.title}}</p>
            <div class="titleInfo">
              <span class="openApp">Open the Tang family</span>
              <span v-if="item.top==true" class="toTop">Roof placement</span>
              <!--<svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-dianzan"></use>
              </svg>-->
              <span class="like">Read {{item.read}}</span>
              <span class="time">{{item.createAt|formatTime}}</span>
            </div>
        </div>
      </div>
    </div>
</template>
<script>
  import {mapActions, mapState, mapGetters} from 'vuex'
  import moment from 'moment'
  export default{
    data(){
      return {
        lists: [],
        id:this.$route.params.id,
      }
    },
    props:{
        related:Array   //The point is here
    },
    created(){
      moment.locale('zh-cn');
    },
    /*computed: {
      ...mapState({
        related: state => state.newsDetails.related,
      })
    },*/
    filters:{
      formatTime(time){
        return moment(time).fromNow();
      },
    },
    methods:{
    },
    watch: {
      related (val) {
        this.lists = val;
      },
      '$route'(to,from){
        this.id=this.$route.params.id
      }
    }
  }
</script>

The effect is as follows:

Tags: Javascript Vue

Posted on Mon, 30 Mar 2020 23:04:08 -0700 by dougmcc1