Vue3+vite优化基础架构(3)--- 优化vue-i18n国际化配置

news2024/11/23 2:50:29

Vue3+vite优化基础架构(3)--- 优化vue-i18n国际化配置

  • 说明
  • 全部页面进行中英文使用
  • 测试中英文切换
  • 对ElementPlus里面的所有组件进行中英文切换

说明

这里记录下自己在Vue3+vite的项目增加全局中英文切换按钮对页面进行中英文切换及同时对ElementPlus里面的所有组件进行中英文切换,不使用ts语法,方便以后直接使用。这里承接自己的博客Vue3+vite优化基础架构(2)— 全局接口请求loading加载这篇博客,在该博客项目的基础上增加全局中英文切换按钮对页面进行中英文切换及同时对ElementPlus里面的所有组件进行中英文切换。

全部页面进行中英文使用

在src/store/modules/userStore.js文件下增加如下代码:
在这里插入图片描述

userStore.js文件代码如下:

//使用pinia来管理全局状态
import { defineStore } from "pinia"

/*defineStore 是需要传参数的,其中第一个参数是id,就是一个唯一的值,
简单点说就可以理解成是一个命名空间.
第二个参数就是一个对象,里面有三个模块需要处理,第一个是 state,
第二个是 getters,
第三个是 actions。
*/
//声明了一个useUserStore方法
const useUserStore = defineStore('user', {
  //准备state——用于存储数据
  state: () => {
    return {
      //当前激活菜单的index
      activeMenu: '',
      //绑定值,选中选项卡的name
      editableTabsValue: '',
      //tab标签选项卡内容
      editableTabs: [],
      //tab页路由地址及参数
      tabRouterList: [],
      //中英文语言,默认中文
      language: 'zh'
    }
  },
  //使用persist插件对state里面属性进行缓存
  persist: {
    enabled: true,//开启缓存,默认缓存所有state里面的属性,默认key为defineStore里面的id值,这里id值为user,所以默认key为user
    //自定义持久化参数,指定以下state里面的属性进行缓存,未指定的不进行缓存
    strategies: [
      {
        // 自定义key
        key: 'activeMenu',
        // 自定义存储方式,默认sessionStorage
        storage: sessionStorage,
        // 指定要持久化的数据
        paths: ['activeMenu']
      },
      {
        key: 'editableTabsValue',
        storage: sessionStorage,
        paths: ['editableTabsValue']
      },
      {
        key: 'editableTabs',
        storage: sessionStorage,
        paths: ['editableTabs']
      },
      {
        key: 'tabRouterList',
        storage: sessionStorage,
        paths: ['tabRouterList']
      },
      {
        key: 'language',
        storage: sessionStorage,
        paths: ['language']
      }
    ]
  },
  getters: {

  },
  //准备actions——用于响应组件中的动作和用于操作数据(state),pinia中只有state、getter、action,抛弃了Vuex中的Mutation
  actions: {
    /**
     * 修改state中数据的方法
     * @param name 需要修改的属性名
     * @param value 修改值
     */
    updateState([name, value]) {
      this[name] = value
    },
    //动态添加tab标签,item为当前点击的菜单项
    addTab(item) {
      const newTab = {
        title: item.meta.title,
        name: item.url,
        iconClass: item.meta.icon,
      }
      // 判断当前editableTabs中是否存在该tab标签
      if (this.editableTabs.findIndex(item => item.title === newTab.title) === -1) {
        this.editableTabs.push(newTab);
        this.editableTabsValue = newTab.name;
        this.activeMenu = newTab.name;
      }
    },
    //移除tab标签
    removeTab(targetName) {
      let tabs = this.editableTabs
      let activeName = this.editableTabsValue
      if (activeName === targetName) {
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            let nextTab = tabs[index + 1] || tabs[index - 1]
            if (nextTab) {
              activeName = nextTab.name
            }
          }
        })
      }
      this.activeMenu = activeName
      this.editableTabsValue = activeName
      this.editableTabs = tabs.filter(tab => tab.name !== targetName)
      this.tabRouterList = this.tabRouterList.filter(item => item.path !== targetName)
    }
  }
})

