当前位置: 首页 > news >正文

鸿蒙OSUniApp开发支持多语言的国际化组件#三方框架 #Uniapp

使用UniApp开发支持多语言的国际化组件

在全球化的今天,一个优秀的应用往往需要支持多种语言以满足不同地区用户的需求。本文将详细讲解如何在UniApp框架中实现一套完整的国际化解决方案,从而轻松实现多语言切换功能。

前言

去年接手了一个面向国际市场的电商项目,需要支持中文、英文和法文三种语言。项目采用UniApp框架开发,可一开始我们团队在国际化方面遇到了不少问题:业务逻辑与翻译文本耦合度高、切换语言后某些组件不更新、动态内容翻译困难等。

经过多次迭代和重构,我们最终开发出了一套灵活且易用的国际化解决方案。这套方案不仅解决了当前项目的需求,还具有很好的通用性和扩展性。今天就把这些经验分享给大家,希望能给正在做国际化的小伙伴提供一些参考。

技术选型

国际化(i18n)库的选择上,我们对比了几个主流方案:

  1. vue-i18n:Vue生态的标准国际化解决方案
  2. i18next:功能全面但体积较大
  3. 自研轻量级方案:针对UniApp定制开发

考虑到UniApp的跨端特性和性能要求,最终我们选择了vue-i18n(8.x版本),它与Vue深度集成且体积适中,社区支持也比较完善。

基础配置

1. 安装依赖

# 项目根目录执行
npm install vue-i18n@8.27.0

2. 创建多语言文件

我们在项目中创建了专门的语言文件目录结构:

/lang/en.js     # 英文/zh-CN.js  # 简体中文/fr.js     # 法文/index.js  # 统一导出

zh-CN.js为例:

export default {common: {confirm: '确认',cancel: '取消',loading: '加载中...',noData: '暂无数据',},login: {title: '用户登录',username: '用户名',password: '密码',remember: '记住密码',submit: '登录',forgotPassword: '忘记密码?',},// 更多模块...
}

3. 配置i18n实例

lang/index.js中配置i18n:

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import enUS from './en.js'
import zhCN from './zh-CN.js'
import fr from './fr.js'
import { getSystemLanguage } from '@/utils/system'Vue.use(VueI18n)// 获取系统语言或存储的语言设置
const getLanguage = () => {// 优先使用存储的语言设置const localLanguage = uni.getStorageSync('language')if (localLanguage) return localLanguage// 否则获取系统语言const systemLanguage = getSystemLanguage()// 映射系统语言到我们支持的语言const languageMap = {'en': 'en','zh-CN': 'zh-CN','fr': 'fr'}return languageMap[systemLanguage] || 'en' // 默认英文
}const i18n = new VueI18n({locale: getLanguage(),messages: {'en': enUS,'zh-CN': zhCN,'fr': fr},silentTranslationWarn: true, // 禁用翻译警告fallbackLocale: 'en' // 回退语言
})export default i18n

4. 在main.js中挂载i18n

import Vue from 'vue'
import App from './App'
import i18n from './lang'Vue.config.productionTip = false// 挂载i18n实例
Vue.prototype._i18n = i18nconst app = new Vue({i18n,...App
})app.$mount()

封装国际化组件

为了使国际化在整个应用中更加方便使用,我们封装了一个专用组件:

