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

vue3 脚手架初始化项目生成文件的介绍

在这里插入图片描述

文章目录

  • 一、介绍
  • 二、举例说明
    • 1.src/http/index.js
    • 2.src/router/index.js
    • 3.src/router/routes.js
    • 4.src/stores/index.js
    • 5.src/App.vue
    • 6.src/main.js
    • 7.babel.config.js
    • 8.jsconfig.json
    • 9.vue.config.js
    • 10. .env
    • 11.src/mock/index.js
    • 12.src/mock/mock-i18n.js
    • 13.src/locales/en.json
    • 14.src/locales/zh.json
    • 15.src/locales/index.js
    • 16.src/views/pages/system/system.js
    • 17. .gitignore
    • 18.package.json

一、介绍

  • node_modules文件夹:项目依赖文件夹
  • public文件夹:一般放置一些静态资源(图片),需要注意,放在public文件夹中的静态资源,在webpack打包时,会原封不动的打包到dist文件夹中。
  • src文件夹(程序员源代码文件夹):
    • assets文件夹:一般也是放置静态资源(一般放置多个组件共用的静态资源),需要注意,放在assets文件夹里的静态资源,在webpack打包时,会把此静态资源当作一个模块,打包到JS文件中。
    • components文件夹:一般放置非路由组件(全局组件)。
    • http文件夹:
      • index.js:集中管理 HTTP 请求的配置和处理逻辑,使得在应用中发送 HTTP 请求变得更加简单和一致。通过使用 Axios 实例和拦截器,可以有效地管理请求和响应,处理身份验证和错误情况,确保用户体验的流畅性。
    • App.vue文件:唯一的根组件。
    • main.js文件:程序的入口文件,也是整个程序当中最先执行的文件。
    • pages|views文件夹:路由组件。
    • router文件夹:路由相关配置。
      • index.js:配置路由
      • routes.js:路由规则定义(该文件夹可有可无,可全部放在上面index.js中)
    • store文件夹:
      • index.js:vuex相关配置。
    • utils文件夹:该文件夹里面经常放一些常用的功能模块,比如正则、临时身份UUID等等。
    • locales:
      • en.json:英文词条
      • zh.json:中文词条
      • index.js:国际化相关配置
    • mock文件夹:模拟json文件及相关接口调用
      • index.js:是一个用于模拟 API 响应的模块,通常在前端开发中使用。它利用 mockjs 库来创建虚拟的 API 接口,以便在开发和测试过程中不依赖于后端服务。以下是这个文件的主要功能和组成部分。
      • mock-i18n.js:模拟的词条文件。
  • babel.config.js文件:babel配置文件(bable相关)。
  • package.json文件:相当于项目的“身份证”,记录了项目的相关信息(如名字、依赖、运行方式等等)。
  • package-lock.json文件:又叫“缓存性文件”,跟踪被安装的每个软件包的确切版本,以便产品可以以相同的方式被 100% 复制(即使软件包的维护者更新了软件包)。即为什么刚开始启动慢,而后面启动就很快?因为缓存性文件都记录下来相关信息了,所以后续启动很快。
  • README.md文件:项目的说明性文件
  • vue.config.js文件:用于关闭ESLINT校验工具+配置代理服务器解决跨域
  • jsconfig.json文件:给src文件夹简写方法,配置别名,方便引入资源

在这里插入图片描述
在这里插入图片描述

二、举例说明

1.src/http/index.js

/**
 * @Name:
 * @Author:贾志博
 * @description:
 */
import axios, { AxiosInstance, AxiosResponse } from "axios";
import {useStore} from "@/stores";

// 创建http请求的实例对象
const $http = axios.create({
  timeout: 30000,
  withCredentials: false,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8',
    'Access-Control-Allow-Origin': '*',
    'X-Requested-With': 'XMLHttpRequest'
  }
});


// 添加请求拦截器
// $http.interceptors.request.use((config) => {
//   const token = ''
//   if (token) {
//     config.headers.Authorization = token;
//   }
//   return config;
// }, (error) => {
//   return Promise.reject(error)
// });

