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

一篇文章带你快速上手Vue3(包含vue核心语法、router路由、axios请求库、pinia状态管理、ts类型约束等等)

目录

写在前面

一、什么是Vue

Vue的核心特性

Vue的两种API风格

二、快速开始

创建项目

单文件组件(SFC)

三、响应式基础

什么是响应式?

ref() - 包装基本类型

reactive() - 代理对象

选择指南

四、模板语法

文本插值 {{ }}

属性绑定 :

事件监听 @

条件渲染

列表渲染 v-for

双向绑定 v-model

五、计算属性与侦听器

computed - 缓存计算结果

watch - 监听变化执行副作用

watchEffect - 自动追踪依赖

六、组件基础

组件的概念

定义与使用组件

Props - 父传子

Emits - 子传父

v-model - 双向绑定

插槽 Slots - 内容分发

七、生命周期

什么是生命周期?

常用生命周期钩子

八、Vue Router - 路由管理

什么是路由?

核心概念

安装与配置

路由导航

路由守卫

九、Axios - HTTP请求

什么是Axios?

为什么需要封装?

安装与基础用法

封装请求实例(推荐)

封装API接口

在组件中使用

十、Pinia - 状态管理

为什么需要状态管理?

Pinia的核心概念

安装与创建Store

在组件中使用

修改State的三种方式

十一、组合式函数 - 逻辑复用

什么是组合式函数?

示例:useMouse

示例:useFetch

十二、TypeScript 支持

为什么使用TypeScript?

Props类型标注

Emits类型标注

Ref和Reactive类型

模板引用类型

十三、项目结构建议

总结


写在前面

Vue是一款渐进式JavaScript框架,核心功能是声明式渲染响应式更新。本文将直击要害,使用最精炼的语言讲解,让你看完就能看懂Vue代码并上手Vue开发。


一、什么是Vue

Vue的核心特性

1. 声明式渲染

传统的命令式编程需要手动操作DOM:获取元素→修改内容→更新样式。而Vue的声明式渲染让你只需描述"页面应该长什么样",Vue会自动将数据映射到DOM。

<!-- 声明式:描述数据和视图的关系 --> <p>{{ message }}</p> <!-- 数据变化时,Vue自动更新DOM,无需手动操作 -->

2. 响应性

Vue会自动追踪数据的变化,当数据改变时,所有依赖该数据的地方都会自动更新。这是通过Proxy代理对象实现的,你对数据的任何修改都会被捕获并触发更新。

Vue的两种API风格

风格

特点

适用场景

选项式API

按data、methods、computed等选项组织代码

小型项目、初学者

组合式API

按功能逻辑组织代码,使用函数式写法

中大型项目、逻辑复用

本文使用组合式API + 单文件组件(SFC),这是Vue 3推荐的标准开发方式。


二、快速开始

创建项目

# 使用官方脚手架创建Vue项目 npm create vue@latest

单文件组件(SFC)

Vue的单文件组件将模板、脚本、样式封装在一个.vue文件中:

  • <template>:HTML模板,使用Vue的模板语法
  • <script setup>:组件逻辑,setup表示使用组合式API
  • <style scoped>:组件样式,scoped表示仅作用于当前组件
<template> <!-- 模板:声明式渲染HTML --> <h1>{{ message }}</h1> </template> <script setup> // setup:使用组合式API的标识 import { ref } from "vue"; // ref():创建响应式数据 const message = ref("Hello Vue!"); </script> <style scoped> /* scoped:样式仅作用于当前组件 */ h1 { color: blue; } </style>

三、响应式基础

什么是响应式?

响应式是指数据变化时,依赖该数据的视图会自动更新。Vue 3使用Proxy实现响应式,可以追踪对象属性的读取和修改。

ref() - 包装基本类型

概念ref()将基本类型(string/number/boolean)包装成一个对象,使其具备响应性。包装后的值需要通过.value访问。

为什么需要包装?:JavaScript的基本类型是按值传递的,无法被追踪。ref将其包装成对象,通过属性访问器实现追踪。