export default useUserStore

在src/views/layout/components/navbar.vue文件下增加如下代码:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

navbar.vue全部代码如下:

<!--通用布局头部内容-->
<template>
  <el-row>
    <el-col :span="20">
      <el-tabs
          v-model="store.editableTabsValue"
          type="border-card"
          closable
          @tab-remove="handleTabRemove"
          @tab-click="handleTabClick"
          v-if="store.editableTabs.length !== 0">
        <el-tab-pane v-for="item in store.editableTabs" :key="item.name" :name="item.name" :label="item.title">
          <!-- 右键菜单开始:自定义标签页显示名称,保证每个标签页都能实现右键菜单 -->
          <template #label>
            <el-dropdown
                trigger="contextmenu"
                :id="item.name"
                @visible-change="handleChange($event, item.name)"
                ref="dropdownRef">
              <span style="font-size: 16px;color: #909399;"
                    :class="store.editableTabsValue === item.name ? 'label' : ''">
                <SvgIcon :iconClass="item.iconClass"></SvgIcon>{{ item.title }}
              </span>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item @click="closeCurrent(item.name)">
                    <el-icon>
                      <Close />
                    </el-icon>关闭当前标签页
                  </el-dropdown-item>
                  <el-dropdown-item @click="closeLeft(item.name)" v-if="show(item.name, 'left')">
                    <el-icon>
                      <DArrowLeft />
                    </el-icon>关闭左侧标签页
                  </el-dropdown-item>
                  <el-dropdown-item @click="closeRight(item.name)" v-if="show(item.name, 'right')">
                    <el-icon>
                      <DArrowRight />
                    </el-icon>关闭右侧标签页
                  </el-dropdown-item>
                  <el-dropdown-item @click="closeOther(item.name)" v-if="store.editableTabs.length > 1">
                    <el-icon>
                      <Operation />
                    </el-icon>关闭其他标签页
                  </el-dropdown-item>
                  <el-dropdown-item @click="closeAll()">
                    <el-icon>
                      <Minus />
                    </el-icon>关闭全部标签页
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </template>
          <!-- 右键菜单结束 -->
        </el-tab-pane>
      </el-tabs>
    </el-col>
    <el-col :span="4">
      <div class="header">
        <!-- 语言切换 -->
        <div class="language" @click="languageSwitch">{{ store.language === "en" ? "中文" : "English" }}</div>
        <!--trigger="click"通过点击下标触发-->
        <div style="cursor: pointer;">
          <el-dropdown trigger="click">
          <span>
            {{ $t("username") }}
            <SvgIcon iconClass="arrowDown" />
          </span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item @click="logout">
                  退出登录
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </div>
    </el-col>
  </el-row>
</template>