// 添加响应拦截器
$http.interceptors.response.use(
  response=> {
    const { data } = response
    if (response.status === 200) {
      return data
    }
  },
  error => {
      if (error.status === 401) {
          sessionStorage.removeItem('principal');
          localStorage.removeItem('mldn-session-id')
        // 路由跳转到登录界面
        window.location.href = `${window.location.origin}/#/`
      } else if (error.status == 502) {
          sessionStorage.removeItem('principal');
          localStorage.removeItem('mldn-session-id')
        window.location.href = `${window.location.origin}/#/`
    }
      return Promise.resolve({code: error.status})
  }
);


const Method = {
  GET: 'get',
  POST: 'post',
  DELETE: 'delete',
  PUT: 'put',
}

export { $http,  Method };

2.src/router/index.js

import { createRouter, createWebHashHistory } from 'vue-router'
import { baseRoutes, routes } from "./routes";
import { useStore } from "@/stores";
import {queryUserMenu} from "@/views/pages/system/system";
import { commonResponse } from "@/views/pages/_common";
import { getSystemType } from "@/views/login/_request";

const router = createRouter({
  history: createWebHashHistory(process.env.BASE_URL),
  routes: baseRoutes
})
let permissionRoutes = []
let permissionMap = new Map()

router.beforeEach((to, from, next) => {
  var principal = localStorage.getItem('mldn-session-id');
  var session_prncipal = sessionStorage.getItem('principal');
  const userName = localStorage.getItem("xnms-user-name");
  if (session_prncipal == null && principal == null) {
    principal = null;
  }

  if (principal == null) {
    if (to.name === 'login') {
      useStore().hasAuth = false;
      next()
    } else {
      useStore().hasAuth = false;
      next({
        name: 'login'
      })
    }
  } else if (to.name === 'login') {
    if(permissionRoutes.length > 0) {
      const initRouterPush = "/pages/" + permissionRoutes[0].path + "/" + permissionRoutes[0].children[0].path;
      useStore().setSelectedMenuKeyFunction(permissionRoutes[0].path)
      useStore().setSelectedMenuItemKeyFunction([permissionRoutes[0].path + "_" + permissionRoutes[0].children[0].path]);
      useStore().setOpenMenuItemFunction([permissionRoutes[0].path]);
      next({path: initRouterPush, replace: true});
    } else {
      hasAuthHandle(to, next, userName);
    }
  } else {
    hasAuthHandle(to, next, userName);
  }
});

const hasAuthHandle = (to, next, userName) => {
  if(!useStore().hasAuth) {
    getSystemType().then(resp => {
      localStorage.setItem('system-type', resp.data)
      useStore().setMode(resp.data)
      queryUserMenu(userName).then(response => {
        commonResponse({
          response,
          onSuccess: () => {
            permissionRoutes = []
            permissionMap = new Map()
            try {
              const deepRoutes =  JSON.parse(JSON.stringify(routes));
              fillPermissionMap(permissionMap, response)
              permissionRoutes = handleRoutes(deepRoutes, permissionMap)
              if (permissionRoutes.length > 0) {
                useStore().routes.value = permissionRoutes
                permissionRoutes.forEach(item => {
                  router.addRoute('pages', item)
                })
              }
            } catch (error) {
              console.error("Error during deep copy:", error);
            }
            useStore().hasAuth = true
            // 检查 to 是否在动态加载的路由里
            const isRouteExists = permissionRoutes.some(route => {
              if (route.name === to.name || route.path === to.path) {
                return true;
              }
              if (route.children) {
                return route.children.some(childRoute => {
                  return childRoute.name === to.name || childRoute.path === to.path;
                });
              }
              return false;
            });

            if (isRouteExists) {
              next({...to, replace: true})
            } else {
              // 如果 to 不在动态路由里,可以导航到默认页面
              if (permissionRoutes.length > 0) {
                const initRouterPush = "/pages/" + permissionRoutes[0].path + "/" + permissionRoutes[0].children[0].path;
                useStore().setSelectedMenuKeyFunction(permissionRoutes[0].path)
                useStore().setSelectedMenuItemKeyFunction([permissionRoutes[0].path + "_" + permissionRoutes[0].children[0].path]);
                useStore().setOpenMenuItemFunction([permissionRoutes[0].path]);
                next({path: initRouterPush, replace: true});
              }
            }
          }
        })
      })
    })
  } else {
    next()
  }
}