<script setup> import { ref } from "vue"; // ref():将基本类型包装成响应式对象 const count = ref(0); function increment() { // script中访问需要.value count.value++; } </script> <template> <!-- 模板中自动解包,不需要.value --> <button @click="increment">{{ count }}</button> </template>

reactive() - 代理对象

概念reactive()接收一个对象,返回该对象的Proxy代理。代理会拦截属性的读取和设置操作,实现响应式。

与ref的区别reactive直接代理对象,不需要.value,但只能用于对象类型。

<script setup> import { reactive } from "vue"; // reactive():将对象转为响应式 const state = reactive({ count: 0, name: "Vue" }); function increment() { // reactive对象直接访问属性,不需要.value state.count++; } </script>

选择指南

场景

使用

原因

基本类型(string/number/boolean)

ref

reactive不支持基本类型

对象/数组

ref 或 reactive

ref内部用reactive包装对象

需要替换整个对象

ref

reactive替换对象会失去响应性

解构后保持响应性

ref

reactive解构需用toRefs


四、模板语法

文本插值 {{ }}

概念:双大括号是Vue的模板插值语法,会将里面的表达式结果渲染为文本。支持简单的JavaScript表达式。

<template> <!-- 显示数据 --> <p>{{ message }}</p> <!-- 支持表达式 --> <p>{{ count + 1 }}</p> <p>{{ isShow ? '是' : '否' }}</p> </template>

属性绑定 :

概念v-bind(简写:)用于将HTML属性与Vue数据绑定。当数据变化时,属性值自动更新。

<template> <!-- : 是 v-bind: 的简写,将属性与数据绑定 --> <img :src="imageUrl" /> <button :disabled="isDisabled">禁用</button> <!-- 对象语法:动态切换class --> <div :class="{ active: isActive, 'text-danger': hasError }"></div> </template>

事件监听 @

概念v-on(简写@)用于监听DOM事件。可以绑定方法或内联语句,$event可以访问原生事件对象。

<template> <!-- @ 是 v-on: 的简写,监听DOM事件 --> <button @click="handleClick">点击</button> <!-- 内联语句 --> <button @click="count++">+1</button> <!-- 传递参数 --> <button @click="handleSubmit($event, '参数')">提交</button> </template>

条件渲染

概念v-if根据条件决定是否渲染元素(条件为false时不创建DOM);v-show始终渲染,只是通过CSS控制显示隐藏。

选择:频繁切换用v-show(初始渲染开销大,切换开销小),条件很少改变用v-if(初始渲染开销小,切换开销大)。

<template> <!-- v-if:条件为false时不渲染DOM(切换开销大) --> <p v-if="isShow">显示</p> <p v-else>隐藏</p> <!-- v-show:始终渲染,只是切换display(初始开销大) --> <p v-show="isShow">总是渲染</p> </template>

列表渲染 v-for

概念v-for用于遍历数组或对象生成列表。:key是必需的性能优化项,帮助Vue识别哪些元素改变了,从而高效更新DOM。

<template> <!-- v-for:遍历数组/对象,:key是性能优化的必需项 --> <ul> <li v-for="(item, index) in list" :key="item.id"> {{ index }} - {{ item.name }} </li> </ul> </template> <script setup> import { ref } from "vue"; const list = ref([ { id: 1, name: "苹果" }, { id: 2, name: "香蕉" }, ]); </script>

双向绑定 v-model

概念v-model是语法糖,等价于:value+@input(或对应表单元素的属性+事件)。实现数据与视图的双向同步。

<template> <!-- v-model = :value + @input,实现双向数据绑定 --> <input v-model="message" /> <!-- 复选框:绑定boolean --> <input type="checkbox" v-model="isChecked" /> <!-- 单选:绑定选中的value --> <input type="radio" value="A" v-model="picked" /> <input type="radio" value="B" v-model="picked" /> </template> <script setup> import { ref } from "vue"; const message = ref(""); const isChecked = ref(false); const picked = ref("A"); </script>

五、计算属性与侦听器

computed - 缓存计算结果