<script setup name="navbar">
  //引入全局状态里面的关于菜单栏列表数据和相关方法
  import useUserStore from '@/store/modules/userStore'
  import { useRouter, useRoute } from "vue-router"
  import { onMounted, ref, computed } from 'vue'
  import { useI18n } from "vue-i18n"
  import {
    Close,
    DArrowLeft,
    DArrowRight,
    Operation,
    Minus
  } from '@element-plus/icons-vue'

  //接手全局状态里面的属性和方法
  const store = useUserStore();
  //使用路由相当于$router,系统路由方法
  const router = useRouter()
  //使用路由相当于$route,点击菜单栏时当前点击的路由页面里面的属性值
  const route = useRoute()
  //使用useI18n
  const { t, locale } = useI18n()
  //用户名
  const username = '超级管理员'

  //触发右键菜单标签页为第一个时,不展示【关闭左侧标签页】
  //触发右键菜单标签页为最后一个时,不展示【关闭右侧标签页】
  const show = (name, type) => {
    const index = store.editableTabs.findIndex((item) => name === item.name)
    return type === 'left' ? index !== 0 : index !== store.editableTabs.length - 1
  }

  //右键菜单ref
  const dropdownRef = ref()

  //在触发右键菜单后,关闭其他tab页上的右键菜单
  const handleChange = (visible, name) => {
    if (!visible) return
    dropdownRef.value.forEach((item) => {
      if (item.id === name) return
      item.handleClose()
    })
  }

  //关闭当前tab页
  const closeCurrent = (targetName) => {
    handleTabRemove(targetName)
  }

  //关闭左侧tab页
  const closeLeft = (targetName) => {
    //查找当前点击的tab页所在位置
    let currentIndex = store.editableTabs.findIndex(
        (item) => item.name === targetName
    )
    //查找当前激活标签页index
    const activeIndex = store.editableTabs.findIndex((item) => item.name === store.editableTabsValue)
    //关闭左侧tab页
    store.editableTabs.splice(0, currentIndex)
    //删除对应的左侧历史路由
    store.tabRouterList.splice(0, currentIndex)
    //如果当前关闭点击的tab页包含激活的tab页,则将激活tab页重置为当前点击的tab
    if (activeIndex < currentIndex) {
      //将当前激活的tab页改为当前点击的
      store.updateState(['editableTabsValue', targetName])
      //将激活菜单改为当前点击的
      store.updateState(['activeMenu', targetName])
      //路由跳转到当前点击的tab页
      //查询当前点击的tab页缓存路由参数
      let result = store.tabRouterList.find(item => item.path === targetName);
      //路由跳转且带上对应tab页的参数
      router.push({ path: targetName, query: result.query })
    }
  }

  //关闭右侧tab页
  const closeRight = (targetName) => {
    //查找当前点击的tab页所在位置
    let currentIndex = store.editableTabs.findIndex(
        (item) => item.name === targetName
    )
    //查找当前激活标签页index
    const activeIndex = store.editableTabs.findIndex((item) => item.name === store.editableTabsValue)
    //关闭右侧tab页
    store.editableTabs.splice(currentIndex + 1)
    //删除对应的右侧历史路由
    store.tabRouterList.splice(currentIndex + 1)
    //如果当前关闭点击的tab页包含激活的tab页,则将激活tab页重置为当前点击的tab
    if (activeIndex > currentIndex) {
      //将当前激活的tab页改为当前点击的
      store.updateState(['editableTabsValue', targetName])
      //将激活菜单改为当前点击的
      store.updateState(['activeMenu', targetName])
      //路由跳转到当前点击的tab页
      //查询当前点击的tab页缓存路由参数
      let result = store.tabRouterList.find(item => item.path === targetName);
      //路由跳转且带上对应tab页的参数
      router.push({ path: targetName, query: result.query })
    }
  }

  //关闭其他tab页
  const closeOther = (targetName) => {
    //查找当前点击的tab页所在位置
    let currentIndex = store.editableTabs.findIndex(
        (item) => item.name === targetName
    )
    //关闭其他标签页
    store.editableTabs = [store.editableTabs[currentIndex]]
    //删除除当前点击外的历史路由
    store.tabRouterList = [store.tabRouterList[currentIndex]]
    //如果当前点击的不等于当前激活的
    if (targetName !== store.editableTabsValue) {
      //将当前激活的tab页改为当前点击的
      store.updateState(['editableTabsValue', targetName])
      //将激活菜单改为当前点击的
      store.updateState(['activeMenu', targetName])
      //路由跳转到当前点击的tab页
      //查询当前点击的tab页缓存路由参数
      let result = store.tabRouterList.find(item => item.path === targetName);
      //路由跳转且带上对应tab页的参数
      router.push({ path: targetName, query: result.query })
    }
  }

  //关闭全部tab页
  const closeAll = () => {
    //清空tabs数组
    store.editableTabs.length = 0
    //清空历史路由
    store.tabRouterList.length = 0
    //当前选中tab页设置为空
    store.updateState(['editableTabsValue', ''])
    //当前激活菜单设置为空
    store.updateState(['activeMenu', ''])
    //跳转到首页
    router.push('home')
  }

  //处理tab标签x按钮的移除
  function handleTabRemove(targetName) {
    //如果editableTabs列表不为空数组
    if (store.editableTabs.length > 0) {
      //如果当前所在的tab页路由地址与移除的tab页名一样,则移到前面一个tab页且路由跳转
      if (route.path === targetName) {
        let tabs = store.editableTabs
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            //获取当前tab的后一个或者前一个
            let nextTab = tabs[index + 1] || tabs[index - 1]
            //如果有值就移到它上面,没有就是最后一个跳转到首页
            if (nextTab) {
              //根据name属性进行查询当前tab页的缓存路由参数
              let result = store.tabRouterList.find(item => item.path === nextTab.name);
              //路由跳转且带上对应tab页的参数
              router.push({ path: nextTab.name, query: result.query })
            } else {
              // 更改tab标签绑定值,选中选项卡的name
              store.updateState(['editableTabsValue', ''])
              // 更改当前激活的菜单
              store.updateState(['activeMenu', ''])
              //当删除的是最后一个tab页的时候,跳转到首页
              router.push('home')
            }
          }
        })
        //从editableTabs中移除当前tab标签
        store.removeTab(targetName)
      } else {
        //从editableTabs中移除当前tab标签
        store.removeTab(targetName)
      }
    }
  }

  //tab标签被选中时触发的事件
  function handleTabClick(tab) {
    store.updateState(['activeMenu', tab.props.name])
    store.updateState(['editableTabsValue', tab.props.name])
    // 判断当前url地址和即将跳转的是否一致,不一致进行跳转,防止跳转多次
    if (tab.props.name !== route.path) {
      // 根据name属性进行查询
      let result = store.tabRouterList.find(item => item.path === tab.props.name);
      //路由跳转且带上对应tab页的参数
      router.push({ path: tab.props.name, query: result.query })
    }
  }

  //页面刷新时,保留当前语言类型,不然会被重置为默认语言中文
  function setLanguage(){
    //如果sessionStorage里面的language为en,则表示要切换到英文语言。否则为中文。
    if(store.language==="en"){
      //将语言切换为英文
      locale.value='en'
    }else {
      //将语言切换为中文
      locale.value='zh'
    }
  }

  //页面初始化时调用语言方法
  setLanguage()

  //中英文语言切换
  function languageSwitch(){
    //如果sessionStorage里面的language为en,则表示要切换到中文语言。否则为英文。
    if(store.language==="en"){
      //将语言切换为中文
      locale.value='zh'
      //将language设置为zh中文
      store.language='zh'
    }else {
      //将语言切换为英文
      locale.value='en'
      //将language设置为zh中文
      store.language='en'
    }
    //语言切换后延迟刷新页面
    setTimeout(() => {
      window.location.reload()
    }, 300)
  }

  //退出登录方法
  function logout() {

  }
