// directives/vT.js import { watch } from 'vue' import { lang } from '@/composables/config' /** * 解析绑定值 * 支持:'key' 或 ['key', param] */ 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 } } /** * 获取全局 i18n 实例 */ 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 // 无 key 时显示 -- if (!key) { updateElementText(el, '') return } let text = '' if (i18n) { const translated = i18n.global.t(key, param) // 如果翻译结果等于 key 本身,说明未找到翻译,显示 -- text = translated === key ? '' : translated } else { text = '' } 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 } }