const fillPermissionMap = (permissionMap, response) => {
  const userName = localStorage.getItem('xnms-user-name')
  if (userName == "Admin") {
    response.data?.forEach(item => {
      const { code, canLook, canEdit } = item;
      permissionMap.set(code, {
        view: canLook == true ? 1 : 0,
        edit: canEdit == true ? 1 : 0
      })
    })
  } else {
    response.data?.forEach(item => {
      const { code, canLook, canEdit } = item;
      if (code.length === 4) {
        permissionMap.set(code, {
          view: canLook == true ? 1 : 0,
          edit: canEdit == true ? 1 : 0
        })
      }
    })

    response.data?.forEach(item => {
      const { code} = item;

      if (code.length === 2) {
        const children = response.data.filter(child => child.pid === code);
        const hasViewVisibleChild = children.some(child => child.canLook === 1);
        const hasEditVisibleChild = children.some(child => child.canEdit === 1);
        permissionMap.set(code, {
          view: hasViewVisibleChild ? 1 : 0,
          edit: hasEditVisibleChild ? 1 : 0
        });
      }
    })
  }
}

const handleRoutes = (routes, permissionMap) => {
  for (let i = 0; i < routes.length; i++) {
    const item = routes[i]
    if (permissionMap?.get(routes[i].meta.key)?.view) {
      routes[i].meta.edit = permissionMap?.get(routes[i].meta.key)?.edit
      if (item.children?.length) {
        handleRoutes(item.children, permissionMap)
      } else {
        if (!item.component) {
          let fileExistCommon = true
          let pathStr = ''
          try {
            const path = item.name.split('_')
            pathStr = path.reduce((pre, cur, index) => {
              return `${pre}/${index === path.length - 1 ? cur.charAt(0).toUpperCase() + cur.slice(1) : cur}`
            })
            require(`@/views/pages/${pathStr}.vue`)
          } catch (e) {
            fileExistCommon = false
          }
          let fileExistDiff = true
          const modeName = useStore().getMode() ? 'XPT' : 'NOR'
          try {
            require(`@/views/pages/${pathStr}-${modeName}.vue`)
          } catch (e) {
            fileExistDiff = false
          }
          if (fileExistDiff) {
            item.component = () => import(`@/views/pages/${pathStr}-${modeName}.vue`)
          } else if (fileExistCommon) {
            item.component = () => import(`@/views/pages/${pathStr}.vue`)
          } else {
            item.component = () => import('@/views/pages/_error/404.vue')
          }
        }
      }
    } else {
      routes.splice(i, 1)
      i--
    }
  }
  return routes
}

export default router

3.src/router/routes.js

import Login from "@/views/login/index.vue";
import Index from "@/views/pages/index.vue";

export const baseRoutes = [
  {
    path: '/',
    name: 'login',
    component: Login,
  },
  {
    path: '/pages',
    name: 'pages',
    component: Index,
    children: []
  }
]

export const routes = [
  {
    path: 'topology',
    name: 'topology',
    meta: {
      key: '00'
    },
    children: [
      {
        path: 'topologyView',
        name: 'topology_topologyView',
        breadcrumb: 'menu_topoView',
        meta: {
          key: '0000'
        },
      },
      {
        path: 'electronicMap',
        name: 'topology_electronicMap',
        breadcrumb: 'menu_electronicMap',
        meta: {
          key: '0001'
        },
      },
    ]
  }
]

4.src/stores/index.js

import {defineStore} from "pinia";
import {ref} from 'vue'

