zhb 2 tháng trước cách đây
mục cha
commit
2ee93ce873
2 tập tin đã thay đổi với 87 bổ sung28 xóa
  1. 71 0
      directives/v-t.js
  2. 16 28
      main.js

+ 71 - 0
directives/v-t.js

@@ -0,0 +1,71 @@
+import { watch } from 'vue'
+import { lang } from '@/composables/config'
+
+const parseBinding = (val) => {
+  if (Array.isArray(val)) {
+    const [key, ...rest] = val
+    if (rest.length === 0) return { key, param: undefined }
+    if (rest.length === 1) return { key, param: rest[0] }
+    return { key, param: rest }
+  }
+  return { key: val, param: undefined }
+}
+
+const updateElementText = (el, text) => {
+  if (!el) return
+  if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {
+    el.value = text
+  } else if ('textContent' in el) {
+    el.textContent = text
+  } else if ('innerText' in el) {
+    el.innerText = text
+  }
+}
+
+const getI18n = () => {
+  return typeof globalThis !== 'undefined' && globalThis.__i18n ? globalThis.__i18n : null
+}
+
+export default {
+  mounted(el, binding) {
+    const setState = (val) => {
+      const { key, param } = parseBinding(val)
+      el._vTKey = key
+      el._vTParam = param
+    }
+    const update = () => {
+      const i18n = getI18n()
+      const key = el._vTKey
+      const param = el._vTParam
+      if (!key) return
+      const text = i18n ? i18n.global.t(key, param) : String(key)
+      updateElementText(el, text)
+    }
+    setState(binding.value)
+    update()
+    el._vTSetState = setState
+    el._vTUpdate = update
+
+    el._vTStopWatch = watch(() => lang.value, () => {
+      const i18n = getI18n()
+      if (i18n?.global?.locale?.value !== undefined) {
+        i18n.global.locale.value = lang.value
+      }
+      update()
+    }, { immediate: false, flush: 'sync' })
+  },
+  updated(el, binding) {
+    if (el._vTSetState) el._vTSetState(binding.value)
+    if (el._vTUpdate) el._vTUpdate()
+  },
+  unmounted(el) {
+    if (el._vTStopWatch) {
+      el._vTStopWatch()
+      delete el._vTStopWatch
+    }
+    if (el._vTUpdate) delete el._vTUpdate
+    if (el._vTSetState) delete el._vTSetState
+    if (el._vTKey) delete el._vTKey
+    if (el._vTParam) delete el._vTParam
+  }
+}

+ 16 - 28
main.js

@@ -7,47 +7,35 @@ import { interpolateTemplate } from "./locale/utils";
 import vEllipsis from './directives/v-ellipsis'
 import { createI18n } from "vue-i18n";
 import { routeInterceptor } from '@/utils/routeInterceptor.js'
+import { lang } from '@/composables/config'
+import { watch } from "vue";
+import vT from './directives/v-t'
 export const i18n = createI18n({
   legacy: false,
   allowComposition: true,
-  locale: uni.getStorageSync("lang") || "cn",
+  locale: lang.value || "cn",
   messages,
 });
+globalThis.__i18n = i18n
 const pinia = createPinia();
 
-const originalT = i18n.global.t;
-i18n.global.t = function (key, param1, param2) {
-  const result = originalT.call(this, key, param1, param2);
-  if (param1 === undefined && param2 === undefined) {
-    return result;
-  }
-  let values = param1;
-  if (
-    typeof param1 === "object" &&
-    !Array.isArray(param1) &&
-    Array.isArray(param2)
-  ) {
-    values = param1;
-  } else if (Array.isArray(param1)) {
-    values = param1;
-  } else if (typeof param1 === "object" && param1 !== null) {
-    values = param1;
-  } else if (param1 !== undefined) {
-    values = [param1];
-  }
-  return interpolateTemplate(result, values);
-};
 // #ifdef VUE3
 import { createSSRApp } from "vue";
 export function createApp() {
   const app = createSSRApp(App);
-  app.directive('ellipsis', vEllipsis)
+  app.directive('ellipsis', vEllipsis);
   app.use(uviewPlus);
   app.use(pinia);
   app.use(i18n);
-  routeInterceptor.install()
-  return {
-    app,
-  };
+  app.directive('t', vT);
+  // 保持 locale 与存储 lang 同步(可选)
+  watch(() => lang.value, (val) => {
+    if (!val) return;
+    if (i18n?.global?.locale?.value !== undefined) {
+      i18n.global.locale.value = val;
+    }
+  }, { immediate: true, flush: 'sync' });
+  routeInterceptor.install();
+  return { app };
 }
 // #endif