基于vue3+ts5+vue-router4+pinia2的PC端项目搭建教程
导语:在日常开发中,有时候会在项目中引入 ts 来解决一些 js 的问题,下面就简单介绍一下如何使用 vue3+ts+router+pinia 来搭建一个项目。
目录
- 简介
- 创建
- 安装
- 配置
- 实战
简介
vue3 目前是常用的 vue 版本,提供了组合式 API 以及一些新的功能和特性;ts 这种类型编程语言可以在编译时通过静态分析检测出很多常见错误,减少了生产环境中的运行时错误,改善了开发体验和效率;vue-router 也更新到了 4 版本,pinia 则是最新退出的替代 vuex 的一个 vue 官方状态管理库;下面就结合以上提到的技术栈组合来简单创建一个项目。
- vite 官网
- vuejs 官网
- ts 官网
- vue-router 官网
- pinia 官网
创建
下面打开 cmd 或其他命令行,输入以下命令创建一个 vite 项目。
这里我选择使用pnpm
来创建。
- 创建 vite 项目
pnpm create vite
- 填写项目信息
包括项目名称、选择框架、js 语言等。
√ Project name: ... tslx
√ Select a framework: » Vue
√ Select a variant: » TypeScript
- 创建成功
根据以下步骤来安装基本的依赖和运行项目。
cd tslx
pnpm install
pnpm run dev
安装
创建好项目后,接下来安装一些必备的依赖包。
必备依赖包
- vue-router
这个是必须的,路由管理。
pnpm i vue-router -S
- sass
这个是必须的,主要是使用 sass 写项目样式表。
pnpm i sass -S
- axios
这个是必须的,主要是 http 请求数据。
pnpm i axios -S
可选依赖包
- pinia
这个是可选的,主要是提供状态管理。
pnpm i pinia -D
- pinia-plugin-persist
这个是可选的,主要是提供状态管理的持久化存储。
pnpm i pinia-plugin-persist -D
- unplugin-auto-import
这个是可选的,自动导入依赖插件。
pnpm i unplugin-auto-import -D
- normalize.css
这个是可选的,主要是可定制化 CSS 样式。
pnpm i normalize.css -D
- mitt
这个是可选的,一个简洁、灵活的 JavaScript 事件订阅和发布库。
pnpm i mitt -D
- @volar-plugins/vetur
这是可选的,一个支持 vue3 语法的插件。
pnpm i @volar-plugins/vetur -D
- @vitejs/plugin-vue
这个是可选的,支持基于 Vite 构建的 Vue 项目。
pnpm i @vitejs/plugin-vue -D
- @types/node
这个是可选的,主要是解决模块的声明问题。
pnpm i @types/node -D
- path
这个是可选的,主要是 node 的 path 模块。
pnpm i path -D
- rollup-plugin-visualizer
这个是可选的,主要是应用模块统计。
pnpm i rollup-plugin-visualizer -D
- vue-i18n
这个是可选的,主要是多语言配置。
pnpm i vue-i18n -D
好了,以上就是日常开发项目常用的一些依赖包。
配置
下面配置一下vite.config.ts
文件和main.ts
文件以及其他需要配置的文件。
vite 配置文件
打开vite.config.ts
文件,主要是添加插件配置,文件路径别名配置,css 全局样式配置,服务端端口及代理配置。
引入依赖
import AutoImport from "unplugin-auto-import/vite";
import vetur from "@volar-plugins/vetur";
import path from "path";
import { visualizer } from "rollup-plugin-visualizer";
插件配置
在plugins
中添加以下配置。
//...
{plugins: [vue({template: {compilerOptions: {isCustomElement: () => {return false;},},},}),vetur,AutoImport({dts: "src/auto-import.d.ts",include: [/\.[tj]sx?$/, // .ts, .tsx, .js, .jsx/\.vue$/,/\.vue\?vue/, // .vue],imports: ["vue","vue-router",{from: "vue-router",imports: ["RouteLocationRaw"],type: true,},],}),visualizer({emitFile: false,filename: "stats.html",open: true,}),];
}
// ...
文件路径别名配置
在src
文件夹下面新建三个文件,可以选择去掉assets
文件夹。
types
:主要是存放 ts 声明等内容;styles
:主要是存放全局样式文件;apis
:主要是存放全局方法文件;
下面是配置方法。
//...
{resolve: {alias: {"@": path.resolve(__dirname, "./src"),"@c": path.resolve(__dirname, "./src/components"),"@t": path.resolve(__dirname, "./src/types"),"@s": path.resolve(__dirname, "./src/styles"),"@a": path.resolve(__dirname, "./src/apis"),},}
}
//...
css 全局样式配置
下面设置 css 全局样式配置,在刚刚创建的styles
文件夹下面创建一个global.scss
的文件。
// ...
{css: {preprocessorOptions: {scss: {additionalData: '@import "./src/styles/global.scss";',javascriptEnabled: true,},},},
}
//...
服务端端口及代理配置
最后就是一个服务端的配置,包括端口,自动打开网页,跨域接口设置。
//...
{server: {host: "0.0.0.0",port: 6060,open: true,proxy: {"/api": {autoRewrite: true,target: "http://127.0.0.1:9999",changeOrigin: true,ws: true,},},},
}
//...
配置好以后,重启一下服务就生效了。
配置 ts
- 添加
paths
路径
在tsconfig.json
中新增一个paths
属性并配置如下。
{"paths": {"@/*": ["src/*"],"@c/*": ["src/components/*"],"@t/*": ["src/types/*"],"@s/*": ["src/styles/*"],"@a/*": ["src/apis/*"]}
}
- 完整配置
完整的tsconfig.json
内容:
{"compilerOptions": {"target": "ESNext","useDefineForClassFields": true,"module": "ESNext","lib": ["ESNext", "DOM", "DOM.Iterable"],"skipLibCheck": true,/* Bundler mode */"moduleResolution": "Node","allowImportingTsExtensions": true,"resolveJsonModule": true,"isolatedModules": true,"noEmit": true,"jsx": "preserve",/* Linting */"strict": true,"noUnusedLocals": true,"noUnusedParameters": true,"noFallthroughCasesInSwitch": true},"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],"references": [{ "path": "./tsconfig.node.json" }],"paths": {"@/*": ["src/*"],"@c/*": ["src/components/*"],"@t/*": ["src/types/*"],"@s/*": ["src/styles/*"],"@a/*": ["src/apis/*"]}
}
完整的tsconfig.node.json
的内容:
{"compilerOptions": {"composite": true,"skipLibCheck": true,"module": "ESNext","moduleResolution": "Node","allowSyntheticDefaultImports": true},"include": ["vite.config.ts"]
}
配置 main.ts
- 整理
main.ts
文件
修改为以下内容,这样方便后面挂载全局组件,方法和插件等内容。
import { createApp } from "vue";
import App from "./App.vue";const app = createApp(App);app.mount("#app");
- vue 组件声明
打开main.ts
会看到找不到模块“./App.vue”或其相应的类型声明的报错,下面就在src
下面新建一个 vue 声明文件global.d.ts
。
// ./src/global.d.ts
declare module "*.vue" {import type { DefineComponent } from "vue";const vueComponent: DefineComponent<{}, {}, any>;export default vueComponent;
}
这个可以让 ts 识别 vue 组件类型声明。
配置 vue-router
下面简单的配置一个路由文件,在src
下面新建一个router
文件夹,并创建一个index.ts
文件。
// ./src/router/index.ts// 导入依赖
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";// 配置routes
const routes: Array<RouteRecordRaw> = [{path: "/",name: "Home",component: () => import("@c/home.vue"),children: [],},{path: "/404",name: "NotFound",component: () => import("@c/404.vue"),meta: {title: "404",auth: false,},},{path: "/:pathMatch(.*)",redirect: "/404",},
];// 配置router
const router = createRouter({history: createWebHistory(),routes,scrollBehavior(to, from) {console.log(to, from);return {left: 0,top: 0,};},
});// 配置钩子
router.beforeEach((to, from, next) => {console.log(to, from);// ...next();
});router.afterEach((to, from) => {console.log(to, from);// window.scrollTo(0, 0);
});// 导出路由
export default router;
- 导入
main.ts
文件。
//...
import router from "./router";
// ...
app.use(router);
//...
配置 pinia
在src
下面新建一个store
的文件夹,里面新建一个index.ts
、types.ts
以及user.ts
的文件。
index.ts
文件
这个文件主要是放置基础的配置,包括插件,持久化存储。
import { createPinia } from "pinia";
import piniaPluginPerisit from "pinia-plugin-persist";// 全局设置
export const pinia = createPinia();
pinia.use(piniaPluginPerisit);export default pinia;
在配置的时候,pinia-plugin-persist
插件可能会报错,原因是找不到模块声明。
可以采取以下方法解决:
- 升级到最新版试试看;
- 在
types
目录下新建一个pinia-plugin-persist.d.ts
声明文件。
内容为:
declare module "pinia-plugin-persist";
types.ts
文件
这个文件主要是放置类型变量。
const enum NAMES {user = "USER",
}export default NAMES;
enum
可能会报错,Parsing error: The keyword 'enum' is reserved
, enum 是 Javascript 为未来特性保留的关键字,我们不应该使用它,属于eslint
检查错误。
可以采取以下方法解决:
安装三个插件eslint-plugin-vue
、@typescript-eslint/parser
、@typescript-eslint/eslint-plugin
;
pnpm i eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin -D
修改项目根目录下的.eslintrc.json
配置文件;
{"env": {"browser": true,"es2021": true,"node": true,"vue/setup-compiler-macros": true},"extends": ["plugin:vue/vue3-essential","eslint:recommended","prettier","plugin:@typescript-eslint/recommended"],"parser": "vue-eslint-parser","parserOptions": {"ecmaVersion": "latest","sourceType": "module","parser": "@typescript-eslint/parser"},"plugins": ["vue", "prettier"],"rules": {"semi": ["warn", "never"]},"settings": {}
}
重启一下项目就可以了。
user.ts
文件
这个文件主要是用户的一些状态信息。
import { defineStore } from "pinia";
import NAMES from "./types";
import { User } from "../types/interface";// 用户
const user = defineStore(NAMES.user, {state: () => {return {userInfo: {id: 1,name: "mark",},};},getters: {getUserInfo(state) {return state.userInfo;},},actions: {saveUser(user: User) {this.userInfo = user;},},
});export default user;
上面简单做了个interface
的接口定义。
// ./src/types/interface.ts
// 用户信息
export interface User {id: number;name: string;
}
- 导入
main.ts
文件。
//...
import pinia from "./store";
// ...
app.use(pinia);
//...
配置 vue-i18n
在src
文件夹下面新建locale
文件夹,用了存放vue-i18n
配置信息。
包括zhCn.ts
、zhHk.ts
、en.ts
、lang.ts
、index.ts
等文件。
语言内容
- 中文简体 zhCn
const zhCn = {home: "首页",index: "主页",list: "列表",info: "信息",welcome: "欢迎光临",
};export default zhCn;
- 中文繁体 zhHk
const zhHk = {home: "首頁",index: "主頁",list: "清單",info: "資訊",welcome: "歡迎光臨",
};export default zhHk;
- 英文 en
// 英文
const en = {home: "Home",index: "Index",list: "List",info: "Info",welcome: "Welcome",
};export default en;
配置index.ts
- 导入
lang.ts
import zhCn from "./zhCn";
import zhHk from "./zhHk";
import en from "./en";export default {zhCn,zhHk,en,
};
- 导入
index.ts
import { createI18n } from "vue-i18n";
import messages from "./lang";const i18n: any = createI18n({locale: localStorage.getItem("lang") || "zhCn",globalInjection: true,legacy: false,messages,
});export default i18n;
tsconfig.json
中添加类型
{"compilerOptions": {// ..."types": ["vue-i18n"]}// ...
}
全局引入
在main.ts
中引入vue-i18n
。
// ...
import i18n from "./locale/index";
// ...
app.config.globalProperties.$i18n = i18n;
// ...
app.use(i18n);
接下来就可以在组件或者其他 ts 文件中使用了。
配置全局样式
在styles
文件夹中新建一个font.scss
和reset.css
样式文件,然后导入main.ts
文件中即可实现。
// ./src/main.ts
import "@s/reset.css";
import "@s/font.scss";
配置全局方法
- http 方法
在apis
文件夹中新建一个http.ts
文件,封装请求方法。
// ./src/apis/http.ts
import axios from "axios";// 创建axios实例
const http = axios.create({baseURL: "/",timeout: 30000,headers: {"Content-Type": "application/json",},
});// 请求拦截
http.interceptors.request.use((config) => {config.headers.version = "v1";return config;},(err) => {return Promise.reject(err);}
);// 响应拦截
http.interceptors.response.use((res) => {let data = res.data;return data;},(err) => {return Promise.reject(err);}
);export default http;
- util 方法
在apis
文件夹中新建一个util.ts
文件,封装请求方法。
// ./src/apis/util.ts
// 全局方法
import { AllAny } from "../types/interface";const sum = (a: number, b: number): number => a + b;const util: AllAny = {sum,
};export default util;
这里我又定义了util
的接口。
// 任意对象类型
export interface AllAny {[propsName: string]: any;
}
- mitt 方法
下面介绍以下如何配置mitt
。
在apis
文件夹下面新建一个mitts.ts
文件。
// ./src/apis/mitts.ts
import mitt, { Emitter } from "mitt";
import { MittEvents } from "../types/interface";const mitts: Emitter<MittEvents> = mitt<MittEvents>();export default mitts;
记得在interface.ts
声明以下类型。
// mitt类型
export type MittEvents = {[propsName: string]: any;
};
- 导入
main.ts
文件
// ./src/main.ts
// ...
import http from "./apis/http";
import util from "./apis/util";
import mitts from "./apis/mitts";
// ...
app.config.globalProperties.$http = http;
app.config.globalProperties.$util = util;
app.config.globalProperties.$mitts = mitts;
// ...
实战
在项目创建,安装依赖,配置全局环境结束后,写一个简单的组件案例。
组件组成
<!-- 组件模板 -->
<template></template>
<!-- 组件脚本 -->
<script lang="ts" name="Hello"></script>
<!-- 组件样式 -->
<style lang="scss" scoped></style>
小案例
下面是home.vue
组件中的一些小案例,可以练习一下。
- 模板内容
<!-- 计算属性 -->
<p><span>{{ sayHi }}</span>
</p>
<p><button type="button" @click="changeName">改变姓名</button>
</p>
<!-- 路由 -->
<p><button type="button" @click="goNotFound">到404</button>
</p>
<!-- 请求接口 -->
<p><button type="button" @click="getData">请求接口</button>
</p>
<p>接口数据:{{ msg }}</p>
<!-- 全局方法 -->
<p><input v-model="sumInfo.num1" type="number" name="num1" id="num1" placeholder="数字1" />+<input v-model="sumInfo.num2" type="number" name="num2" id="num2" placeholder="数字2" />= {{sumInfo.sum }}
</p>
<p><button type="button" @click="getSum">计算和</button>
</p>
<!-- 发送消息 -->
<p><button type="button" @click="sendMsg">发送消息</button>
</p>
- 引入依赖
import { reactive, ref, watch, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import userStore from "../store/user";
import { Store } from "pinia";
import { useCurrentInstance } from "../types/util";
import { AllAny } from "../types/interface";
- 定义数据
// 组件路由
const route = useRoute();
const router = useRouter();
console.log("route:", route, router);// 用户状态
const user: Store = userStore();
console.log("store:", user);// 组件数据
const msg: Ref = ref("");
console.log("data:", msg);const info = reactive({id: 1,name: "mark",
});
console.log("data:", info);const sumInfo = reactive({num1: 0,num2: 0,sum: 0,
});console.log("sum:", sumInfo);
- 定义方法
// 组件监听
watch(() => [info.name],(val: string[]) => {console.log("watch:", val);}
);// 组件计算
const sayHi = computed(() => {return `Hi,${info.name}!`;
});// 组件当前实例
const { proxy } = useCurrentInstance();
console.log("proxy:", proxy);// 改变姓名
function changeName() {info.name = "jack";
}// 到404
function goNotFound() {router.push("/404");
}// 请求接口
async function getData() {let data: AllAny = await proxy.$http.get("/todos/1");msg.value = data;console.log("http:", data);
}// 计算和
function getSum() {let sum: number = proxy.$util.sum(sumInfo.num1, sumInfo.num2);sumInfo.sum = sum;
}// 发送消息
function sendMsg() {proxy.$mitts.emit("user", "mark");
}
多语言案例
- 路由使用
import i18n from "../locale/index";
const trans = i18n.global.t;trans("home");
- 组件使用
import { useI18n } from "vue-i18n";
const { t } = useI18n();console.log(t("welcome"));
以上就是如何从零搭建一个 vue3+ts5+vue-router4+pinia2 的项目方法。
相关文章:
基于vue3+ts5+vue-router4+pinia2的PC端项目搭建教程
导语:在日常开发中,有时候会在项目中引入 ts 来解决一些 js 的问题,下面就简单介绍一下如何使用 vue3tsrouterpinia 来搭建一个项目。 目录 简介创建安装配置实战 简介 vue3 目前是常用的 vue 版本,提供了组合式 API 以及一些新…...

6个无版权、免费、高清图片素材库
找免费无版权图片素材,就上这6个网站,超高质量,可商用,赶紧收藏! 1、菜鸟图库 https://www.sucai999.com/pic.html?vNTYwNDUx 网站主要为新手设计师提供免费素材,这些素材的质量都很高,类别也…...
什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的 IE?
什么是响应式设计: 响应式设计(Responsive Design)是一种Web设计和开发方法,旨在使网站在不同设备和屏幕尺寸上都能提供一致的用户体验。响应式设计的目标是适应多种终端,包括桌面计算机、笔记本电脑、平板电脑和移动设备&#x…...
LeetCode 2906. 构造乘积矩阵【前后缀分解,数组】中等
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...

vue3+koa+axios实现前后端通信
vue3koaaxios实现前后端通信 写了一个小demo来实现前后端通信,涉及跨域问题,非常简单可以给大家平时开发的时候参考 服务端: 目录结构如下: router index.js // router的入口文件 // 引入路由 const Router require("koa-router&quo…...

Required MultipartFile parameter ‘file‘ is not present
出现这个原因我们首先想到的是加一个RequestParam("file"),但是还有可能的原因是因为我们的名字有错误 <span class"input-group-addon must">模板上传 </span> <input id"uploadFileUpdate" name"importFileU…...

vue3后台管理系统之layout组件的搭建
1.1静态布局 <template><div class"layout_container"><!-- 左侧导航 --><div class"layout_slider"></div><!-- 顶部导航 --><div class"layout_tabbar"></div><!-- 内容展示区 --><…...

Minio 文件上传(后端处理同文件判断,同一文件秒传)
记录minio 文件上传 MinIO提供多个语言版本SDK的支持,下边找到java版本的文档: 地址:https://docs.min.io/docs/java-client-quickstart-guide.html maven依赖如下: XML <dependency><groupId>io.minio</groupId…...

模拟IIC通讯协议(stm32)(硬件iic后面在补)
一、IIC基础知识总结。 1、IIC通讯需要两条线就可以,SCL、SDA。 2、IIC的数据传输的速率,不同的ic是不同的,根据电平维持的延时函数的时间来确定IIC数据传输的速率. 3、IIC的延时函数可以使用延时函数,延时函数一般使用系统滴答时…...
使用注解读取properties配置文件
文章目录 1、背景2、注解方式2.1 PropertySource 、 ConfigurationProperties2.2 读取properties中全部字段值ConfigurationProperties2.3 读取properties中部分字段值:value("${自定义key}") 1、背景 服务中使用到了redis,需要配置redis连接…...

Python---练习:求世界杯小组赛的总成绩(涉及:布尔类型转换为整型)
案例 世界杯案例 需求: 世界杯案例,世界杯小组赛的比赛规则是我们的球队与其他三支球队进行比赛,然后根据总成绩(积分)确定出线资格。小组赛球队实力已知(提示用户输入各球队实力),我们通过一个数字表示。如果我们赢…...

vue3学习源码笔记(小白入门系列)------KeepAlive 原理
目录 说明组件是如何被缓存的,什么时候被激活对于KeepAlive 中组件 如何完成激活的对于KeepAlive 中组件 如何完成休眠的 总结 说明 Vue 内置了 KeepAlive 组件,实现缓存多个组件实例切换时,完成对卸载组件实例的缓存,从而使得组…...

边写代码边学习之mlflow
1. 简介 MLflow 是一个多功能、可扩展的开源平台,用于管理整个机器学习生命周期的工作流程和工件。 它与许多流行的 ML 库内置集成,但可以与任何库、算法或部署工具一起使用。 它被设计为可扩展的,因此您可以编写插件来支持新的工作流程、库和…...

基于吉萨金字塔建造优化的BP神经网络(分类应用) - 附代码
基于吉萨金字塔建造优化的BP神经网络(分类应用) - 附代码 文章目录 基于吉萨金字塔建造优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.吉萨金字塔建造优化BP神经网络3.1 BP神经网络参数设置3.2 吉萨金字…...
axios的post请求所有传参方式
Axios支持多种方式来传递参数给POST请求。以下是一些常见的方式: 作为请求体: 你可以将参数作为请求体的一部分,通常用于发送表单数据或JSON数据。例如: const data { key1: value1, key2: value2 }; axios.post(/api/endpoint, …...
【c++】向webrtc学比较2: IsNewerSequenceNumber 用于NackTracker及测试
LatestSequenceNumber inline uint16_t LatestSequenceNumber(uint16_t sequence_number1,uint16_t sequence_number2) {return IsNewerSequenceNumber(sequence_number1, sequence_number2)? sequence_number1: sequen...

PRCV 2023:语言模型与视觉生态如何协同?合合信息瞄准“多模态”技术
近期,2023年中国模式识别与计算机视觉大会(PRCV)在厦门成功举行。大会由中国计算机学会(CCF)、中国自动化学会(CAA)、中国图象图形学学会(CSIG)和中国人工智能学会&#…...
深度学习硬件配置推荐(kaggle学习)
目录 1. 基础推荐2. GPU显存与内存是一个1:4的配比?3. deep learning 入门和kaggle比赛4. 有些 Kaggle 比赛数据集很大,可能需要更多的 GPU 显存,请推荐显存4. GDDR6和HBM25. HDD 或 SATA SSD 1. 基础推荐 假设您作为一个深度学习入门学者的…...

1019hw
登录窗口头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QToolBar> #include <QMenuBar> #include <QPushButton> #include <QStatusBar> #include <QLabel> #include <QDockWidget>//浮动窗口…...

两分钟搞懂UiAutomator自动化测试框架
1. UiAutomator简介 UiAutomator是谷歌在Android4.1版本发布时推出的一款用Java编写的UI测试框架,基于Accessibility服务。其最大的特点就是可以跨进程操作,可以使用UiAutomator框架提供的一些方便的API来对安卓应用进行一系列的自动化测试操作…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...