后台管理系统国际化技术方案

286 阅读1分钟

前言

实现类似新增/编辑操作时,切换语言字段时,对应更改表单字段清空,将上一个语言的表单数据暂存,切换回来时可以回显的功能。

通过双向绑定实现对应语言表单回显

 <script setup>
     const formRef = ref(null)
     const searchForm = reactive({
         lang: 'zh',
         // 定义语言类型为对象,key为语言,value为内容对象
         options: {
             'zh': {
                 packageName: null,
                 packageTag: null
             },
             'en': {
                 packageName: null,
                 packageTag: null
             },
             'tc': {
                 packageName: null,
                 packageTag: null
             }
         }
     })
     const rules = reactive({
         lang: [{ required: true, message: '请选择语言', trigger: 'blur' }],
     })
 ​
     // 当前语言
     const currentLang = computed(() => {
         return searchForm.lang
     })
 </script>
 <template>
     <el-form ref="formRef" :model="searchForm" :rules="rules">
         <el-form-item label="语言" prop="lang">
             <MultipleLanguageSelect v-model="searchForm.lang" />    // 封装el-select
         </el-form-item>
         
         <el-form-item 
             label="会员套餐名称:" 
             prop="options['zh'].packageName"
             :rules="{ required: true, message: '请输入会员套餐名称', trigger: 'blur' }"
         >
             <el-input 
                 v-model.trim="searchForm.options[currentLang].packageName" 
                 :disabled="disabled" 
                 placeholder="请输入会员套餐名称" 
                 maxlength="6" 
                 show-word-limit 
             />
         </el-form-item>
     </el-form>
 </template>

表单校验直接通过:rules实现

如果写在script中则会增加麻烦,rules无法穿透第二层对象。因为此处语言的form表单在第二层对象中。

直接写在template解决问题。

 <el-form-item 
     label="会员套餐名称:" 
     prop="options['zh'].packageName"        // 默认校验简体中文
     :rules="{ required: true, message: '请输入会员套餐名称', trigger: 'blur' }"
 >

监听切换语言时,默认语言的必填项是否为空

 <script setup>
 // 监听切换语言时,必填项是否为空
 watch(() => searchForm.lang, () => {
     formRef.value.validate(valid => {
         if (!valid) {
             // 为空时不允许切换语言
             searchForm.lang = 'zh'
         }
     })
 }, { deep: true })    
 </script>

非默认语言disabled属性判断

 <script setup>
 // 当前是否是中文
 const isZh = computed(() => {
     return !(searchForm.lang === 'zh')
 })
 </script>

传参时,后端接收语言数据为数组,需作进一步转换

 // 传参数据处理
 const handlerParams = () => {
     let handleList = []
     // 遍历语言对象返回所需数组
     Object.keys(state.searchForm.options)?.forEach(key => {
         handleList.push({ ...state.searchForm.options[key], language: key })
     })
     const params = { ...state.searchForm, ...state.searchForm.options['CN'] }
     params.list = handleList  // 添加数组进searchFrom
     return params
 }

传参数据格式为

 {
     ...,
     "list": [
         {
             "language":"EN",
             "name":"who",
             ...
         }
     ]
 }

获取数据需将语言数组装换成对象

因为通过对象绑定key值来锁定语言更明了,避免绑定数组index时,如果后期语言顺序出现变化导致BUG。

 // 响应数据处理
 const handleResponse = (res = null) => {
     let localOptions = {}
     if (res && res.list) {
         res.list.forEach(key => {
             localOptions[key.language] = key
         })
     } else {
         localOptions = null
     }
     state.searchForm.options = localOptions || {
         'CN': {
             title: null,
             ...
         },
         'EN': {
             title: null,
             ...
         },
         'TW': {
             title: null,
             ...
         }
     }
 }