</script>

<style lang="less" scoped>
  //设置高度
  :deep(.el-tabs__nav-scroll) {
    height: 60px;
  }

  //去掉el-tabs的边框
  :deep(.el-tabs) {
    border: none;
  }

  .header {
    height: 62px;
    position: absolute;
    right: 30px;
    top: 0px;
    z-index: 1; //不设置这个,el-down点击出不来,被tab标签页长度挡住了
    display: flex;
    align-items: center; //垂直居中
  }

  //tab标签页里面字体设置
  .label {
    color: #1B68B6 !important; //激活标签页高亮
    font-size: 16px;
  }

  :deep(.el-tabs__item) {
    &:hover {
      span {
        color: #1B68B6 !important; //鼠标移到标签页高亮
      }
    }
  }
  .language{
    cursor: pointer;
    margin-right: 20px;
    color: #49A1F3;
    font: 14px 微软雅黑 宋体;
  }
</style>

src/locale/language/en.js文件代码如下:

export default {
  en: {
    username: 'Admin',
    home: 'I am home',
    tip: 'request error'
  }
}

src/locale/language/zh.js文件代码如下:

export default {
  zh: {
    username: '超级管理员',
    home: '我是首页',
    tip: '请求失败'
  }
}

src/views/home/index.vue首页文件代码如下,这里只对首页里面的内容做中英文切换,用来测试是否可以实现:

