帮公司搭了个Nuxt3项目框架

news2024/11/17 16:19:44

theme: smartblue

最近公司立项了一个新项目,因为是to C 的,所以对SEO是有较高需求的,由于公司前端技术栈统一用的VUE,顺理成章的就选择了nuxt这个全栈框架。项目立项之后我就被安排了负责前端项目框架的搭建,从搭建过程的体验来看,技术栈切换到nuxt还是有门槛的,所以这里我就把经过我打磨好的nuxt完整项目框架分享出来,大家即拿即用,童叟无欺。顺嘴提一句,欢迎大家关注我的微信公众号fever code,获取最新技术分享。

项目结构

- api
- assets
-- images
-- lang
---- en_us.json
---- zh_cn.json
-- scss
---- constants.scss
---- index.scss
- components
- composables
-- store
-- pinia
-- locale.js
-- auth.js
-- toast.js
- configs
- constants
-- auth.js
- layouts
-- default.vue
-- login.vue
- middleware
-- default.global.js
- pages
- plugins
-- pinia.js
- public
- server
-- api
---- list.js
-- middleware
---- request.js
- utils
-- http.js
- .env.development
- .env.local
- .env.production
- .eslintrc.cjs
- .gitignore
- .prettierrc.json
- app.vue
- error.vue
- i18n.config.js
- nuxt.config.ts
- package.json

NUXT项目配置

下面贴一下nuxt项目配置的代码。因为UI设计师选用的样式风格是arco-design组件库的风格,所以项目中也集成的acro-design。项目采用的适配方案是px-to-vw,状态管理工具是nuxt自带的useStatepinia,简单的状态管理采用useState就够了,复杂的状态就决定使用pinia分模块化管理。项目的受众群体囊括了海内外的业内人士,所以在项目中也做了国际化的处理,环境变量使用的是VITE_开头,客户端可以使用import.env.meta访问,也可以使用useRuntimeConfig获得。

// https://nuxt.com/docs/api/configuration/nuxt-config

export default defineNuxtConfig({
    devtools: { enabled: false },
    app: {
        head: {
            titleTemplate: '%s - 京东商城',
            title: '京东商城',
            charset: 'utf-8',
            htmlAttrs: {
                lang: 'zh-CN'
            },
            meta: [
                { name: 'keywords', content: '网上购物,网上商城,家电,手机,电脑,服装,居家,母婴,美妆,个护,食品,生鲜,京东' },
                {
                    name: 'description',
                    content:
                        '京东JD.COM-专业的综合网上购物商城,为您提供正品低价的购物选择、优质便捷的服务体验。商品来自全球数十万品牌商家,囊括家电、手机、电脑、服装、居家、母婴、美妆、个护、食品、生鲜等丰富品类,满足各种购物需求。'
                }
            ]
        }
    },
    // 注入全局样式
    css: ['~/assets/scss/index.scss'],
    modules: [
        // arco-design UI组件库
        'arco-design-nuxt-module',
        // 国际化插件
        '@nuxtjs/i18n',
        [
            // pinia状态管理库
            '@pinia/nuxt',
            {
                // 项目中自动导入pinia的defineStore方法
                autoImports: ['defineStore']
            }
        ]
    ],
    // arco-design UI组件库配置
    arco: {
        importPrefix: 'A',
        hookPrefix: 'Arco',
        locales: ['getLocale'],
        localePrefix: 'Arco'
    },
    // 国际化插件配置
    i18n: {
        strategy: 'no_prefix', // 添加路由前缀的方式
        locales: ['en', 'zh'], //配置语种
        defaultLocale: 'zh', // 默认语种
        vueI18n: 'i18n.config.js' // 通过vueI18n配置
    },
    // nuxt组件库配置
    components: [
        {
            path: '~/components',
            extensions: ['.vue'],
            pathPrefix: false
        }
    ],
    imports: {
        dirs: [
            // 扫描composables目录中的所有(包括子文件夹)模块
            'composables/**'
        ]
    },
    // 发服务器配置
    devServer: {
        port: 3001
    },
    build: {
        // 在开发环境和生产环境对es包使用babel进行语法转换
        transpile: ['element-plus/es']
    },
    vite: {
        css: {
            preprocessorOptions: {
                scss: {
                    // 全局引入scss常量,供全局使用
                    additionalData: '@import "assets/scss/constant.scss";'
                }
            }
        }
    },
    postcss: {
        plugins: {
            'postcss-px-to-viewport': {
                viewportWidth: 1920 /** 设计稿的视口宽度 */,
                unitToConvert: 'px' /** 需要转换的单位,默认为"px" */,
                unitPrecision: 5 /** 单位转换后保留的精度 */,
                propList: ['*'] /** 能转化为vw的属性列表 */,
                viewportUnit: 'vw' /** 希望使用的视口单位 */,
                fontViewportUnit: 'vw' /** 字体使用的视口单位 */,
                selectorBlackList: [] /**  需要忽略的CSS选择器 */,
                minPixelValue: 1 /** 设置最小的转换数值 */,
                mediaQuery: false /** 媒体查询里的单位是否需要转换单位 */,
                replace: true /** 是否直接更换属性值,而不添加备用属性 */,
                exclude: undefined /** 忽略某些文件夹下的文件或特定文件 */,
                include: undefined /**  设置将只有匹配到的文件才会被转换 */,
                landscape: false /** 是否添加根据 landscapeWidth 生成的媒体查询条件 @media */,
                landscapeUnit: 'vw' /** 横屏时使用的单位 */,
                landscapeWidth: undefined /** 横屏时使用的视口宽度 */
            }
        }
    },
    runtimeConfig: {
        mode: process.env.VITE_MODE,
        base_url: process.env.VITE_BASE_URL,
        app: {
            mode: process.env.VITE_MODE,
            base_url: process.env.VITE_BASE_URL,
        }
    }
})

