当前位置:   article > 正文

Vue2/3如何强制重新渲染整个页面

Vue2/3如何强制重新渲染整个页面

前言

VoerkaI18n是一个非常优秀的前端多语言解决方案库,提供初始化、提取文本、自动翻译、编译、自动补丁等工具链支持。

在开发@voerkai18n/vue2@voerkai18n/vue两个针对Vue2/3的适配场景时,需要在切换语言时强制重新刷新整个页面,但是无论是Vue2还是Vue3均没有提供官方API,需要用点小技巧,以下是经验总结。

注意: 是重新渲染整个页面,而不是reload整个页面

Vue2

  • 第1版的@voerkai18n/vue2

首先在Vue2组件实例上发现一个未公开的forceUpdateAPI,从字面意思上看,就是强制更新的意思,实际测试也的确可以调用forceUpdate实现强制重新渲染组件。

这下好了,只需要遍历一个组件树,分别调用每个组件实例的forceUpdate就可以实现整个页面的强制重新渲染了。
但是官方也没有一个API可以遍历组件树的方法,所以只能是自己通过分析组件树结构来进行遍历,实际也是可行的。

至第一版的@voerkai18n/vue2就出炉了。

但是由于用的是未公开的API,心里总不点忐忑不安。果然,没多久就有用户反馈forceUpdate在开发模式下有效,但是在构建后就无效了。

  • 第2版的@voerkai18n/vue2

接下来就开始探索新的强制重新渲染方案,再镒重新拜官网文档,发现一个底层API observable,该API是用来创建一个响应式可观察对象的,结合Vue的工作机制,这有了一个方案。

  • 创建一个observable用来保存当前活动语言
  • 让翻译函数t依赖该observable

如此,当切换语言时,就可以让所有使用t函数的组件自动重新渲染。

代码如下:

export const i18nPlugin = {
        install:function (Vue:any, options:VoerkaI18nVue2Options) { 
            const { i18nScope } = Object.assign({},options)
            if(!i18nScope){
                throw new Error('Parameter<i18nScope> is required for VoerkaI18n Vue2 Plugin')
            }        
            const state = Vue.observable({ langauge : i18nScope.activeLanguage })
            Vue.prototype.t = (message:string,...args:any[])=>{
                state.langauge 
                return i18nScope.t(message,...args)
            }         
            Vue.prototype.getActiveLanguage =()=> {
                return state.langauge 
            }
            i18nScope.on("change",(language:string)=>{
                state.langauge = language
            })
        }
    } 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

以上开发了一个Vue2组件,为每一个组件提供一个t函数,重点在于state.langauge这句代表了其依赖了state.langauge这个可观察对象。

实测,第2版本的@voerkai18n/vue2可以实现当切换语言时,所有使用到t函数的组件均会重新渲染。

Vue3

Vue3中同样也是没有官方的强制重新渲染整个页面的API,但是在Vue3的响应式API更新完善,实现的思路大体相同。

  • 第1步:创建一个ref对象用来保存当前语言
  let activeLanguage = ref(i18nScope.global.activeLanguage)        
  • 1
  • **第3步:创建全局计算属性$activeLanguage
        app.mixin({
            computed:{
                $activeLanguage:{
                    get: ():string =>activeLanguage.value,
                    set: (value:string) =>{                        i18nScope.change(value).then((newLanguage:string)=>activeLanguage.value=newLanguage)
                    }
                }        
            }
        }) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • **第3步:创建全局可用的t函数,在组件模块中可以直接使用
        app.config.globalProperties.t = function(message:string,...args:any[]){
            // 通过访问计算属性activeLanguage来实现当activeLanguage变更时的重新渲染
            this.$activeLanguage
            return i18nScope.t(message,...args)
        } 
  • 1
  • 2
  • 3
  • 4
  • 5

重点在于t函数里面用到了this.$activeLanguage。这样,当计算属性$activeLanguage变化时,就触发组件的重新渲染。

小结

  • 利用Vue2/3响应式系统API来保存当前语言
  • 让翻译函数t依赖响应式变量

完整代码可以参见:

@voerkai18n/vue
@voerkai18n/vue2

开源推荐

以下是我的一大波开源项目推荐:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/215850
推荐阅读
相关标签
  

闽ICP备14008679号