• 父组件中vuex方法更新state,子组件不能及时更新并渲染的解决方法


    场景:

    我实际用到的是这样的,我父组件引用子组件related,父组件调用获取页面详情的方法,更新了state值related,子组件根据该related来渲染相关新闻内容,但是页面打开的时候总是先加载子组件,子组件在渲染的时候还没有获取到更新之后的related值,即使在子组件中watch该值的变化依然不能渲染出来子组件的相关新闻内容。

    我的解决办法:

    父组件像子组件传值,当父组件执行了获取页面详情的方法之后,state值related更新,然后传给子组件,子组件再进行渲染,可以正常获取到。

    父组件代码:

    <template>
      <div id="newsDetails">
        <mt-header title="详情">
          <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">关注</span>
          </div>
          <div class="bodyFont clearfloat" id="bodyFont" ref="bodyFont" :class="{bodyHeight:contentStatus}">
            <div v-html="content"></div>
            <div class="editor" v-if="editorName">责任编辑:{{editorName}}</div>
          </div>
          <div class="contentToggle" @click="contentStatus=!contentStatus" v-if="contentStatus">阅读全文</div>
          <Related :related="related"></Related>
        <!--重点是这里  父组件向子组件传值-->
     </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('登录后进行关注');
            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);
          },
        }
      }

    子组件related.vue

    <template>
        <div v-if="lists.length>0">
            <div class="tagTitle"><span>相关新闻</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">打开唐人家</span>
                  <span v-if="item.top==true" class="toTop">置顶</span>
                  <!--<svg class="icon" aria-hidden="true">
                    <use xlink:href="#icon-dianzan"></use>
                  </svg>-->
                  <span class="like">阅读 {{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   //重点是这里
        },
        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>

    效果如图:

  • 相关阅读:
    C#各版本新特性
    ubantu操作积累
    C# System.Net.Http.HttpClient使用说明
    IIS下VUE跳转
    融合主流的技术 分布式中间件+微服务+微架构架构
    论减少代码中return语句的骚操作
    shell脚本--多个代码库批量pull最新master代码
    SpringBoot单元测试
    Qt音视频开发36-USB摄像头解码qcamera方案
    Qt音视频开发35-Onvif图片参数
  • 原文地址:https://www.cnblogs.com/beileixinqing/p/8931730.html
Copyright © 2020-2023  润新知