<!--home首页代码-->
<template>
  <!--对页面内容进行中英文切换-->
  <div>{{ $t("home") }}</div>
</template>

<script setup name="home">
import {login} from '@/api/login'
import { useI18n } from "vue-i18n"

//使用useI18n
const { t } = useI18n()

const data={username:"test111",password:"123456"}

login(data).then( res => {
  console.info("请求成功")
}).catch(err => {
  console.info("请求失败,",err)
  //在js里面对提示进行中英文切换
  alert(t('tip'))
})

</script>

<style lang="less" scoped>

</style>

测试中英文切换

谷歌浏览器页面效果如下:
在这里插入图片描述
点击English按钮后切换为英文效果如下:
在这里插入图片描述

对ElementPlus里面的所有组件进行中英文切换

main.js代码如下:

import { createApp } from 'vue'
//引入element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
//将element-plus里面默认语言英文改为中文,需要引入它
import zhCn from 'element-plus/dist/locale/zh-cn'
//element-plus组件全局样式和html全局样式引入
import './styles/element-plus.less'
import './styles/common.less'
//引入dayjs日期插件
import dayjs from 'dayjs'
//引入国际化配置
import lang from './locale'
//引入router路由
import router from './router'
//引入pinia状态管理
import pinia from './store'
//引入svg-icons
import 'virtual:svg-icons-register'
import App from './App.vue'

const app = createApp(App)
//使用element-plus,并设置语言为中文
app.use(ElementPlus, {
  locale: zhCn,
})
//通过provide全局注入工具函数
app.provide('$dayjs', dayjs)
//国际化配置使用
app.use(lang)
//使用router路由
app.use(router)
//使用pinia状态管理
app.use(pinia)
app.mount('#app')

src/App.vue文件代码如下:

<template>
  <div>
  	<!--在路由入口这里使用ElConfigProvider对ElementPlus组件进行中英文切换-->
    <el-config-provider :locale="locale">
      <!--路由入口 在App.vue中使用<router-view>组件来渲染要显示的组件-->
      <router-view/>
    </el-config-provider>
  </div>
</template>

<script setup name="App">
  import { reactive } from 'vue'
  import { ElConfigProvider } from 'element-plus'
  import zhCn from 'element-plus/es/locale/lang/zh-cn'
  //引入全局状态里面的关于菜单栏列表数据和相关方法
  import useUserStore from '@/store/modules/userStore'

  //接手全局状态里面的属性和方法
  const store = useUserStore()

  //将ElementPlus里面的组件进行中英文切换
  const { locale } = reactive({
    locale: store.language==='en'?'':zhCn
  })
</script>

<style scoped>

</style>

src/views/home/index.vue首页文件代码如下,这里对日期选择器控件进行中英文切换测试:

<!--home首页代码-->
<template>
  <!--对ElementPlus里面的组件进行中英文切换-->
  <el-date-picker type="date"/>
  <!--对页面内容进行中英文切换-->
  <div>{{ $t("home") }}</div>
</template>

<script setup name="home">
import {login} from '@/api/login'
import { useI18n } from "vue-i18n"

//使用useI18n
const { t } = useI18n()

const data={username:"test111",password:"123456"}

login(data).then( res => {
  console.info("请求成功")
}).catch(err => {
  console.info("请求失败,",err)
  //在js里面对提示进行中英文切换
  alert(t('tip'))
})

</script>

<style lang="less" scoped>

</style>

谷歌浏览器效果如下:
日期选择器中文效果如下:
在这里插入图片描述
语言切换为英文后效果如下:
在这里插入图片描述
好了,到这里vue-i18n国际化配置应该是可以直接到项目中直接实际使用了。又进步了一点点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1644494.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