客户端请求HTTP模块封装

Nuxt作为一个全栈框架,是有客户端和服务端的概念的。在使用nuxt开发的过程中,很多人有一个误区,认为前端所有的请求都要发送到nuxt服务端,nuxt服务端请求后端接口后返回前端。其实不是这样的,只有需要SSR(服务端渲染)的内容才需要这样做,也就是需要渲染的数据的GET请求才需要这样做,对于增加、删除、修改这一类请求完全可以直接在客户端向后端发请求。这里贴一下我封装HTTP模块(请求库用的是nuxt自带的$fetch)。

/**
 * @description http模块
 */
import { jumpToLogin } from '@/utils/utils'

// 接口基地址
const BASE_URL = import.meta.env.VITE_BASE_URL

// 环境
const MODE = import.meta.env.VITE_MODE

// 生产环境
const MODE_PRODUCTION = 'production'

// GET请求方法
const METHOD_GET = 'GET'

// 成功状态
const SUCCESS_STATUS_TEXT = 'OK'

// 响应类型
const RESPONSE_TYPE = ['blob', 'stream']

// 请求拦截器
const requestInterceptor = (config) => {
    if (config.options.meta?.needAuth) {
        const { getToken, getUid } = useAuth()
        const token = getToken()
        const uid = getUid()
        const method = config.options.method?.toUpperCase()

        if (method === METHOD_GET) {
            const query = config.options.query || {}
            config.options.query = { ...query, token, uid }
        } else {
            const body = config.options.body || {}
            config.options.body = { ...body, token, uid }
        }
    }
    return config
} 

// 响应拦截器
const responseInterceptor = (response) => {
    const res = response.response

    if (res.status === 200 &&
        res.statusText === SUCCESS_STATUS_TEXT &&
        res._data.data &&
        RESPONSE_TYPE.includes(res?.type)
    ) {
        return response
    }

    if (MODE !== MODE_PRODUCTION) {
        console.log(res.url, {
            code: res._data.code,
            data: res._data.data,
            res: res._data,
            params: response.options,
            resHeaders: res.headers
        })
    }

    if (res._data.code === 0 || res._data.code === 200) {
        return response
    } else if (res._data.code === -50) {
        // token过期或失效
        const routeMeta = useRouteMeta()
        const { removeToken, removeUid } = useAuth()
        const userInfo = useUserInfo()
        removeToken()
        removeUid()

        // 清空用户信息
        userInfo.value = {}

        if (routeMeta.value.needAuth) {
            // 当前页面需要权限的话,登录失效即跳转登录页
            jumpToLogin()
        }

        return Promise.reject(res._data)
    }
    return Promise.reject(res._data)
}  

