更新website后端
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* {yz:xxx} 站点标签指令(dedecms 风格)
|
||||
*
|
||||
* 用法:在模板里直接写标签,元素加 v-yz 即可
|
||||
* <p v-yz>{yz:icp}</p>
|
||||
* <p v-yz>备案号:{yz:icp} | {yz:policeicp}</p>
|
||||
*
|
||||
* 元素内所有 {yz:标签名} 会被替换为「官网管理 - 站点设置」中对应的值,
|
||||
* 未配置的标签输出空字符串(与后端 themes 模板行为一致)。
|
||||
*
|
||||
* 注意:指令通过 innerHTML 替换内容,因此元素内只能放纯文本/HTML 片段,
|
||||
* 不要放子组件或需要响应式绑定的内容;需要条件渲染的地方请用 siteInfo.xxx。
|
||||
*/
|
||||
import { watchEffect, type Directive } from "vue";
|
||||
import { siteTags } from "@/config/site";
|
||||
|
||||
/** 与后端 tagengine 的全局标签正则保持一致 */
|
||||
const TAG_PATTERN = /\{yz:([a-zA-Z_]\w*)\}/g;
|
||||
|
||||
/** 每个元素对应的 watchEffect 停止函数 */
|
||||
const stops = new WeakMap<HTMLElement, () => void>();
|
||||
|
||||
/** 依据当前标签值渲染元素内容;始终基于首次保存的原文,避免重复替换 */
|
||||
function render(el: HTMLElement): void {
|
||||
if (!el.dataset.yzRaw) {
|
||||
el.dataset.yzRaw = el.innerHTML;
|
||||
}
|
||||
const raw = el.dataset.yzRaw;
|
||||
|
||||
el.innerHTML = raw.replace(
|
||||
TAG_PATTERN,
|
||||
(_match: string, key: string) => siteTags[key] ?? ""
|
||||
);
|
||||
}
|
||||
|
||||
export const yz: Directive<HTMLElement> = {
|
||||
mounted(el) {
|
||||
// watchEffect 会追踪 render 中读取到的标签值;
|
||||
// 站点设置是异步拉取的,数据到位后会自动重新渲染
|
||||
stops.set(el, watchEffect(() => render(el)));
|
||||
},
|
||||
unmounted(el) {
|
||||
stops.get(el)?.();
|
||||
stops.delete(el);
|
||||
},
|
||||
};
|
||||
|
||||
export default yz;
|
||||
Reference in New Issue
Block a user