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函数的组件自动重新渲染。

代码如下:

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

开源推荐

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

相关推荐
洛_尘6 小时前
Python 5:使用库
java·前端·python
Bigger6 小时前
Bun 能上生产吗?我的实战结论
前端·node.js·bun
kyriewen8 小时前
你的前端滤镜慢得像PPT?用Rust+WebAssembly,一秒处理4K图
前端·rust·webassembly
kyriewen118 小时前
你等的Babel编译,够喝三杯咖啡了——用Rust重写的SWC,只需眨个眼
开发语言·前端·javascript·后端·性能优化·rust·前端框架
IT_陈寒8 小时前
SpringBoot自动配置坑了我,原来要这样绕过去
前端·人工智能·后端
东方小月8 小时前
Claude Code 完整上手指南:MCP、Skills、第三方模型配置一次搞定
前端·人工智能·后端
XZ探长9 小时前
基于 Trae Solo 移动办公修复 Vue3 前端服务问题
前端
蝎子莱莱爱打怪9 小时前
Claude Code 省 Token 小妙招:RTK + Caveman 组合拳
前端·人工智能·后端
Momo__9 小时前
Vue 3.6 Vapor Mode:跳过虚拟 DOM,性能极致优化
前端·vue.js
少年白马醉春风丶9 小时前
从零构建 AIGC 无限画布:AIGCCanvasFlow 技术全解析
前端·后端·aigc