// 错误拦截器
const errorInterceptor = (err) => {
    return Promise.reject(err.error)
}

const httpInstance = $fetch.create({
    baseURL: BASE_URL,
    onRequest: requestInterceptor,
    onResponse: responseInterceptor,
    onRequestError: errorInterceptor
}) 

export default httpInstance

api接口管理模块

// /api/common.js

/**
 * @description 项目中公共请求api
 */

import http from '@/utils/common' 

// 获取上传临时密钥
export function getCommonList() {
    return http('/api/common/getList', {
        method: 'get',
        meta: {
            // 标记该接口是否需要权限校验,需要则会在请求拦截器那里做请求拦截相关逻辑处理
            needAuth: true
        }
    })
}

NUXT服务端请求

nuxt服务端接口开发,请求流程:前端 --> nuxt服务端 --> java等服务端接口

// /server/api/list.js

import { readRawBody, getQuery, getMethod } from 'h3'

export default defineEventHandler(async (event) => {
    // const res = await useFetchData('/user-center/user/getUserInfo', {
    //     method,
    //     baseURL: event.context.baseUrl,
    //     headers: event.context.headers,
    //     params: getQuery(event),
    //     body
    // })

    const method = getMethod(event).toUpperCase()
    let body
    if (method !== 'GET') body = await readRawBody(event)
    const res = await $fetch('/user-center/user/getUserInfo', {
        method,
        baseURL: event.context.baseUrl,
        headers: event.context.headers,
        params: getQuery(event),
        body
    })

    return res || { userInfo: {} }
})

nuxt服务端中间件处理请求(所有通往nuxt服务端的请求,以及nuxt服务端响应前端过程都会在这里被拦截处理)

import { getHeaders } from 'h3'

export default defineEventHandler((event) => {
    const reqHeaders = getHeaders(event)
    const ssrHeader = new Headers()
    const { app } = useRuntimeConfig()

    ssrHeader.set('cookie', reqHeaders.cookie)
    // 往nuxt请求注入请求基地址
    event.context.baseUrl = app.base_url
    // 往nuxt请求注入请求头
    event.context.headers = ssrHeader
})

前使用useFetch调用nuxt接口即可

<srcipt setup>
const { data: result } = await useFetch('/api/list')
</script>

路由守卫

nuxt中的路由守卫是在客户端middleware使用defineNuxtRouteMiddleware路由中间件功能实现的。nuxt中设计的客户端的middleware主要是用来拦截路由的,即客户端的路由切换会通过客户端的middleware。如果客户端向nuxt服务端发请求,则请求都会被服务端的middleware拦截处理。客户端的中间件文件名如果使用.global.js,则nuxt会识别为这是一个全局生效的中间件。由于我们这里实现的是全局路由守卫功能,所以文件名命名为default.global.js

// /middleware/default.global.js

/**
 * @description 全局路由守卫
 */
import { jumpToLogin } from '@/utils/utils'

export default defineNuxtRouteMiddleware((to, from) => {
    const routeMeta = useRouteMeta()
    const { getToken, getUid } = useAuth()

    if (to.meta.needAuth && (!getToken() || !getUid())) {
        // 需要授权的页面验证是否登录
        jumpToLogin()
        
        return abortNavigation()
    }

    // 记录当前要访问页面的元信息(必须置于鉴权逻辑之后),供http模块鉴权之用
    routeMeta.value = to.meta || {}
})

状态管理

项目中的状态管理我同时使用了nuxt集成的轻量级的useState和vue官方推荐的pinia

使用useState封装的hook直接放到/composables/store文件夹下

// composables/store/base.js

/**
 * @description 项目基础状态管理模块
 */

import { USER_INFO, ROUTE_META, LOCALE_TYPE } from '@/constants/state'

// 用户信息管理
export const useUserInfo = () => useState(USER_INFO, () => {
    return {}
})

// 路由元数据
export const useRouteMeta = () => useState(ROUTE_META, () => {
    return {}
})

// 国际化 - 本地语言类型
export const useLocale = () => useState(LOCALE_TYPE, () => {
    return 'zh'
})

