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

开源推荐

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

相关推荐
小小小小宇10 分钟前
前端XSS和CSRF以及CSP
前端
UFIT13 分钟前
NoSQL之redis哨兵
java·前端·算法
超级土豆粉20 分钟前
CSS3 的特性
前端·css·css3
星辰引路-Lefan21 分钟前
深入理解React Hooks的原理与实践
前端·javascript·react.js
wyn2000112832 分钟前
JavaWeb的一些基础技术
前端
Hygge-star1 小时前
Flask音频处理:构建高效的Web音频应用指南
前端·flask·音视频·pygame·csdn开发云
江城开朗的豌豆1 小时前
JavaScript篇:回调地狱退散!6年老前端教你写出优雅异步代码
前端·javascript·面试
飞鸟malred1 小时前
vite+tailwind封装组件库
前端·react.js·npm
TE-茶叶蛋1 小时前
Vue Fragment vs React Fragment
javascript·vue.js·react.js
Angindem1 小时前
从零搭建uniapp项目
前端·vue.js·uni-app