概念computed用于定义基于其他数据计算得出的值。与普通函数的区别是:computed有缓存,只有依赖变化时才重新计算。

适用场景:需要根据现有数据派生出新数据,且不想重复计算时。

<script setup> import { ref, computed } from "vue"; const firstName = ref("张"); const lastName = ref("三"); // computed:基于依赖缓存结果,只有依赖变化才重新计算 const fullName = computed(() => { return firstName.value + lastName.value; }); // 可写的计算属性 const fullName2 = computed({ get: () => firstName.value + lastName.value, set: (val) => { [firstName.value, lastName.value] = val.split(" "); }, }); </script>

watch - 监听变化执行副作用

概念watch用于监听特定数据的变化,当数据变化时执行回调函数。适合执行异步操作或复杂逻辑。

与computed的区别:computed返回一个新值,watch执行副作用(不返回值)。

<script setup> import { ref, watch } from "vue"; const searchText = ref(""); const results = ref([]); // watch:监听数据源变化,执行副作用(如API请求) watch(searchText, async (newVal, oldVal) => { // newVal: 新值, oldVal: 旧值 if (newVal.length > 2) { results.value = await fetchSearchResults(newVal); } }); // 监听多个数据源 watch([foo, bar], ([newFoo, newBar], [oldFoo, oldBar]) => { // 同时监听foo和bar的变化 }); // 立即执行 + 深度监听 watch( someObject, (newVal) => { /* ... */ }, { immediate: true, deep: true } ); </script>

watchEffect - 自动追踪依赖

概念watchEffect会立即执行回调,并自动追踪回调中用到的所有响应式数据。当任何依赖变化时,回调会重新执行。

与watch的区别:watch显式指定监听源,watchEffect自动追踪;watch可以获取新旧值,watchEffect不能。

<script setup> import { ref, watchEffect } from "vue"; const userId = ref(1); const userData = ref(null); // watchEffect:自动追踪回调中用到的所有响应式依赖 // 组件挂载时立即执行,依赖变化时重新执行 watchEffect(async () => { // 用到了userId,自动建立依赖关系 const res = await fetch(`/api/users/${userId.value}`); userData.value = await res.json(); }); </script>

六、组件基础

组件的概念

组件是Vue的核心概念,将页面拆分成独立、可复用的模块。每个组件封装了自己的模板、逻辑和样式,可以像搭积木一样组合成完整应用。

定义与使用组件

概念:创建一个.vue文件即定义了一个组件,在父组件中导入即可使用。组件可以复用多次,每个实例有独立的状态。

<!-- ButtonCounter.vue --> <template> <button @click="count++">点击 {{ count }} 次</button> </template> <script setup> import { ref } from "vue"; const count = ref(0); </script>
<!-- 父组件中使用 --> <template> <ButtonCounter /> </template> <script setup> import ButtonCounter from "./ButtonCounter.vue"; </script>

Props - 父传子

概念:Props是父组件向子组件传递数据的机制。子组件通过defineProps声明接收哪些props,父组件通过属性绑定传递数据。

单向数据流:Props是只读的,子组件不能直接修改props,应该通过事件通知父组件修改。

<!-- 子组件:Child.vue --> <script setup> // defineProps:声明接收的props(编译器宏,无需导入) const props = defineProps({ title: String, // 基础类型校验 likes: { type: Number, default: 0 }, // 带默认值 author: { type: Object, required: true }, // 必传 status: { type: String, validator: (v) => ["success", "fail"].includes(v), // 自定义校验 }, }); </script> <template> <h3>{{ props.title }}</h3> </template>
<!-- 父组件传递 --> <template> <!-- 静态值 --> <Child title="标题" /> <!-- 动态绑定 --> <Child :title="dynamicTitle" :likes="count" /> </template>

Emits - 子传父

概念:子组件通过$emit触发自定义事件,父组件通过@事件名监听事件。这是子组件向父组件通信的主要方式。