pinia模块直接放到/composables/pinia文件夹下管理维护。因为nuxt中pinia存在,刷新状态丢失的情况,所以在客户端的plugins中集成了pinia-plugin-persistedstate插件,实现状态数据持久化能力。

// plugins/pinia.js
// https://prazdevs.github.io/pinia-plugin-persistedstate/zh/guide/config.html

/**
 * @description pinia数据持久化插件
 */
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.$pinia.use(piniaPluginPersistedstate)
})

国际化

项目中使用的国际化插件是vue-i18n,配置如下

// i18n.config.js

import en from "assets/lang/en_us.json";
import zh from "assets/lang/zh_cn.json";

export default defineI18nConfig(() => ({
    legacy: false,  // 是否兼容之前
    fallbackLocale: 'en',  // 区配不到的语言就用en
    messages: {
        en,
        zh
    }
}))
// /assets/lang/en_us.json
{

    "home": "Home"

}
// /assets/lang/zh_cn.json
{

    "home": "主页"

}

为了使用方便,我特地在文件夹下封装了一个hook

/**
 * @description 提供国际化功能的hook
 */

export function useI18nHook() {
    const { locale, setLocale } = useI18n()
    const localeLang = useLocale()

    // 初始化本地语言类型
    localeLang.value = locale
    
    const setLocaleLang = (type) => {
        setLocale(type)
        localeLang.value = type
    }
    
    return {
        locale: localeLang,
        setLocale: setLocaleLang
    }
}

.vue模版中使用直接如下

<template>
    <div>{{ $t('home') }}
</template>

不仅页面代码需要国际化处理,UI组件库也需要国际化处理,acro-designUI库使用a-config-provider标签在App.vue文件中全局注入本地语言

<template>
    <div>
        <a-config-provider :locale="locale">
            <NuxtLayout>
                <NuxtPage />
            </NuxtLayout>
        </a-config-provider>
    </div>
</template>

<script setup>
import enUS from '@arco-design/web-vue/es/locale/lang/en-us'
import zhCN from '@arco-design/web-vue/es/locale/lang/zh-cn'

const locales = {
    zh: zhCN,
    en: enUS
}

const { locale: langLocale } = useI18nHook()

const locale = computed(() => {
    return locales[langLocale] || zhCN
})

useHead({
    link: [
        { rel: 'shortcut icon', href: '/favicon.ico' },
        { rel: 'apple-touch-icon', href: '/favicon.ico' }
    ]
})
</script>

其他配置

Layout

// /layout/default.vue

<template>
    <div class="layout-container">
        <Header />
        <main class="content">
            <slot />
        </main>
        <Footer />
    </div>
</template>

<style scoped lang="scss">
.layout-container {
    min-height: 100vh;
    .content {
        min-height: calc(100vh - 447px);
        background: #f7f8fa;
    }
}
</style>

权限管理HOOK

// /composables/auth.js

/**
 * @description 提供权限管理功能
 */
import { TOKEN_KEY, UID_KEY } from '@/constants/auth'

const MODE = import.meta.env.VITE_MODE

const DomainMap = {
    development: 'demo.com',
    production: 'demo.cn',
}

