zoukankan      html  css  js  c++  java
  • vue项目刷新当前页面的几种解决方案对比:如何优雅的强制重新渲染子组件

      一般刷新页面可以用 location.reload(true),history.go(0) 等方法,但是这对vue项目很不友好,会使页面重新加载出现暂时性的空白,而且耗费性能,所以vue项目最好不用这些方法。vue有this.$forceUpdate()可以强制更新,下面介绍其他更好的方法。

    一、带上当前页面路由跳转到一个重定向的页面,重定向页面再跳转回来

    // 1、新建refresh.vue
    <script>
    export default {
      name: "refresh",
      beforeCreate(){
        this.$router.push(this.$route.query.path)
      },
    };
    </script>
    
    // 2、router.js配置一个refresh路由
    import refresh from './components/refresh.vue'
    {
        path: '/refresh',
        name: 'refresh',
        component: refresh
    },
    
    // 3、在要刷新的地方跳转传参即可
    reflesh(){
        this.$router.push({path:'/refresh',query:{path:this.$route.fullPath}})
    },

      有一个问题是点击浏览器返回相当于没点击,因为跳转的是refresh页面,而refresh又会跳回原页面。所以并不合适。

    二、通过 provide 和 inject 结合 v-if 的功能触发页面刷新

      这对选项需要一起使用,以允许一个根组件向其所有子组件注入一个依赖,实现原理就是通过控制router-view 的显示与隐藏,来重渲染路由区域,重而达到页面刷新的效果,show -> false -> show

    1、修改app.vue,利用 v-if 可以刷新页面的属性,同时使用 provide 和 inject 将祖先节点的数据传递给子代节点

    <template>
      <div id="app">
            <router-view v-if="isRouterAlive"></router-view>
      </div>
    </template>
     
    <script>
    export default {
      name: 'App',
      provide (){
         return {
           reload:this.reload
         }
      },
      data(){
        return {
           isRouterAlive:true
        }
      },
      methods:{
        reload (){
           this.isRouterAlive = false
           this.$nextTick(function(){
              this.isRouterAlive = true
           })
        }
      },
      components:{
      }
    }
    </script>

    2、在要刷新的子路由页面引入inject,然后执行reload事件即可刷新页面

        export default {
          name: "demo",
          inject:['reload'],
          data() {
            return {}
          },
          methods: {
            reflesh(){
              this.reload()
            },
          }
        }

    三、使用内置的forceUpdate方法(较好的)

      组件内置$forceUpdate方法,使用前需要在配置中启用

    import Vue from 'vue'
    Vue.forceUpdate()
    
    export default {
      methods: {
        handleUpdateClick() {
          this.$forceUpdate()
        }
      }
    }

      由于一些嵌套特别深的数据,导致数据更新了,但是页面却没有重新渲染。我遇到的一个情况是,v-for遍历数据渲染,当方法中处理相应数组数据时,数组改变了,但是页面却没有重新渲染。

      解决方法:运用 this.$forceUpdate()强制刷新,解决v-for更新数据不重新渲染页面。

      官方解释:迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

    四、使用key-changing优化组件(最好的)

      key-changing的原理很简单,vue使用key标记组件身份,当key改变时就是释放原始组件,重新加载新的组件。

    <template>
        <div>
            <!-- 父组件 -->
            <div>
                <button @click="reLoad">点击重新渲染子组件</button>
            </div>
            <!-- 内容库子组件 -->
            <lib-window :key="time" :channelCode="searchChannelCode"></lib-window>
        </div>
    </template>
     
    <script>
    import children from '@/components/parent/children'
    export default {
        name: 'contentLib',
        components: { libWindow },
        data () {
            return {
                time: ''
            }
        },
        methods: {
            reLoad () {
                this.time = new Date().getTime()
            }
        }
    }
    </script>

      我们通过 :key 实现,当key 值变更时,会自动的重新渲染,key的作用主要是为了高效的更新虚拟DOM。推荐使用这种。

  • 相关阅读:
    什么是结构化数据?什么是半结构化数据?
    安卓图表引擎AChartEngine(一)
    Android中通过pid获取app包名
    Android USER 版本与ENG 版本的差异--MTK官方解释
    Android 各层中日志打印功能的应用
    Android音频系统之AudioFlinger(二)
    Android音频系统之AudioFlinger(一)
    Android音频系统之音频框架
    第1章 音频系统
    Android音频系统之AudioPolicyService
  • 原文地址:https://www.cnblogs.com/goloving/p/13941836.html
Copyright © 2011-2022 走看看