<!-- 子组件 --> <script setup> // defineEmits:声明要触发的事件 const emit = defineEmits(["update", "delete"]); function handleUpdate() { // 触发事件,传递数据给父组件 emit("update", { id: 1, name: "新名称" }); } </script> <template> <button @click="handleUpdate">更新</button> </template>
<!-- 父组件监听 --> <template> <Child @update="handleUpdate" @delete="handleDelete" /> </template> <script setup> function handleUpdate(data) { console.log("收到更新:", data); } </script>

v-model - 双向绑定

概念v-model是Props和Emits的语法糖,实现父子组件的双向数据绑定。本质上是:modelValue+@update:modelValue

<!-- 子组件:CustomInput.vue --> <script setup> const props = defineProps(["modelValue"]); const emit = defineEmits(["update:modelValue"]); function onInput(e) { // 触发update:modelValue事件更新父组件数据 emit("update:modelValue", e.target.value); } </script> <template> <input :value="modelValue" @input="onInput" /> </template>
<!-- 父组件使用 --> <template> <!-- v-model是 :modelValue + @update:modelValue 的语法糖 --> <CustomInput v-model="message" /> </template>

插槽 Slots - 内容分发

概念:插槽允许父组件向子组件传递模板内容,实现组件的灵活复用。具名插槽可以分发内容到子组件的不同位置,作用域插槽可以让子组件向父组件传递数据。

<!-- 子组件:Card.vue --> <template> <div class="card"> <!-- 具名插槽:header --> <header> <slot name="header">默认标题</slot> </header> <!-- 默认插槽 --> <main> <slot>默认内容</slot> </main> <footer> <slot name="footer" :data="footerData"></slot> </footer> </div> </template> <script setup> const footerData = { date: "2024-01-01" }; </script>
<!-- 父组件使用 --> <template> <Card> <!-- #header 是 v-slot:header 的简写 --> <template #header> <h2>自定义标题</h2> </template> <!-- 默认插槽内容 --> <p>卡片内容</p> <!-- 作用域插槽:接收子组件传递的数据 --> <template #footer="{ data }"> <p>日期: {{ data.date }}</p> </template> </Card> </template>

七、生命周期

什么是生命周期?

生命周期是组件从创建到销毁的各个阶段。Vue提供了钩子函数,让你在这些阶段执行自定义逻辑。

常用生命周期钩子

钩子

触发时机

常用场景

onMounted

组件挂载到DOM后

发起API请求、操作DOM

onUpdated

数据更新后

响应数据变化后的操作

onUnmounted

组件销毁前

清理定时器、事件监听

<script setup> import { onBeforeMount, // DOM挂载前 onMounted, // DOM挂载后(常用:发起请求、操作DOM) onBeforeUpdate, // 数据更新前 onUpdated, // 数据更新后 onBeforeUnmount,// 组件卸载前 onUnmounted, // 组件卸载后(常用:清理副作用) } from "vue"; // 挂载:组件插入DOM onMounted(() => { console.log("组件已挂载,可以操作DOM"); }); // 卸载:组件从DOM移除 onUnmounted(() => { console.log("组件已卸载,清理定时器、事件监听等"); }); </script>

八、Vue Router - 路由管理

什么是路由?

路由是单页应用(SPA)中管理页面导航的机制。Vue Router通过URL映射到不同组件,实现无刷新页面切换。

核心概念

  • 路由(Route):URL路径与组件的映射关系
  • 路由器(Router):管理所有路由的实例
  • 路由视图(RouterView):渲染匹配组件的容器
  • 导航守卫:路由切换前后的拦截处理

安装与配置

npm install vue-router@4
// router/index.js import { createRouter, createWebHistory } from "vue-router"; const router = createRouter({ history: createWebHistory(), // history模式(无#)或createWebHashHistory(有#) routes: [ { path: "/", component: () => import("@/views/Home.vue") }, { path: "/about", component: () => import("@/views/About.vue") }, { path: "/user/:id", // 动态路由 component: () => import("@/views/User.vue"), meta: { requiresAuth: true } // 路由元信息 }, ], }); export default router;
// main.js import { createApp } from "vue"; import App from "./App.vue"; import router from "./router"; createApp(App).use(router).mount("#app");

路由导航

声明式导航:使用<router-link>组件,类似<a>标签但无刷新。

编程式导航:使用useRouter获取路由器实例,调用pushreplace等方法。

<template> <!-- router-link:声明式导航,类似<a>标签 --> <nav> <router-link to="/">首页</router-link> <router-link :to="{ name: 'User', params: { id: 123 } }">用户</router-link> </nav> <!-- router-view:路由匹配组件的渲染出口 --> <router-view /> </template> <script setup> import { useRouter, useRoute } from "vue-router"; const router = useRouter(); // 路由实例(用于编程式导航) const route = useRoute(); // 当前路由信息 // 编程式导航 function goToUser(id) { router.push(`/user/${id}`); // 字符串路径 router.push({ path: "/user", query: { id } }); // 带查询参数 router.push({ name: "User", params: { id } }); // 命名路由 router.replace("/home"); // 替换当前历史记录 router.back(); // 返回上一页 } // 获取路由参数 const userId = route.params.id; // 动态路由参数 /user/:id const query = route.query.search; // 查询参数 ?search=xxx </script>

路由守卫

概念:路由守卫是在路由切换前后执行的钩子函数,用于权限验证、数据预加载等。

// 全局前置守卫:路由跳转前执行 router.beforeEach((to, from, next) => { const isLoggedIn = localStorage.getItem("token"); // to: 目标路由, from: 来源路由 if (to.meta.requiresAuth && !isLoggedIn) { next("/login"); // 未登录,重定向到登录页 } else { next(); // 放行 } });

九、Axios - HTTP请求

什么是Axios?

Axios是一个基于Promise的HTTP库,用于浏览器和Node.js。它提供了简洁的API来发起HTTP请求,支持请求/响应拦截器、自动转换JSON等功能。

为什么需要封装?

实际项目中,直接调用axios会导致:

  • 重复配置baseURL、timeout等
  • 每个请求都要处理错误
  • 无法统一添加token等认证信息

因此需要封装统一的请求实例。

安装与基础用法

npm install axios
import axios from "axios"; // 基础请求 axios.get("/api/users").then((res) => console.log(res.data)); axios.post("/api/users", { name: "张三" }); // async/await const users = await axios.get("/api/users");

封装请求实例(推荐)

// utils/request.js import axios from "axios"; const request = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, // 基础URL timeout: 10000, // 超时时间 }); // 请求拦截器:在请求发送前处理(如添加token) request.interceptors.request.use((config) => { const token = localStorage.getItem("token"); if (token) config.headers.Authorization = `Bearer ${token}`; return config; }); // 响应拦截器:在收到响应后处理(如统一错误处理) request.interceptors.response.use( (res) => res.data, // 直接返回data (err) => { if (err.response?.status === 401) { window.location.href = "/login"; } return Promise.reject(err); } ); export default request;

封装API接口

// api/user.js import request from "@/utils/request"; export const getUsers = (params) => request.get("/users", { params }); export const getUserById = (id) => request.get(`/users/${id}`); export const createUser = (data) => request.post("/users", data); export const updateUser = (id, data) => request.put(`/users/${id}`, data); export const deleteUser = (id) => request.delete(`/users/${id}`);

在组件中使用

<script setup> import { ref, onMounted } from "vue"; import { getUsers, deleteUser } from "@/api/user"; const users = ref([]); const loading = ref(false); async function loadUsers() { loading.value = true; try { users.value = await getUsers({ page: 1 }); } finally { loading.value = false; } } async function handleDelete(id) { await deleteUser(id); await loadUsers(); // 删除后刷新列表 } onMounted(loadUsers); </script>

十、Pinia - 状态管理

为什么需要状态管理?

当多个组件需要共享数据时,通过Props层层传递(Prop Drilling)会变得复杂。状态管理库提供全局的、响应式的数据存储,任何组件都可以访问和修改。

Pinia的核心概念

  • Store:状态管理的单元,类似组件但只关注状态
  • State:响应式数据
  • Getters:计算属性,派生状态
  • Actions:修改状态的方法

安装与创建Store

npm install pinia
// stores/counter.js import { defineStore } from "pinia"; import { ref, computed } from "vue"; // defineStore(唯一ID, 函数) 创建store export const useCounterStore = defineStore("counter", () => { // State:响应式状态 const count = ref(0); // Getter:计算属性 const doubleCount = computed(() => count.value * 2); // Action:修改状态的方法 function increment() { count.value++; } return { count, doubleCount, increment }; });

在组件中使用

<script setup> import { useCounterStore } from "@/stores/counter"; import { storeToRefs } from "pinia"; const counter = useCounterStore(); // 直接解构会失去响应性,使用storeToRefs保持响应性 const { count, doubleCount } = storeToRefs(counter); // 方法可以直接解构 const { increment } = counter; </script> <template> <p>{{ count }} / {{ doubleCount }}</p> <button @click="increment">+1</button> </template>

修改State的三种方式

const counter = useCounterStore(); // 1. 直接修改(简单场景) counter.count++; // 2. $patch批量修改(多个状态) counter.$patch({ count: 10, name: "new" }); // 3. 通过Action修改(推荐,可包含业务逻辑) counter.increment();

十一、组合式函数 - 逻辑复用

什么是组合式函数?

组合式函数(Composables)是利用Vue组合式API封装可复用逻辑的函数。与Mixin相比,它更清晰、类型友好、无命名冲突。

命名约定:以use开头,如useMouseuseFetch

示例:useMouse

概念:将鼠标位置追踪逻辑封装成可复用的函数,任何组件都可以使用。

// composables/useMouse.js import { ref, onMounted, onUnmounted } from "vue"; export function useMouse() { const x = ref(0); const y = ref(0); function update(e) { x.value = e.pageX; y.value = e.pageY; } onMounted(() => window.addEventListener("mousemove", update)); onUnmounted(() => window.removeEventListener("mousemove", update)); return { x, y }; // 返回响应式状态 }
<script setup> import { useMouse } from "@/composables/useMouse"; const { x, y } = useMouse(); // 复用鼠标追踪逻辑 </script> <template> <p>鼠标: {{ x }}, {{ y }}</p> </template>

示例:useFetch

// composables/useFetch.js import { ref, watch } from "vue"; export function useFetch(url) { const data = ref(null); const error = ref(null); const loading = ref(false); async function fetch() { loading.value = true; try { const res = await fetch(url.value); data.value = await res.json(); } catch (e) { error.value = e.message; } finally { loading.value = false; } } // url变化时自动重新获取 watch(url, fetch, { immediate: true }); return { data, error, loading, refetch: fetch }; }

十二、TypeScript 支持

为什么使用TypeScript?

TypeScript为JavaScript提供静态类型检查,可以在编译时发现错误,提供更好的IDE支持(代码提示、重构等),增强代码可维护性。

Props类型标注

概念:使用接口(Interface)定义Props的结构,通过泛型传递给defineProps,实现类型检查和代码提示。

<script setup lang="ts"> // 定义Props接口 interface Props { title: string; // 必传 count?: number; // 可选 items: { id: number; name: string }[]; } // 泛型方式声明props const props = defineProps<Props>(); // 带默认值 const props2 = withDefaults(defineProps<Props>(), { count: 0, }); </script>

Emits类型标注

<script setup lang="ts"> // 定义Emits类型 const emit = defineEmits<{ change: [id: number]; // 事件名: [参数类型] update: [value: string]; }>(); emit("change", 123); // 类型检查:参数必须是number </script>

Ref和Reactive类型

<script setup lang="ts"> import { ref, reactive } from "vue"; // ref自动推断类型 const count = ref<number>(0); const status = ref<"loading" | "success">("loading"); // 定义接口 interface User { id: number; name: string; } const user = ref<User>({ id: 1, name: "" }); const user2 = reactive<User>({ id: 1, name: "" }); </script>

模板引用类型

<script setup lang="ts"> import { ref, onMounted } from "vue"; // 标注DOM元素类型 const inputRef = ref<HTMLInputElement | null>(null); onMounted(() => { inputRef.value?.focus(); // 类型安全访问 }); </script> <template> <input ref="inputRef" /> </template>

十三、项目结构建议

src/ ├── assets/ # 静态资源 ├── components/ # 公共组件 ├── views/ # 页面组件 ├── router/ # 路由配置 ├── stores/ # Pinia状态管理 ├── composables/ # 组合式函数 ├── api/ # 接口封装 ├── utils/ # 工具函数 ├── App.vue └── main.ts

总结

Vue 3 核心知识体系:

模块

核心API

作用

响应式

ref/reactive

创建响应式数据

模板

{{ }}/:/@/v-model

声明式渲染、绑定、事件

组件

Props/Emits/Slots

组件通信

计算

computed/watch

派生数据、副作用

路由

Vue Router

单页应用导航

请求

Axios

HTTP数据交互

状态

Pinia

全局状态管理

复用

Composables

逻辑复用

类型

TypeScript

类型安全

http://www.jsqmd.com/news/657261/

相关文章:

  • Excel公式美化器:终极免费工具,让复杂公式一目了然!
  • 【GitHub项目推荐--Agentic Design Patterns:AI Agent 架构设计的“中文版设计模式”】⭐⭐⭐⭐⭐
  • 如何快速将飞书文档转换为Markdown:终极解决方案指南
  • 中层已死,智能体在管你
  • MinerU 系列教程 第十三课:FastAPI 服务 - mineru-api 深度解析
  • 保姆级教程:在COMSOL中搞定压电晶体仿真,手把手教你设置旋转坐标系和欧拉角
  • Spotify广告拦截终极指南:BlockTheSpot如何让免费用户享受Premium体验?
  • 深入PCA9685数据手册:手把手教你用STM32的IIC调试其所有寄存器(附逻辑分析仪实测波形)
  • 10 分钟装好 Hermes,用 Profile 隔离你的“工作人格“和“生活人格“
  • Meta与博通续约至2029年,将推2纳米AI计算加速器,博通CEO转任顾问
  • Java大厂面试实录:互联网医疗场景下的核心技术栈问答解析
  • 终极指南:5分钟免费解锁Cursor AI Pro完整功能的完整解决方案
  • 从非结构化文档到智能知识图谱:llm-graph-builder 如何重塑企业知识管理
  • 用STM32CubeMX和HAL库点亮WS2812:新手避坑RGB灯珠颜色错乱的5个关键步骤
  • 别再手动造数据了!用Modbus Slave模拟从站,5分钟搞定PLC通讯调试
  • SITS2026 AI邮件引擎深度拆解:5类高频场景模板+2步调试法,即刻生成高回复率商务邮件
  • 计算机算法的生命周期的庖丁解牛
  • 豆瓣9.1,麻省理工经典概率论神作!读者看完疾呼“请扔掉你们学校自己编的概统教材!”
  • 若依WMS仓库管理系统:现代化仓储管理的完整解决方案
  • Hyperf方案 微服务拆分策略与实践
  • 【GitHub项目推荐--LingBot-Map:流式 3D 重建的几何上下文 Transformer】⭐⭐⭐⭐⭐
  • CSAPP 3e实验环境构建实战:从虚拟机到WSL的完整指南
  • 【研报317】2026年中国汽车行业趋势分析报告:新能源、智能网联、组合辅助驾驶重塑出行
  • 别再只盯着内存溢出了!从Unity崩溃日志中揪出AssetBundle.LoadAsset_Internal的真凶
  • 告别CAN总线焦虑:一文搞懂LIN协议在汽车车窗、车灯控制中的应用
  • 【零基础】在Ubuntu22.04上开始一个基于MotrixSim与MotrixLab的强化学习项目
  • Wand-Enhancer完全指南:免费解锁WeMod高级功能的终极解决方案
  • 算法训练营第四天|59.螺旋矩阵II
  • 亲测6款AI生成器,20分钟搞定6万字论文带数据分析 - 麟书学长
  • 2026年OpenClaw怎么搭建?3分钟腾讯云零技术安装OpenClaw及百炼Coding Plan步骤