export function useAuth() {
    const cookieToken = useCookie(TOKEN_KEY, { domain: DomainMap[MODE] }
    const cookieUID = useCookie(UID_KEY, { domain: DomainMap[MODE] })

    const getToken = () => {
        return cookieToken.value
    }

    const setToken = (token) => {
        cookieToken.value = token
    }

    const removeToken = () => {
        cookieToken.value = undefined
    }

    const getUid = () => {
        return cookieUID.value
    }

    const setUid = (uid) => {
        cookieUID.value = uid
    }

    const removeUid = () => {
        cookieUID.value = undefined
    }

    return {
        getToken,
        setToken,
        removeToken,
        getUid,
        setUid,
        removeUid,
    }
}

全局Toast HOOK

toast提示使用的是vue-toast-notification插件

// /composables/toast.js

/**
 * @description 全局用toast提示方法
 */
import { useToast as useToastNotification } from 'vue-toast-notification'

export function useToast() {
    return useToastNotification()
}

Eslint配置

配置里继承的@nuxt/eslint-config的规则较为严格,不用也可以去掉

module.exports = {
    root: true,
    extends: ['@nuxt/eslint-config'],
    parserOptions: {
        ecmaVersion: 'latest'
    },
    rules: {
        'vue/multi-word-component-names': 0/**针对单个单词组件报错的规则关闭 */,
        'no-undef': 0, /**关闭变量未定义检查 */
        'no-debugger': 2 /**禁用 debugger  */,
        'no-dupe-args': 2 /**禁止 function 定义中出现重名参数 */,
        'no-dupe-keys': 2 /**禁止对象字面量中出现重复的 key */,
        'no-empty': 1 /**禁止出现空语句块 */,
        'no-ex-assign': 1 /**禁止对 catch 子句的参数重新赋值 */,
        'no-extra-boolean-cast': 1 /**禁止不必要的布尔转换 */,
        'no-extra-parens': 1 /**禁止不必要的括号 */,
        'no-extra-semi': 1 /**禁止不必要的分号 */,
        'no-func-assign': 1 /**禁止对 function 声明重新赋值 */,
        'no-irregular-whitespace': 1 /**禁止在字符串和注释之外不规则的空白 */,
        'no-unexpected-multiline': 1 /**禁止出现令人困惑的多行表达式 */,
        'no-unreachable': 1 /**禁止在return、throw、continue 和 break语句之后出现不可达代码 */,
        'use-isnan': 1 /**要求使用 isNaN() 检查 NaN */,
        'dot-location': 1 /**强制在点号之前和之后一致的换行 */,
        'eqeqeq': 2 /**要求使用 === 和 !== */,
        'no-alert': 1 /**禁用 alert、confirm 和 prompt */,
        'no-case-declarations': 1 /**不允许在 case 子句中使用词法声明 */,
        'no-else-return': 1 /**禁止 if 语句中有 return 之后有 else */,
        'no-empty-function': 1 /**禁止出现空函数 */,
        'no-eq-null': 1 /**禁止在没有类型检查操作符的情况下与 null 进行比较 */,
        'no-eval': 1 /**禁用 eval() */,
        'no-fallthrough': 1 /**禁止 case 语句落空 */,
        'no-lone-blocks': 1 /**禁用不必要的嵌套块 */,
        'no-redeclare': 1 /**禁止使用 var 多次声明同一变量 */,
        'no-self-assign': 1 /**禁止自我赋值 */,
        'no-self-compare': 1 /**禁止自身比较 */,
        'no-unmodified-loop-condition': 1 /**禁用一成不变的循环条件 */,
        'vars-on-top': 1 /**要求所有的 var 声明出现在它们所在的作用域顶部 */,
        'eol-last': 1 /**强制文件末尾至少保留一行空行强制文件末尾至少保留一行空行 */,
    }
}

Premitter配置

{
  "$schema": "https://json.schemastore.org/prettierrc",
  "semi": false,
  "tabWidth": 2,
  "singleQuote": true,
  "printWidth": 100,
  "trailingComma": "none",
  "useTabs": true
}

package.json

{
    "name": "app",
    "private": true,
    "type": "module",
    "scripts": {
        "build": "nuxt build --dotenv .env.production",
        "build:dev": "nuxt build --dotenv .env.development",
        "serve": "nuxt dev --dotenv .env.local",
        "generate": "nuxt generate",
        "preview": "nuxt preview --dotenv .env.production",
        "postinstall": "nuxt prepare",
        "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
        "format": "prettier"
    },
    "dependencies": {
        "@pinia/nuxt": "^0.5.1",
        "arco-design-nuxt-module": "^0.1.0",
        "blueimp-md5": "^2.19.0",
        "clipboard": "^2.0.11",
        "cos-js-sdk-v5": "^1.8.1",
        "dayjs": "^1.11.11",
        "nuxt": "^3.12.2",
        "pinia": "^2.1.7",
        "pinia-plugin-persistedstate": "^3.2.1",
        "vue": "^3.4.29",
        "vue-i18n": "^9.13.1",
        "vue-router": "^4.3.3",
        "vue-toast-notification": "^3.1.2"
    },
    "devDependencies": {
        "@nuxt/eslint-config": "^0.3.13",
        "@nuxtjs/i18n": "^8.3.1",
        "postcss-aspect-ratio-mini": "^1.1.0",
        "postcss-px-to-viewport": "^1.1.1",
        "prettier": "^3.3.2",
        "sass": "^1.77.6",
        "sass-loader": "^14.2.1"
    }
}

环境变量

环境变量定义了.local.env.production.env.development.env这里只单列一个

# 环境变量
VITE_MODE=development

# 接口基地址
VITE_BASE_URL=https://demo.cn

写在最后

扫码关注作者微信公众号fever code,获取一手技术分享
在这里插入图片描述

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

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

相关文章

探寻IT的道路,从现在开始!

IT专业入门&#xff0c;高考假期预习指南 七月来临&#xff0c;各省高考分数已揭榜完成。而高考的完结并不意味着学习的结束&#xff0c;而是新旅程的开始。对于有志于踏入IT领域的高考少年们&#xff0c;这个假期是开启探索IT世界的绝佳时机。作为该领域的前行者和经验前辈&a…

Java [ 基础 ] 数组、ArrayList和LinkedList✨

目录 ✨探索Java基础 数组、ArrayList和LinkedList✨ 一、总体介绍 二、分别介绍 1. 数组&#xff08;Array&#xff09; 2. ArrayList 3. LinkedList 三、区别总结 四、常见面试题 如何选择使用数组、ArrayList和LinkedList&#xff1f; 如何实现线程安全的ArrayL…

stm32cubeide的undefined reference难解之谜

stm32cubeide 的 undefined reference 难解之谜 今天使用意法半导体公司的STM32CubeIDE 1.15.0编码器 遇到了一个熟悉&#xff0c;却令我绞尽脑汁的问题 这个问题大家应该都挺常见的 有以下几种要注意的地方 1、路径是否包含 2、函数是否在C文件定义 3、函数是否在头文件中定…

美国拟立法评估:极端网络攻击下关基设施能否切换手动操作

文章目录 前言一、评估关基设施快速切换手动操作的可行性1、评估需包括如下内容:2、政策保障关键基础设施运行二、保障关基设施安全迫不容缓前言 随着来自俄罗斯、伊朗和朝鲜等敌对国家以及国家关联团体的威胁不断增加,网络攻击对电网、水务系统和管道等关键基础设施的潜在破…

Python绘制动态树形:实现分形树动画

文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Turtle绘制分形树函数动态绘制函数主函数 完整代码 引言 分形树是一种通过递归生成的美丽图案&#xff0c;在数学和计算机图形学中有着重要的地位。在这篇博客中&#xff0c;我们将使用Python创建一个动态的分…

【C语言】union 关键字

在C语言中&#xff0c;union关键字用于定义联合体。联合体是一种特殊的数据结构&#xff0c;它允许不同的数据类型共享同一段内存。所有联合体成员共享同一个内存位置&#xff0c;因此联合体的大小取决于其最大成员的大小。 定义和使用联合体 基本定义 定义一个联合体类型时…

【NOI-题解】1372. 活动选择1456. 淘淘捡西瓜1485. 接水问题

文章目录 一、前言二、问题问题&#xff1a;1372. 活动选择问题&#xff1a;1456. 淘淘捡西瓜问题&#xff1a;1485. 接水问题 三、感谢 一、前言 本章节主要对贪心问题进行讲解&#xff0c;包括《1372. 活动选择》《1456. 淘淘捡西瓜》《1485. 接水问题》题目。 二、问题 问…

Pandas函数详解:案例解析(第25天)

系列文章目录 Pandas函数详解排序函数聚合函数缺失值处理日期函数 文章目录 系列文章目录前言1 索引和列名操作1.1 查看索引和列名1.2 修改索引和列名 2 常用计算函数2.1 排序函数2.2 聚合函数2.3 练习 3 缺失值处理3.1 缺失值概念3.2 加载包含缺失值数据3.3 查看缺失值3.4 缺失…

无人机集群协同搜索研究综述

源自&#xff1a;指挥控制与仿真 作者&#xff1a;刘圣洋, 宋婷, 冯浩龙, 孙玥, 韩飞 注&#xff1a;若出现无法显示完全的情况&#xff0c;可 V 搜索“人工智能技术与咨询”查看完整文章 摘要 无人机集群协同区域搜索能够有效地获取任务区域地面信息,降低环境不确定度。基…

【操作系统】操作系统运行环境——处理器的运行模式

处理器的运行模式 导读一、内核程序和应用程序二、特权指令与非特权指令三、用户态与核心态四、内核4.1 时钟管理4.2 中断机制4.3 原语4.4 系统控制的数据结构及处理 结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我…

高校教师教学质量评估系统-计算机毕业设计源码03344

摘要 在高等教育中&#xff0c;教学质量是培养优秀人才的关键。为了提高教学质量&#xff0c;高校需要建立一套科学、有效的教师教学质量评估系统。本研究采用 SSM技术框架&#xff0c;旨在开发一款高校教师教学质量评估系统。 SSM框架作为一种成熟的Java开发框架&#xff0c;具…

echarts--Tree的label上添加图片

使用echarts的rich富文本&#xff0c;配合lable的formatter去实现 主要代码&#xff1a;label里 rich: {img1: {backgroundColor: {image: Cloudy,},height: 40}},formatter: function (param) {var res "";res {img1|} param.name;return res;}, 如果想要哪一节…

基于贝叶斯优化的卷积神经网络-循环神经网络混合模型的的模拟股票时间序列预测(MATLAB R2021B)

将机器学习和深度学习方法运用到股市分析中, 不仅具有一定的理论价值, 也具有一定的实践价值。从理论价值上讲, 中国的量化投资技术&#xff08;投资观念、方法与决策等&#xff09;还不够成熟, 尚处在起步阶段, 能够将量化投资技术运用到投资决策中的公司寥寥无几。目前, 国内…

程序员学CFA——经济学(五)

经济学&#xff08;五&#xff09; 货币政策与财政政策基本术语货币政策货币货币的功能货币的定义货币的创造过程货币的供给和需求费雪效应 中央银行中央银行的职能中央银行的目标与通货膨胀的成本中央银行的有效性 货币政策工具货币传导机制货币政策的目标与形式货币政策的目标…

AIGC时代算法工程师的面试秘籍(2024.6.10-6.23第十六式) |【三年面试五年模拟】

写在前面 【三年面试五年模拟】旨在整理&挖掘AI算法工程师在实习/校招/社招时所需的干货知识点与面试方法&#xff0c;力求让读者在获得心仪offer的同时&#xff0c;增强技术基本面。也欢迎大家提出宝贵的优化建议&#xff0c;一起交流学习&#x1f4aa; 欢迎大家关注Rocky…

还以网站建设为主营?赶紧转!除非你的网站做比他们还漂亮

案例一&#xff1a;某上市公司2019年找A公司做了一个官网&#xff0c;网站做了三年多&#xff0c;到现在没有上线&#xff0c;该公司业务没受任何影响&#xff0c;一直蒸蒸高日上。案例二&#xff1a;我公司也有自己官网&#xff0c;这么多年页面啥流量&#xff0c;一样不影响我…

001:开源交易系统开发实战开篇

本专栏采用融入【主力思维】的方法学&#xff0c;包含数据抓取、特征模型开发、历史验证回归测试、每日动态风险评估管理等技术&#xff0c;较大的增强股票投资胜率&#xff0c;让IT开发者拥有一套实用的属于自己思路的专用交易软件。 先简要介绍下系统运行的成果和项目架构&a…

这玩意终于有免费的了———Navicat Premium Lite

免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 去下载吧&…

uniapp应用如何实现传感器数据采集和分析

UniApp是一种跨平台的应用开发框架&#xff0c;它支持在同一份代码中同时开发iOS、Android、H5等多个平台的应用。在UniApp中实现传感器数据采集和分析的过程可以分为以下几个步骤&#xff1a; 引入相关插件或库 UniApp通过插件或库的形式扩展功能。对于传感器数据采集和分析&…

无人机对地面运动目标定位---获取目标的移动方向和速度

目录 一、引子 我们利用单目无人机通过等时间间隔拍照的形式对地面某移动目标进行定位&#xff0c;当前&#xff0c;我们已经获得了每张相片上该目标的三维坐标&#xff0c;并且知道该无人机在飞行过程中拍照的时间间隔&#xff0c;那么我们就可以通过一定的计算&#xff0c;得…