export const useStore = defineStore('main', () => {
  const mode = ref(0)
  const setMode = (modeVal) => {
    mode.value = modeVal
  }
  const getMode = () => {
    return mode.value
  }

  const openMenuItem = ref([]);
  const setOpenMenuItemFunction = (modeVal) => {
    openMenuItem.value = modeVal
  }
  const getOpenMenuItemFunction = () => {
    return openMenuItem
  }


  const selectedMenuItemKey = ref(null);
  const setSelectedMenuItemKeyFunction = (modeVal) => {
    selectedMenuItemKey.value = modeVal
  }
  const getSelectedMenuItemKeyFunction = () => {
    return selectedMenuItemKey
  }

  const selectedMenuKey = ref("");
  const setSelectedMenuKeyFunction = (modeVal) => {
    selectedMenuKey.value = modeVal
  }
  const getSelectedMenuKeyFunction = () => {
    return selectedMenuKey
  }


  const hasAuth = ref(false)
  const routes = ref([])
  const popoverVisible = ref(false);
  const popoverPosition = ref({ top: 0, left: 0 });
  const selectTopoNode = ref(null)
  const websocketRepeaterList = ref([])

  return {
    getMode,
    setMode,
    setSelectedMenuKeyFunction,
    getSelectedMenuKeyFunction,
    setSelectedMenuItemKeyFunction,
    getSelectedMenuItemKeyFunction,
    setOpenMenuItemFunction,
    getOpenMenuItemFunction,
    hasAuth,
    routes,
    popoverVisible,
    popoverPosition,
    selectTopoNode,
    websocketRepeaterList,
  }
})

使用方式:在其他xx.vue页面中

import { useStore } from "@/stores";

useStore().hasAuth = false;

5.src/App.vue

<template>
  <router-view/>
</template>

<script setup>
import {reactive, provide} from "vue";
import {useI18n} from "vue-i18n";
import {useStore} from "@/stores";
import {getSystemLanguage} from "@/views/pages/system/system";
const userInfo = reactive({
  userId: '',
  token: ''
})
provide('t', useI18n().t)
provide('userInfo', userInfo)

const getSystemMode = () => {
  getSystemLanguage().then(response => {
    const mode = response.data
    if (mode) {
      localStorage.setItem('xnms-mode', mode)
      useStore().setMode(parseInt(mode))
    }
  })
}

getSystemMode()
</script>

<style>
</style>

6.src/main.js

import { createApp } from 'vue';
import App from './App.vue';
import { createPinia } from "pinia";
// import getRouter from '@/router';
import router from '@/router'
import getI18n from '@/locales';
import SelfComponents from "@/views/pages/_common/selfComponents/index";
import ArcoVue, {Message} from '@arco-design/web-vue';
import ArcoVueIcon from '@arco-design/web-vue/es/icon';
import '@arco-design/web-vue/dist/arco.css';
import '@/assets/index.less';
window.Message = Message
if (process.env.NODE_ENV === 'development') {
  // import('@/mock')
}

const store = createPinia()

const promise = Promise.all([getI18n()])
const _beforeMount = await promise
// window.i18n = _beforeMount[0]

const app = createApp(App)
app
  .use(_beforeMount[0])
  .use(router)
  .use(ArcoVue)
  .use(ArcoVueIcon)
  .use(store)
  .use(SelfComponents)
app.mount('#app')

7.babel.config.js

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}

8.jsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "baseUrl": "./",
    "moduleResolution": "node",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  }
}

9.vue.config.js

const { defineConfig } = require('@vue/cli-service')
const path = require('path')
// const target = 'http://127.0.0.1:61000/'
// const target = 'http://10.110.24.117:62000/'
const target = 'http://10.110.24.62:61000/'
module.exports = defineConfig({
  // publicPath: process.env.NODE_ENV === 'development' ? '' : '/XNMS',
  transpileDependencies: true,
  lintOnSave: false,
  assetsDir: 'assets',
  devServer: {
    proxy: {
      '/api': {
        target,
        changeOrigin: true,
      },
    }
  },
  pluginOptions: {
    i18n: {
      locale: 'en',
      fallbackLocale: 'en',
      localeDir: 'locales',
      enableLegacy: false,
      runtimeOnly: false,
      compositionOnly: false,
      fullInstall: true
    }
  },
  chainWebpack: config => {
    config.module.rule('svg')
      .exclude.add(path.resolve('src/assets/svg'))
    config.module.rule('icons')
      .test(/\.svg$/)
      .include.add(path.resolve('src/assets/svg')).end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({ symbolId: 'icon-[name]' })

  }
})

10. .env

VUE_APP_I18N_LOCALE=en
VUE_APP_I18N_FALLBACK_LOCALE=en

11.src/mock/index.js

import Mock from 'mockjs'
import {i18nList} from './mock-i18n'

