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

前言

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

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

你可以想到的可能是重新刷新整个页面,但是我们要的重新渲染而不是重新reload,两者区别挺大的,此时需要用点小技巧,以下是经验总结。

Vue2

  • 第1版的@voerkai18n/vue2

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

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

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

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

  • 第2版的@voerkai18n/vue2

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

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

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

代码如下:

ts 复制代码
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
            })
        }
    } 

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

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

Vue3

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

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

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

小结

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

完整代码可以参见:

@voerkai18n/vue @voerkai18n/vue2

开源推荐

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

相关推荐
geovindu3 小时前
css: Timeline scribble
前端·css·iphone
沙漠之主11 小时前
C++编程教学设计资料:从入门到实战的完整课程方案
java·前端·c++
hasty11 小时前
不上传新包,也能改变用户拿到的版本:npm dist-tag 的 OIDC 权限治理
前端·npm·node.js
Csvn12 小时前
diff 算法(虚拟 DOM Reconciliation)
前端
前端snow13 小时前
ai agent --- 文件存储
前端
Frag0ut13 小时前
Chrome四大版本获取及共存指南:Stable/Beta/Dev/Canary
前端·chrome·浏览器·dev·beta·canary·共存版
IT_陈寒14 小时前
SpringBoot自动配置坑了我一把,原来是这样绕过去的
前端·人工智能·后端
广州华水科技14 小时前
单北斗GNSS变形监测在大坝安全监测中的应用与优势
前端
zeng不错15 小时前
B站 173 个投稿活动看到眼瞎?我写了个扩展,主打一个精准打击
前端
Latchh15 小时前
前端导出的JPEG红字发糊,质量要拉到100才清楚
前端·图像处理·人工智能·计算机视觉