stm32单片机开发五、I2C通信

I2C这部分的时序单元可以看我另外一篇博客I2C基本知识 I2C发送数据时是高位先行&#xff0c;也就是先发送高位的&#xff0c;比如一个字节有8位B0-B7&#xff0c;先发送B7高位 I2C用的是同步时序&#xff0c;它有一个好处&#xff0c;比如传输过程中&#xff0c;出现了中断&…

深度学习之基于Pytorch姿态估计的仰卧起坐计数系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 仰卧起坐作为一种常见的健身动作&#xff0c;被广泛用于腹部肌肉的锻炼。然而&#xff0c;对于仰卧起…

(四)机器学习在银行中的典型应用场景(模型) #CDA学习打卡

本文总结了机器学习在银行中的典型业务应用场景&#xff0c;包括客户管理、零售智能营销、公司智能营销、自然语言处理、运营管理以及图像识别。

智慧园区sip对讲广播解决方案

智慧园区sip对讲广播解决方案18123651365 目前而言智慧园区管理者主要需要解决的问题是&#xff1a; 1.面对庞大的园区小区规模&#xff0c;能源管理全部依赖人工已经无法实现&#xff1b; 2.节能管理工作难度大&#xff0c;面对问题&#xff0c;没有好的解决方案&#xff1b; …

pyqt6的安装,使用-1

pyqt6安装的话&#xff0c;在自己所用的环境里安就可以&#xff0c;之前写有yolov5,yolov8的环境配置&#xff0c;python3.8的我安装就没有问题&#xff0c;打开anaconda&#xff0c;激活自己的环境 把这复制进去 pip install pyqt6 pip install pyqt6-tools 这个安装完了之后…

【JavaWeb】网上蛋糕项目商城-关键字搜索,购物车以及商品详情功能

概念 上文中已经实现热销和新品的商品列表功能&#xff0c;本文篇幅中实现关键字搜索商品&#xff0c;将商品加入购物车&#xff0c;以及查看商品的详情信息等功能 关键字搜索实现步骤 在head.jsp头部页面中&#xff0c;鼠标移动至搜索图标会显示隐藏的搜索框进行输入关键信…

数据结构(C):玩转链表

&#x1f37a;0.前言 言C之言&#xff0c;聊C之识&#xff0c;以C会友&#xff0c;共向远方。各位博友的各位你们好啊&#xff0c;这里是持续分享数据结构知识的小赵同学&#xff0c;今天要分享的数据结构知识是链表&#xff0c;在这一章&#xff0c;小赵将会向大家展开聊聊链表…

c语言排序算法之八(桶排序)

前言 以下内容是被验证可以有效理解桶排序&#xff0c;代码也较容易理解。如果你发现还有很多需要增加的&#xff0c;欢迎留言。 为什么要单独写排序算法这一系列&#xff0c;看过一些贴子普遍篇幅较长。看完依旧难以直观理解原理及整个过程。代码永远是基于理解的基础上才能…

Carla基础 | Carla预编译版安装与ROS联合仿真图文教程

目录 1 什么是Carla&#xff1f;2 Carla预编译版安装2.1 独立显卡配置2.2 安装ROS2.3 启动虚拟环境2.4 安装Carla预编译版2.5 安装carla-ros-bridge 3 测试案例常见问题 1 什么是Carla&#xff1f; Carla是由西班牙巴塞罗那自治大学计算机视觉中心指导开发的开源仿真模拟器&…

Redis-五大数据类型-Set(集合)

五大数据类型-Set&#xff08;集合&#xff09; 简介 与List类似是一个列表功能&#xff0c;但Set是自动排重的&#xff0c;当需要存储一个列表数据&#xff0c;又不希望出现重复数据时&#xff0c;Set是一个很好的选择。 Set是String类型的无序集合&#xff0c;它底层其实是…

学生宿舍智能电表系统改造升级意义