Mock.mock('/menu/list', 'get', {
  status: 0,
  dataList: [
    {
      path: 'topology',
      children: [
        {
          path: 'topologyView',
          name: 'topology_topologyView',
        },
        {
          path: 'electronicMap',
          name: 'topology_electronicMap',
        },
      ]
    }
  ]
})

Mock.mock('/api/in', 'get', {
  code: 200,
  data: 1,
  msg: "成功",
  pagination: null
})

Mock.mock(/^\/api\/in\/[\S]*$/, 'get', {
  code: 200,
  msg: '',
  data: {
    ...i18nList()
  }
})

Mock.mock('/api/site_statistic', 'post', {
  "code": 200,
  "data": [
    {
      "businessData": {
        "datas": {
          "additionalProp1": 1,
          "additionalProp2": 2,
          "additionalProp3": 3,
          "additionalProp4": 4,
          "additionalProp5": 5
        },
      },
      "siteData": {
        "datas": {
          "additionalProp1": 1,
          "additionalProp2": 2,
          "additionalProp3": 3,
          "additionalProp4": 4,
          "additionalProp5": 5
        },
      },
      "siteID": 1,
      "siteAlias": "站点1",
    },
    {
      "businessData": {
        "datas": {
          "additionalProp1": 1,
          "additionalProp2": 2,
          "additionalProp3": 3,
          "additionalProp4": 4,
          "additionalProp5": 5
        },
      },
      "siteData": {
        "datas": {
          "additionalProp1": 1,
          "additionalProp2": 2,
          "additionalProp3": 3,
          "additionalProp4": 4,
          "additionalProp5": 5
        },
      },
      "siteID": 2,
      "siteAlias": "站点2",
    }
  ],
  "msg": "string",
  "pagination": {
    "currentPage": 0,
    "pageSize": 0,
    "totalPages": 0,
    "totalRecords": 0
  }
})