<!-- components/i18n-text/i18n-text.vue -->
<template><text :class="['i18n-text', customClass]" :style="customStyle">{{ finalText }}</text>
</template><script>
export default {name: 'i18n-text',props: {// i18n键名i18n: {type: String,default: ''},// 参数对象,用于替换占位符params: {type: Object,default: () => ({})},// 不使用i18n时的直接文本text: {type: String,default: ''},// 自定义类名customClass: {type: String,default: ''},// 自定义样式customStyle: {type: String,default: ''}},computed: {finalText() {// 优先使用i18n键名进行翻译if (this.i18n) {return this.$t(this.i18n, this.params)}// 否则直接使用传入的文本return this.text}}
}
</script><style>
.i18n-text {/* 可根据需要添加样式 */
}
</style>

注册为全局组件:

// components/index.js
import i18nText from './i18n-text/i18n-text.vue'export default {install(Vue) {Vue.component('i18n-text', i18nText)// 其他全局组件...}
}// main.js中引入并使用
import components from './components'
Vue.use(components)

实用功能开发

1. 语言切换工具类

// utils/language.js
import i18n from '@/lang'export const switchLanguage = (lang) => {// 切换语言i18n.locale = lang// 持久化语言设置uni.setStorageSync('language', lang)// 通知所有页面语言已变更uni.$emit('languageChanged', lang)// 刷新当前页面const pages = getCurrentPages()const currentPage = pages[pages.length - 1]if (currentPage && currentPage.$vm) {currentPage.$vm.$forceUpdate()}
}// 获取当前语言
export const getCurrentLanguage = () => {return i18n.locale
}// 检查是否为RTL语言(如阿拉伯语)
export const isRTLLanguage = () => {const rtlLanguages = ['ar', 'he'] // 从右到左书写的语言代码return rtlLanguages.includes(getCurrentLanguage())
}

2. 语言选择器组件

<!-- components/language-picker/language-picker.vue -->
<template><view class="language-picker"><view class="current-language" @tap="showOptions = true"><image :src="languageIcons[currentLanguage]" class="language-icon"></image><text>{{ languageNames[currentLanguage] }}</text><uni-icons type="bottom" size="14" color="#666"></uni-icons></view><uni-popup ref="popup" type="bottom" @change="popupChange"><view class="language-options"><view class="popup-title"><i18n-text i18n="settings.selectLanguage"></i18n-text></view><view v-for="(name, code) in languageNames" :key="code"class="language-option":class="{ active: currentLanguage === code }"@tap="changeLanguage(code)"><image :src="languageIcons[code]" class="language-icon"></image><text>{{ name }}</text><uni-icons v-if="currentLanguage === code" type="checkmarkempty" size="18" color="#007AFF"></uni-icons></view><view class="cancel-btn" @tap="showOptions = false"><i18n-text i18n="common.cancel"></i18n-text></view></view></uni-popup></view>
</template><script>
import { getCurrentLanguage, switchLanguage } from '@/utils/language'export default {name: 'language-picker',data() {return {showOptions: false,currentLanguage: getCurrentLanguage(),languageNames: {'en': 'English','zh-CN': '简体中文','fr': 'Français',},languageIcons: {'en': '/static/flags/en.png','zh-CN': '/static/flags/zh-cn.png','fr': '/static/flags/fr.png',}}},watch: {showOptions(val) {if (val) {this.$refs.popup.open()} else {this.$refs.popup.close()}}},methods: {changeLanguage(lang) {if (this.currentLanguage === lang) {this.showOptions = falsereturn}// 设置加载状态uni.showLoading({ title: '' })// 切换语言switchLanguage(lang)this.currentLanguage = langthis.showOptions = falsesetTimeout(() => {uni.hideLoading()}, 500)},popupChange(e) {this.showOptions = e.show}}
}
</script><style lang="scss">
.language-picker {.current-language {display: flex;align-items: center;padding: 6rpx 16rpx;border-radius: 8rpx;background-color: rgba(0, 0, 0, 0.05);.language-icon {width: 36rpx;height: 36rpx;margin-right: 8rpx;border-radius: 50%;}}.language-options {background-color: #fff;border-radius: 16rpx 16rpx 0 0;padding-bottom: env(safe-area-inset-bottom);.popup-title {text-align: center;padding: 30rpx 0;font-size: 32rpx;font-weight: 500;border-bottom: 1rpx solid #eee;}.language-option {display: flex;align-items: center;padding: 30rpx 40rpx;border-bottom: 1rpx solid #f5f5f5;.language-icon {width: 50rpx;height: 50rpx;margin-right: 20rpx;border-radius: 50%;}&.active {background-color: #f9f9f9;}}.cancel-btn {text-align: center;padding: 30rpx 0;color: #007AFF;font-size: 32rpx;}}
}
</style>

实战应用

1. 在页面中使用

<!-- pages/home/home.vue -->
<template><view class="home"><view class="header"><i18n-text i18n="home.title" class="title"></i18n-text><language-picker></language-picker></view><view class="content"><view class="welcome-message"><i18n-text i18n="home.welcome" :params="{ username: userInfo.nickname }"></i18n-text></view><view class="product-list"><view class="product-item" v-for="(item, index) in productList" :key="index"><image :src="item.image" mode="aspectFill"></image><view class="product-info"><!-- 产品标题可能来自接口,需要动态翻译 --><text class="product-title">{{ getProductTitle(item) }}</text><text class="product-price">{{ formatCurrency(item.price) }}</text></view></view></view></view></view>
</template><script>
export default {data() {return {userInfo: {nickname: '张三'},productList: []}},onLoad() {this.fetchProductList()// 监听语言变化刷新数据uni.$on('languageChanged', this.handleLanguageChange)},onUnload() {uni.$off('languageChanged', this.handleLanguageChange)},methods: {async fetchProductList() {// 模拟接口请求const res = await this.$api.product.getList()this.productList = res.data},handleLanguageChange() {// 语言变化时刷新数据this.fetchProductList()},// 根据当前语言获取正确的产品标题getProductTitle(item) {const lang = this.$i18n.localeconst titleKey = `title_${lang.replace('-', '_')}`// 如果接口返回了对应语言的标题,优先使用if (item[titleKey]) {return item[titleKey]}// 否则使用默认语言标题return item.title},// 根据当前语言格式化货币formatCurrency(price) {const lang = this.$i18n.localeconst currencyMap = {'zh-CN': 'CNY','en': 'USD','fr': 'EUR'}return new Intl.NumberFormat(lang, {style: 'currency',currency: currencyMap[lang] || 'USD'}).format(price)}}
}
</script>

2. 处理动态内容和API数据

在实际项目中,我们经常需要处理来自API的多语言数据,以下是一些常用策略:

// 处理API返回的多语言内容
export const processMultiLangContent = (data) => {const currentLang = getCurrentLanguage()const result = {}// 递归处理对象const processObject = (obj) => {const newObj = {}Object.keys(obj).forEach(key => {const value = obj[key]// 如果是多语言字段对象 { zh-CN: '中文', en: 'English' }if (value && typeof value === 'object' && !Array.isArray(value) && value[currentLang]) {newObj[key] = value[currentLang]} // 如果是普通对象,递归处理else if (value && typeof value === 'object' && !Array.isArray(value)) {newObj[key] = processObject(value)}// 如果是数组,处理数组中的每个对象else if (Array.isArray(value)) {newObj[key] = value.map(item => {if (typeof item === 'object') {return processObject(item)}return item})}// 其他情况直接赋值else {newObj[key] = value}})return newObj}return processObject(data)
}

进阶技巧

1. 请求拦截器添加语言参数

为了让后端能够返回对应语言的内容,我们在请求拦截器中添加语言参数:

// request.js
import { getCurrentLanguage } from '@/utils/language'// 请求拦截
export const requestInterceptor = (config) => {// 添加语言参数config.header = {...config.header,'Accept-Language': getCurrentLanguage()}return config
}

2. 处理消息提示

封装消息提示方法,自动应用翻译:

// utils/message.js
import i18n from '@/lang'export const showToast = (messageKey, params = {}) => {uni.showToast({title: i18n.t(messageKey, params),icon: 'none'})
}export const showModal = (titleKey, contentKey, params = {}) => {return new Promise((resolve, reject) => {uni.showModal({title: i18n.t(titleKey),content: i18n.t(contentKey, params),confirmText: i18n.t('common.confirm'),cancelText: i18n.t('common.cancel'),success: (res) => {if (res.confirm) {resolve(true)} else {resolve(false)}},fail: reject})})
}

常见问题及解决方案

1. 组件未响应语言变化

解决方案:使用事件总线通知组件重新渲染

// 切换语言时触发全局事件
uni.$emit('languageChanged', newLang)// 在组件中监听
created() {this.unsubscribe = uni.$on('languageChanged', this.handleLanguageChange)
},
beforeDestroy() {this.unsubscribe()
},
methods: {handleLanguageChange() {this.$forceUpdate()}
}

2. 日期格式化问题

解决方案:封装日期格式化工具函数

// utils/date.js
import { getCurrentLanguage } from './language'export const formatDate = (date, format = 'short') => {const targetDate = new Date(date)const lang = getCurrentLanguage()const options = {'short': { year: 'numeric', month: 'short', day: 'numeric' },'long': { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' },'time': { hour: '2-digit', minute: '2-digit' },'full': { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long', hour: '2-digit', minute: '2-digit' }}return new Intl.DateTimeFormat(lang, options[format]).format(targetDate)
}

性能优化

为了提高应用性能,我们采取了以下措施:

  1. 按需加载语言包:根据用户设置的语言只加载需要的语言包
  2. 缓存翻译结果:对频繁使用的翻译进行缓存
  3. 避免过度翻译:只翻译用户可见内容,非关键内容使用默认语言
// lang/loader.js - 动态加载语言包
export const loadLanguage = async (lang) => {let messages = {}try {// 动态导入语言包const module = await import(/* webpackChunkName: "[request]" */ `./${lang}.js`)messages = module.default} catch (e) {console.error(`Could not load language pack: ${lang}`, e)// 加载失败时使用备用语言const fallbackModule = await import(/* webpackChunkName: "en" */ './en.js')messages = fallbackModule.default}return messages
}

总结

通过本文,我们详细介绍了UniApp中实现国际化的完整方案,从基础配置到组件封装,再到实际应用和性能优化。这套方案具有以下特点:

  1. 易用性:通过组件化设计,使翻译使用变得简单
  2. 灵活性:支持静态翻译和动态内容翻译
  3. 可扩展性:轻松添加新语言支持
  4. 性能优化:按需加载和缓存机制保证性能

希望这篇文章能对大家在UniApp项目中实现国际化有所帮助。如果有任何问题或建议,欢迎在评论区留言交流!

参考资料

  1. vue-i18n官方文档
  2. UniApp全局组件开发文档
  3. Web国际化API

相关文章:

鸿蒙OSUniApp开发支持多语言的国际化组件#三方框架 #Uniapp

使用UniApp开发支持多语言的国际化组件 在全球化的今天&#xff0c;一个优秀的应用往往需要支持多种语言以满足不同地区用户的需求。本文将详细讲解如何在UniApp框架中实现一套完整的国际化解决方案&#xff0c;从而轻松实现多语言切换功能。 前言 去年接手了一个面向国际市场…...

MySQL之基础事务

目录 引言&#xff1a; 什么是事务&#xff1f; 事务和锁 mysql数据库控制台事务的几个重要操作指令&#xff08;transaction.sql&#xff09; 1、事物操作示意图&#xff1a; 2.事务的隔离级别 四种隔离级别&#xff1a; 总结一下隔离指令 1. 查看当前隔离级别​​ …...

OpenHarmony系统HDF驱动开发介绍(补充)

一、HDF驱动简介 HDF&#xff08;Hardware Driver Foundation&#xff09;驱动框架&#xff0c;为驱动开发者提供驱动框架能力&#xff0c;包括驱动加载、驱动服务管理、驱动消息机制和配置管理。 简单来说&#xff1a;HDF框架的驱动和Linux的驱动比较相似都是由配置文件和驱动…...

深度学习中的查全率与查准率:如何实现有效权衡

&#x1f4cc; 友情提示&#xff1a; 本文内容由银河易创AI&#xff08;https://ai.eaigx.com&#xff09;创作平台的gpt-4-turbo模型辅助生成&#xff0c;旨在提供技术参考与灵感启发。文中观点或代码示例需结合实际情况验证&#xff0c;建议读者通过官方文档或实践进一步确认…...

文件名是 ‪E:\20250512_191204.mp4, EV软件录屏,未保存直接关机损坏, 如何修复?

去github上下载untrunc 工具就能修复 https://github.com/anthwlock/untrunc/releases 如果访问不了 本机的 hosts文件设置 140.82.112.3 github.com 199.232.69.194 github.global.ssl.fastly.net 就能访问了 实在不行&#xff0c;从这里下载&#xff0c;传上去了 https://do…...

界面控件DevExpress WinForms v24.2 - 数据处理功能增强

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…...

Web UI测试效率低?来试Parasoft Selenic的智能修复与分析!

如果你正在使用Selenium进行Web UI测试&#xff0c;但被测试维护的繁琐、测试不稳定以及测试执行缓慢等问题困扰&#xff0c;不妨试试Parasoft Selenic&#xff01; Parasoft Selenic能够通过智能修复与分析功能&#xff0c;帮你自动检测并修复测试中的不稳定因素&#xff0c;…...

计算机视觉最不卷的方向:三维重建学习路线梳理

提到计算机视觉&#xff08;CV&#xff09;&#xff0c;大多数人脑海中会立马浮现出一个字&#xff1a;“卷”。卷到什么程度呢&#xff1f;2022年秋招CV工程师岗位数下降了16%&#xff0c;但求职人数增加了23%&#xff0c;求职人数与招聘岗位的比例达到了恐怖的15:1&#xff0…...

国产 ETL 数据集成厂商推荐—谷云科技 RestCloud

数字化转型加速推进的商业环境中&#xff0c;数据已成为企业最为关键的资产之一。然而&#xff0c;随着企业信息化的建设不断深入&#xff0c;各个业务系统之间数据分散、格式不一、难以互通等问题日益凸显&#xff0c;严重制约了企业对数据价值的深度挖掘与高效利用。在此背景…...

vscode extention踩坑记

# npx vsce package --allow-missing-repository --no-dependencies #耗时且不稳定 npx vsce package --allow-missing-repository #用这行 code --install-extension $vsixFileName --force我问ai&#xff1a;为什么我的.vsix文件大了那么多 ai答&#xff1a;因为你没有用 --n…...

AI时代的弯道超车之第十二章:英语和编程重要性?

在这个AI重塑世界的时代,你还在原地观望吗?是时候弯道超车,抢占先机了! 李尚龙倾力打造——《AI时代的弯道超车:用人工智能逆袭人生》专栏,带你系统掌握AI知识,从入门到实战,全方位提升认知与竞争力! 内容亮点: AI基础 + 核心技术讲解 职场赋能 + 创业路径揭秘 打破…...

关于数据湖和数据仓的一些概念

一、前言 随着各行业数字化发展的深化,数据资产和数据价值已越来越被深入企业重要发展的战略重心,海量数据已成为多数企业生产实际面临的重要问题,无论存储容量还是成本,可靠性都成为考验企业数据治理的考验。本文来看下海量数据存储的数据湖和数据仓,数据仓库和数据湖,…...

hbase shell的常用命令

一、hbase shell的基础命令 # 客户端登录 [rootCloud-Hadoop-NN-02 hbase]$ ./bin/hbase shell# 查看所有表 hbase> list### 创建数据表student&#xff0c;包含Sname、Ssex、Sage、Sdept、course列族/列 ### 说明&#xff1a;列族不指定列名时&#xff0c;列族可以直接成为…...

高并发内存池(四):Page Cache结构设计

目录 一&#xff0c;项目整体框架回顾 Thread Cache结构 Central Cache结构 二&#xff0c;Page Cache大致框架 三&#xff0c;Page Cache申请内存实现 Central Cache向Page Cache申请内存接口 从Page Cache中获取span接口 Page Cache加锁问题 申请内存完整过程 源码&a…...

易学探索助手-项目记录(九)

本文介绍本地大模型推理数据集构成 &#xff08;一&#xff09;古籍数据获取 以44种竖向从右至左排列的繁体古文为研究对象&#xff0c;通过OCR识别、XML结构化处理&#xff0c;最终生成符合大模型训练要求的数据集。 1.技术路线设计 图像处理层&#xff1a;PaddleOCR识别竖…...

Idea 设置编码UTF-8 Idea中 .properties 配置文件中文乱码

Idea 设置编码UTF-8 Idea中 .properties 配置文件中文乱码 一、设置编码 1、步骤&#xff1a; File -> Setting -> Editor -> File encodings --> 设置编码二、配置文件中文乱码 1、步骤&#xff1a; File -> Setting -> Editor -> File encodings ->…...

Redis缓存穿透、雪崩、击穿的解决方案?

Redis 缓存问题解决方案及Java实现 一、缓存穿透解决方案 &#xff08;缓存穿透指查询不存在数据&#xff0c;绕过缓存直接访问数据库&#xff09; 1. 布隆过滤器 空值缓存 注意点&#xff1a; 1.布隆过滤器是需要预热数据的&#xff0c;就是需要输入当前数据库已经存在的…...

第29节:现代CNN架构-Inception系列模型

引言 Inception系列模型是卷积神经网络(CNN)发展历程中的重要里程碑,由Google研究人员提出并不断演进。这一系列模型通过创新的架构设计,在保持计算效率的同时显著提升了图像识别任务的性能。从最初的Inception v1到最新的Inception-ResNet,每一代Inception模型都引入了突破…...

初识C++:类和对象(上)

概述&#xff1a;本篇博客主要讲解类和对象的学习。 目录 1. 类的定义 1.1 类定义格式 1.2 访问限定符 1.3 类域 2.实例化 2.1 实例化概念 2.2 this指针 3. 小结 1. 类的定义 1.1 类定义格式 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{} 中为类的…...

腾讯 IMA 工作台升级:新增知识库广场与 @提问功能

目录 一、引言 二、知识库广场功能 2.1 功能架构解析 2.2 技术实现突破 三、知识库提问功能 3.1 交互模式革新 3.2 技术底层逻辑 四、实战价值 4.1 知识管理方面 4.2 工作效率提升方面 4.3 团队协作方面 4.4 知识变现方面 五、未来展望 5.1 技术演进方向 5.2 商业…...

[目标检测] YOLO系列算法讲解

前言 目标检测就是做到给模型输入一张图片或者视频&#xff0c;模型可以迅速判断出视频和图片里面感兴趣的目标所有的位置和它 的类别&#xff0c;而当前最热门的目标检测的模型也就是YOLO系列了。 YOLO系列的模型的提出&#xff0c;是为了解决当时目标检测的模型帧率太低而提…...

Python 之 selenium 打开浏览器指定端口进行接续操作

一般使用 selenium 进行数据爬取时&#xff0c;常用处理流程是让 selenium 从打开浏览器开始&#xff0c;完成全流程的所有操作。但是有时候&#xff0c;我们希望用户先自己打开浏览器进入指定网页&#xff0c;完成登录认证等一系列操作之后&#xff08;比如用户、密码、短信验…...

GPUGeek携手ComfyUI :低成本文生图的高效解决方案

一、文生图领域的困境与ComfyUI的优势 在当今数字化创意表达的时代&#xff0c;文生图技术日益受到关注。像豆包这类以语言交互为主的大模型&#xff0c;虽然在文本处理上表现出色&#xff0c;但在文生图方面&#xff0c;其生成效果难以达到专业图像创作的要求。而Midjourney&…...

OpenCV CUDA 模块中用于在 GPU 上计算两个数组对应元素差值的绝对值函数absdiff(

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 void cv::cuda::absdiff 是 OpenCV CUDA 模块中的一个函数&#xff0c;用于在 GPU 上计算两个数组对应元素差值的绝对值。 该函数会逐元素计算两…...

互联网大厂Java面试题:深入解析SpringCloud微服务架构中的服务注册与发现机制

互联网大厂Java面试题&#xff1a;深入解析SpringCloud微服务架构中的服务注册与发现机制 面试题 问题&#xff1a; 在SpringCloud微服务架构中&#xff0c;服务注册与发现是核心功能之一。请详细说明Nacos作为服务注册中心的实现原理&#xff0c;并对比其与Eureka的异同点。…...

东芝新四款产品“TB67Z830SFTG、TB67Z830HFTG、TB67Z850SFTG、TB67Z850HFTG系列三相栅极驱动器ic三相栅极驱动器IC

支持用于电动工具、吸尘器、工业机器人等的三相无刷DC电机 东芝电子设备与存储公司(简称“东芝”)推出了TB67Z83xxFTG系列三相栅极驱动器ic的四个产品和TB67Z85xxFTG系列三相栅极驱动器IC的四个产品&#xff0c;用于消费和工业设备的三相无刷DC电机。通过将新产品与作为电机控制…...

react+html-docx-js将页面导出为docx

1.主要使用&#xff1a;html-docx-js进行前端导出 2.只兼容到word&#xff0c;wps兼容不太好 3.处理分页换行 4.处理页眉 index.tsx import { saveAs } from file-saver; import htmlToDocxGenerate from ./HtmlToDocx;const handleExportByHtml async () > {const expor…...

Linux基础 -- SSH 流式烧录与压缩传输笔记

Linux SSH 流式烧录与压缩传输指南 一、背景介绍 在嵌入式开发和维护中&#xff0c;常常需要通过 SSH 从 PC 向设备端传输大文件&#xff08;如系统镜像、固件&#xff09;并将其直接烧录到指定磁盘&#xff08;如 /dev/mmcblk2&#xff09;。然而&#xff0c;设备端存储空间…...

<论文>(微软)避免推荐域外物品:基于LLM的受限生成式推荐

一、摘要 本文介绍微软和深圳大学合作发表于2025年5月的论文《Avoid Recommending Out-of-Domain Items: Constrained Generative Recommendation with LLMs》。论文主要研究如何解决大语言模型&#xff08;LLMs&#xff09;在推荐系统中推荐域外物品的问题&#xff0c;提出了 …...

2025年渗透测试面试题总结-360[实习]安全工程师(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 1. 自我介绍 2. WAF及其绕过方式 3. IPS/IDS/HIDS 4. 云安全 5. 绕过安骑士/安全狗 6. Gopher扩展…...

【机器学习】支持向量回归(SVR)从入门到实战:原理、实现与优化指南

前言 在机器学习的广阔领域中&#xff0c;回归分析作为预测连续型变量的重要手段&#xff0c;被广泛应用于金融预测、工业生产、科学研究等诸多场景。支持向量回归&#xff08;SVR&#xff09;作为回归算法家族中的佼佼者&#xff0c;凭借独特的理论优势与强大的实践能力脱颖而…...

右值引用的学习

传统的C语法中就有引用的语法&#xff0c;而C11中新增了的右值引用语法特性&#xff0c;所以从现在开始我们之前学习的引用就叫做左值引用。无论左值引用还是右值引用&#xff0c;都是给对象取别名。 左值引用和右值引用 在讲之前&#xff0c;我们先来看一下什么是左值和右值…...

碎片笔记|AI生成图像溯源方法源码复现经验(持续更新中……)

前言&#xff1a;本篇博客分享一些溯源方法的复现经验&#xff0c;希望能帮助到大家&#x1f389;。 目录 1. Close-set AttributionRepmixDe-FakeDNA-Net 2. Open-set AttributionPOSE 3. Single-Model AttributionOCC-CLIPLatentTracer 1. Close-set Attribution Repmix 论…...

elementplus el-tree 二次封装支持配置删除后展示展开或折叠编辑复选框懒加载功能

本文介绍了基于 ElementPlus 的 el-tree 组件进行二次封装的 TreeView 组件&#xff0c;使用 Vue3 和 JavaScript 实现。TreeView 组件通过 props 接收树形数据、配置项等&#xff0c;支持懒加载、节点展开/收起、节点点击、删除、编辑等操作。组件内部通过 ref 管理树实例&…...

【C/C++】深度探索c++对象模型_笔记

1. 对象内存布局 (1) 普通类&#xff08;无虚函数&#xff09; 成员变量排列&#xff1a;按声明顺序存储&#xff0c;但编译器会根据内存对齐规则插入填充字节&#xff08;padding&#xff09;。class Simple {char a; // 1字节&#xff08;偏移0&#xff09;int b; …...

Spring MVC数据绑定和响应 你了解多少?

数据绑定的概念 在程序运行时&#xff0c;Spring MVC接收到客户端的请求后&#xff0c;会根据客户端请求的参数和请求头等数据信息&#xff0c;将参数以特定的方式转换并绑定到处理器的形参中。Spring MVC中将请求消息数据与处理器的形参建立连接的过程就是Spring MVC的数据绑…...

外贸礼品禁忌

一、亚洲 1.印度 牛是神圣动物&#xff0c;别送牛皮制品。另外&#xff0c;左手不洁&#xff0c;送礼得用右手或双手。 2.日本 “梳” 和 “苦” 谐音&#xff0c;不送梳子。日本男性不咋佩戴首饰&#xff0c;除结婚戒指。礼物得装盒、纸包、绳饰&#xff0c;白色包装得有…...

【MySQL 基础篇】深入解析MySQL逻辑架构与查询执行流程

1 MySQL逻辑架构概述 MySQL 的逻辑架构主要分为 Server 层和存储引擎层两部分。 Server 层&#xff1a;包含连接器、查询缓存、分析器、优化器、执行器等组件。同时&#xff0c;所有的内置函数&#xff08;如日期、时间、数学和加密函数等&#xff09;也在这一层实现。此外&a…...

基于C#实现中央定位服务器的 P2P 网络聊天系统

基于中央定位服务器的 P2P 网络聊天系统 1 需求分析与实现功能 本次作业旨在实现一个基于中央定位服务器的 P2P 网络聊天系统&#xff0c;也即通过中央定位服务器实现登入&#xff0c;登出与好友的 IP 查询等操作&#xff0c;在好友间的通信使用 P2P 来完成&#xff0c;具体见…...

【C++】map和set的模拟实现

1.底层红黑树节点的定义 enum Colur {RED,BLACK }; template<class T> struct RBTreeNode {RBTreeNode<T>* _left;RBTreeNode<T>* _right;RBTreeNode<T>* _parent;T _data;Colur _col;RBTreeNode(const T& data):_left(nullptr), _right(nullptr…...

数据结构·字典树

字典树trie 顾名思义&#xff0c;在一个字符串的集合里查询某个字符串是否存在树形结构。 树存储方式上用的是结构体数组&#xff0c;类似满二叉树的形式。 模板 定义结构体和trie 结构体必须的内容&#xff1a;当前结点的字符&#xff0c;孩子数组可选&#xff1a;end用于查…...

centos服务器,疑似感染phishing家族钓鱼软件的检查

如果怀疑 CentOS 服务器感染了 Phishing 家族钓鱼软件&#xff0c;需要立即进行全面检查并采取相应措施。以下是详细的检查和处理步骤&#xff1a; 1. 立即隔离服务器 如果可能&#xff0c;将服务器从网络中隔离&#xff0c;以防止进一步传播或数据泄露。如果无法完全隔离&…...

(C语言)超市管理系统(测试2版)(指针)(数据结构)(清屏操作)

目录 前言&#xff1a; 源代码&#xff1a; product.h product.c fileio.h fileio.c main.c 代码解析&#xff1a; 一、程序结构概述 二、product.c 函数详解 1. 初始化商品列表 Init_products 2. 添加商品 add_product 3. 显示商品 display_products 4. 修改商品 mo…...

可变形卷积简介(Deformable Convolution)

1. 核心原理 可变形卷积通过动态调整卷积核的采样位置&#xff0c;增强模型对几何形变&#xff08;如旋转、缩放&#xff09;的适应能力。其核心改进包括&#xff1a; 偏移量&#xff08;Offset&#xff09;&#xff1a;为卷积核的每个采样点学习 x / y x/y x/y方向的偏移量 …...

02_Servlet

目录 一、简介二、Servlet入门案例2.1、编写Servlet2.2、配置Servlet2.3、访问Servlet2.4、常见错误 三、Servlet详解3.1、实现Servlet的三种方式3.1.1、实现Servlet接口3.1.2、继承GenericServlet类3.1.3、继承HttpServlet类 3.2、配置Servlet的两种方式3.2.1、web.xml方式3.2…...

stm32之FLASH

目录 1.简介2.闪存模块组织3.基本结构3.1 FPEC3.2 程序存储器3.2.1 标准编程3.2.2 页擦除3.2.3 全擦除 3.3 选项字节3.3.1 编程3.3.2 擦除 4.器件电子签名5.实验-读取内部FLASH 1.简介 STM32F1系列的FLASH内存是一个非常重要的存储区域&#xff0c;它主要由三个部分组成&#…...

第3.4节 调用链路分析服务开发

3.4.1 什么是Code Call Graph&#xff08;CCG&#xff09; Code Call Graph&#xff08;CCG&#xff09;即业务代码中的调用关系图&#xff0c;是通过静态分析手段分析并构建出的一种描述代码间关系的图。根据精度不同&#xff0c;一般分为类级别、方法级别、控制流级别&#x…...

超详细Docker教程

前言&#xff1a;大家在在Linux上部署mysql及其他软件时&#xff0c;大家想一想自己最大的感受是什么&#xff1f; 我相信&#xff0c;除了个别天赋异禀的人以外&#xff0c;大多数人都会有相同的感受&#xff0c;那就是麻烦。核心体现在三点&#xff1a; 命令太多了&#xff…...

探索AI新领域:生成式人工智能认证(GAI认证)助力职场发展

在数字化时代的大潮中&#xff0c;人工智能&#xff08;AI&#xff09;技术以其强大的影响力和广泛的应用前景&#xff0c;正逐步重塑我们的生活与工作方式。随着生成式AI技术的崛起&#xff0c;掌握这一前沿技能已成为职场竞争中的关键优势。那么&#xff0c;如何通过系统的学…...

sql sql复习

虽然之前学习过sql&#xff0c;但由于重在赶学习进度&#xff0c;没有学扎实&#xff0c;导致自己刷题的时候有的地方还是模模糊糊&#xff0c;现在主要是复习&#xff0c;补一补知识点。 今日靶场&#xff1a; NSSCTF 云曦历年考核题 在做题之前先回顾一下sql注入的原理&…...