石家庄光大远通电气有限公司学生宿舍智能电表控制系统改造升级功能与意义** 一、实时监测 宿舍智能电表控制系统具备实时监测功能&#xff0c;能够实时收集、记录和分析每个宿舍的用电数据。这种监测不仅可以帮助管理者掌握用电情况&#xff0c;还可以为用户提供详细的用电报…

重生奇迹mu魔剑士怎么转职

重生奇迹MU中的魔剑士怎么才可以转职? 随便建个角色升级到220级&#xff0c;然后小退重建就有魔剑士了。另外魔剑不用二转。400的三转和其他职业一样。 战士不能转魔剑的。当帐号中已经拥有一位等级超过220级以上的角色时&#xff0c;才可以创造职业为魔剑士的新角色。 魔剑…

gcc编译器分析

gcc编译器分析 参考词法分析语法分析预读一个符号语法分析函数调用关系重点函数分析c_parse_filec_parser_translation_unit 参考 《gcc源码分析》 词法分析 词法分析的过程就是将源代码识别成一个一个的词法符号&#xff0c;并在词法分析的过程中创建一些树节点&#xff0c…

YashanDB与帆软信创商业智能软件完成兼容互认证

近日&#xff0c;深圳计算科学研究院崖山数据库系统YashanDB与帆软信创商业智能软件&#xff08;V6.0&#xff09;顺利完成兼容性互认证&#xff0c;经严格测试&#xff0c;双方产品能够相互兼容&#xff0c;稳定运行。 崖山数据库系统YashanDB是深圳计算科学研究院自主研发设计…

一分钱不花从HTTP升级到HTTPS

HTTP升级到HTTPS是一个涉及安全性和技术实施的过程&#xff0c;主要目的是为了提升网站数据传输的安全性&#xff0c;防止数据被窃取或篡改。以下是一些关于从HTTP升级到HTTPS的技术性要点和步骤概述&#xff0c;结合上述信息资源&#xff1a; 一、理解HTTPS的重要性 HTTPS (…

[图解]SysML和EA建模住宅安全系统-01

1 00:00:00,980 --> 00:00:03,100 接下来&#xff0c;我们来看一下案例 2 00:00:04,930 --> 00:00:06,750 我们这次课程的案例 3 00:00:07,090 --> 00:00:13,800 选用了SysML实用指南的书上 4 00:00:13,810 --> 00:00:16,180 第十七章这个案例 5 00:00:16,350 …

《QT实用小工具·五十六》自适应界面变化的控件

1、概述 源码放在文章末尾 该项目实现了网格显示多张带文字的图片在界面中自适应布局 特点 跟随窗口大小变换位置&#xff0c;并带移动动画 响应鼠标事件&#xff0c;图片缩放动画 点击水波纹动画 项目demo演示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #i…

​可视化大屏C位图:3D模型,可视化大屏的画龙点睛之处

Hello&#xff0c;我是大千UI工场&#xff0c;本期可视化大屏的焦点图&#xff08;C位&#xff09;分享将图表作为焦点图的情形&#xff0c;欢迎友友们关注、评论&#xff0c;如果有订单可私信。 3D模型在可视化大屏中有很大的价值&#xff0c;以下是一些相关的优点&#xff1a…

优优嗨聚集团:法律明灯,个债处理中的法律咨询力量

在现代社会&#xff0c;个人债务问题日益突出&#xff0c;无论是因生活消费、投资失利还是其他原因&#xff0c;债务问题都可能成为个人财务的一大负担。面对复杂的债务困境&#xff0c;许多人感到迷茫和无助。此时&#xff0c;法律咨询如同一盏明灯&#xff0c;能够为个人债务…

GEE数据集——全球冰川海拔变化产品(2000-2019 年)

全球冰川海拔变化产品&#xff08;2000-2019 年&#xff09; 该数据集提供了 2000 年至 2019 年期间冰川海拔和质量变化的全面且全球一致的记录。它利用大量卫星图像&#xff08;主要来自美国国家航空航天局&#xff08;NASA&#xff09;的高级星载热发射和反射辐射计&#xf…