Mock.mock('/api/getTransferBusinessData', 'post', {
  code: 200,
  data: [
    {
      id: '1',
      name: '站点1',
      byDateLine: [{
        date: '2021-01-01',
        value1: 1,
        value2: 2
      }, {
        date: '2021-01-02',
        value1: 3,
        value2: 4
      }, {
        date: '2021-01-04',
        value1: 3,
        value2: 6
      }],
      byBusinessTimePie: {
        1: 2,
        2: 4,
        3: 6,
        4: 1,
        5: 3
      },
      byTimeLine: [{
        date: '2021-01-01',
        value1: 1,
        value2: 2
      }, {
        date: '2021-01-02',
        value1: 3,
        value2: 4
      }, {
        date: '2021-01-04',
        value1: 3,
        value2: 6
      }],
    },
    {
      id: '2',
      name: '站点2',
      byDateLine: [{
        date: '2021-01-01',
        value1: 1,
        value2: 2
      }, {
        date: '2021-01-02',
        value1: 3,
        value2: 4
      }, {
        date: '2021-01-04',
     ],
    }
  ]
})

12.src/mock/mock-i18n.js

export const i18nList = () => {
  return {
    "Title": "XNMS客户端",
    "XPTTitle": "XNMS",
    "Login": "登  录",
    "LoginCancel": "取消登录",
    "LoginCheckPassword": "验证中…",
      }
}

13.src/locales/en.json

{
  "menu_topology": "Topology View",
  "menu_alarm": "Monitoring Alarm",
  "menu_device": "Equipment Parameters",
  "menu_data": "Data Query",
  "menu_business": "Business Statistics",
}

14.src/locales/zh.json

{
  "menu_topology": "拓扑展示",
  "menu_alarm": "监控告警",
  "menu_device": "设备参数",
  "menu_data": "数据查询",
  "menu_business": "业务统计",
}

15.src/locales/index.js

import { createI18n } from 'vue-i18n'
import {getI18nLanguagePkg, getNowLanguageType} from "@/views/login/_request";

const getNowLanguage = async () => {
  return new Promise((resolve, reject) => {
    getNowLanguageType().then(response => {
      if (response.code === 200) {
        resolve(response.data)
      } else {
        window.Message.warning(response.msg)
      }
    })
  })
}

const loadRemoteMessages = async (language) => {
  return new Promise((resolve, reject) => {
    getI18nLanguagePkg(language).then(response => {
      if (response.code === 200) {
        const messages = {}
        messages[languageEnum[language]] = response.data
        resolve(messages)
      } else {
        window.Message.warning(response.msg)
      }
    })
  })
}

const getI18n = async () => {
  const language = await getNowLanguage()
  localStorage.setItem('xnms-language', language)
  const remoteMessages = await loadRemoteMessages(language)
  const i18n = createI18n({
    legacy: false,
    locale: languageEnum[language],
    fallbackLocale: 'zh',
    messages: remoteMessages,
    globalInjection: true
  })
  return new Promise((resolve) => {
    resolve(i18n)
  })
}

const languageEnum = {
  0: 'en',
  1: 'zh',
  2: 'ru'
}

export default getI18n

16.src/views/pages/system/system.js

import { $http, Method } from "@/http";

export const getDeviceManageList = (data) => {
  return $http({
    url: `/api/deviceManage/queryDeviceList`,
    method: Method.POST,
    data
  })
}

export const getSystemLanguage = (data) => {
  return $http({
    url: `/api/config`,
    method: Method.GET,
    data
  })
}

export const deleteDevice = (data) => {
  return $http({
    url: `/api/deviceManage/deleteRepeater`,
    method: Method.DELETE,
    data
  })
}

export const updateDevive = (data) => {
  return $http({
    url: `/api/deviceManage/updateDeviceSnmpV3`,
    method: Method.PUT,
    data
  })
}

17. .gitignore

.DS_Store
node_modules
/dist


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

18.package.json

{
  "name": "xnms",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "i18n:report": "vue-cli-service i18n:report --src \"./src/**/*.?(js|vue)\" --locales \"./src/locales/**/*.json\""
  },
  "dependencies": {
    "axios": "^1.7.7",
    "core-js": "^3.8.3",
    "echarts": "^5.5.1",
    "html2canvas": "^1.4.1",
    "jspdf": "^3.0.0",
    "leaflet": "^1.9.4",
    "leaflet-polylinedecorator": "^1.6.0",
    "less": "^4.2.0",
    "less-loader": "^12.2.0",
    "mockjs": "^1.1.0",
    "moment": "^2.30.1",
    "pinia": "^2.2.2",
    "svg-sprite-loader": "^6.0.11",
    "vue": "^3.2.13",
    "vue-i18n": "^9.1.0",
    "vue-router": "^4.0.3"
  },
  "devDependencies": {
    "@arco-design/web-vue": "^2.56.2",
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@intlify/vue-i18n-loader": "^3.0.0",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-plugin-router": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "vue-cli-plugin-i18n": "~2.3.2",
    "vue-cli-plugin-mock": "~1.0.3"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead",
    "not ie 11"
  ]
}

相关文章:

  • es --- 集群数据迁移
  • C++11QT复习 (十四)
  • Qt中的元对象系统
  • 基于chatgpt得到的生活成本计算
  • 开源免费虚拟化软件PVE功能介绍
  • 服务器报错:xxx/libc.so.6: version `GLIBC_2.32‘ not found
  • 软件工程第二章
  • STM32 基础2
  • 华为交换机上配置流量策略根据IP限速
  • CentOS安装Docker
  • 005 vue项目结构 vue请求页面执行流程(vue2)
  • Spring IoCDI
  • tomcat的负载均衡和会话保持
  • 微信小程序生成某个具体页面的二维码
  • JVM基础架构:内存模型×Class文件结构×核心原理剖析
  • 算法刷题记录——LeetCode篇(2.6) [第151~160题](持续更新)
  • 使用ExcelJS实现专业级医疗数据导出功能:从数据到Excel报表的完整指南
  • vscode调试vite项目断点(debugger)
  • 基于HAI应用,从零开始的NLP处理实践指南
  • 【区块链安全 | 第三十一篇】合约(五)
  • 经济日报:人工智能开启太空经济新格局
  • 首届中国人文学科年度发展大会启幕,共话AI时代人文使命
  • 卿晨璟靓等用服刑经历“引流”,专家:将犯罪问题娱乐化会消解刑罚严肃性
  • 雅典卫城上空现“巨鞋”形状无人机群,希腊下令彻查
  • 钕铁硼永磁材料龙头瞄准人形机器人,正海磁材:已向下游客户完成小批量供货
  • 商务部回应稀土出口管制问题