npm常用命令

以下是 npm(Node.js 的包管理工具)的常用简单命令详解,适合前端或 Node.js 初学者快速上手日常开发。

🏗 一、初始化项目

1
npm init

作用:引导创建 package.json 文件,记录项目信息和依赖包。

1
npm init -y

作用:快速创建 package.json 文件,跳过交互步骤。

📦 二、安装依赖包

安装到项目依赖(默认)

1
2
3
npm install <包名>
# 示例:
npm install express

等价于:

1
npm i <包名>

作用:将指定的包安装到项目的 node_modules 目录中,并更新 package.json 文件。
作用:将指定的包安装到项目的 node_modules 目录中。

安装为开发依赖(如测试、打包工具)

1
2
3
npm install <包名> --save-dev
# 示例:
npm install nodemon --save-dev

作用:将指定的包安装为开发依赖,通常用于测试、打包工具等。

全局安装(供系统任何位置使用)

1
2
3
npm install -g <包名>
# 示例:
npm install -g typescript

作用:将指定的包安装到全局,使其可以在命令行中直接使用。

📁 三、查看已安装的包

1
2
3
npm list
npm list --depth=0 # 只看顶层依赖
npm list -g --depth=0 # 查看全局安装包

❌ 四、卸载包

1
2
3
npm uninstall <包名>
# 示例:
npm uninstall express

作用:卸载指定的包,同时从 package.json 文件中移除依赖。

🔄 五、更新包

1
2
3
npm update <包名>
# 示例:
npm update express

作用:更新指定的包到最新版本,同时更新 package.json 文件。

📁 六、安装所有依赖

1
npm install

作用:根据 package.json 文件中的依赖项,安装所有项目依赖。

🧪 七、运行脚本命令

1
2
3
4
5
6
7
npm run <脚本名>
# 示例:
npm run start

npm run <脚本名>
# 示例:
npm run dev

👉 package.json 的 scripts 中定义的命令才能通过 npm run 执行。例如:

1
2
3
4
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
}

作用:执行 package.json 中 scripts 中定义的脚本命令。

🔍 八、搜索包

1
2
3
npm search <关键字>
# 示例:
npm search express

作用:搜索 npm 仓库中与关键字相关的包。

🧼 九、清理缓存(出错时使用)

1
npm cache clean --force

作用:清除 npm 的缓存,通常用于解决依赖安装问题。

🗑 十、删除 node_modules 和 package-lock.json(干净安装前常用)

1
2
rm -rf node_modules package-lock.json
npm install
我的第一个网页
你好,欢迎来到我的网页!
function changeColor() { const title = document.getElementById("title"); title.style.color = "blue"; // 点击按钮后把文字变成蓝色 }
body { font-family: Arial, sans-serif; text-align: center; margin-top: 100px; } #title { color: black; font-size: 32px; } button { padding: 10px 20px; font-size: 16px; cursor: pointer; }

title: OSI
date: 2025-05-12 19:45:13
tags:
- OSI
- 网络
categories: 网络
description: “OSI 七层模型”

🌐 总结对照表:

层级 名称 常见协议举例
7 应用层 HTTP, FTP, SMTP, DNS, SSH
6 表示层 TLS/SSL, JPEG, MPEG, GZIP
5 会话层 NetBIOS, RPC, SMB
4 传输层 TCP, UDP, SCTP
3 网络层 IP, ICMP, IGMP, IPSec
2 数据链路层 Ethernet, ARP, PPP, VLAN
1 物理层 RJ-45, IEEE 802.11, 光纤, 同轴电缆等

🧱 1. 物理层(Physical Layer)

作用:传输比特流(0 和 1),涉及硬件设备与物理介质
常见协议/标准:

  • Ethernet(以太网物理标准,如 100Base-T)
  • IEEE 802.11(WiFi 物理标准)
  • 光纤、同轴电缆等
  • RS-232(串行通信标准)

作用:在物理层上传输帧,处理 MAC 地址、差错检测等
常见协议/标准:

  • Ethernet(以太网帧封装)
  • ARP(地址解析协议)
  • PPP(点到点协议)
  • HDLC(High-Level Data Link Control)

🌐 3. 网络层(Network Layer)

作用:负责路由选择与 IP 寻址,实现跨网段通信
常见协议/标准:

  • IP(Internet Protocol,包括 IPv4、IPv6)
  • ICMP(Internet Control Message Protocol,ping 用的)
  • IGMP(Internet Group Management Protocol)
  • IPSec(用于安全传输的 IP 加密协议)

🌐 4. 传输层(Transport Layer)

作用:提供可靠的数据传输,确保数据包按序到达
常见协议/标准:

  • TCP(Transmission Control Protocol,可靠传输)
  • UDP(User Datagram Protocol)– 无连接、不可靠但高效
  • SCTP(Stream Control Transmission Protocol)

🌐 5. 会话层(Session Layer)

  • 作用:建立、管理和终止会话
    常见协议/标准:
  • NetBIOS(网络基本输入输出系统)
  • RPC(远程过程调用)
  • SMB(服务器消息块)

    注:现代网络中会话层通常和表示层、应用层一起实现。

🌐 6. 表示层(Presentation Layer)

作用:数据格式转换、加解密、压缩
常见协议/标准:

  • TLS/SSL(传输层安全协议)
  • JPEG(联合照片专家组)
  • MPEG(运动图像专家组)
  • GZIP、DEFLATE(压缩算法)

🌍 7. 应用层(Application Layer)

作用:面向用户,提供各种网络服务的接口
常见协议/标准:

  • HTTP(超文本传输协议)
  • FTP(文件传输协议)
  • SMTP(简单邮件传输协议)
  • DNS(域名系统)
  • SSH(安全外壳协议)

    注:应用层协议通常是网络服务的入口,如 HTTP、FTP、SMTP、DNS 等。

ref标签隔离

ref 标签隔离

示例

  • person.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script setup lang="ts">
import { ref } from "vue";
let title = ref(); // 用于存储ref标签内容
function shouLog() {
console.log(title.value);
}
</script>

<template>
<div class="person">
<h1 ref="title">中国</h1>
<button @click="shouLog">输出h1标签</button>
</div>
</template>

<style scoped>
.person {
background: #ccc;
padding: 20px 100px;
box-shadow: 0 0 10px skyblue;
border-radius: 10px;
/* margin: auto; */
}
</style>
  • App.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<script setup lang="ts" name="App">
//name是给组件起一个名字,方便调试
import person from "./components/person.vue";
import { ref } from "vue";

let title = ref();
function shouLog() {
console.log(title.value);
}
</script>

<template>
<div class="app">
<h1 ref="title">你好</h1>
<button @click="shouLog">打印</button>
</div>
<person />
</template>

<style scoped>
.app {
background: #ccc;
padding: 20px 100px;
box-shadow: 0 0 10px skyblue;
border-radius: 10px;
/* margin: auto; */
}
</style>

watch & watchEffect

watch


响应式对象

响应式对象

ref

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<script setup lang="ts" name="own123">
import { ref } from "vue";
// ref 是一个函数,返回一个基本类型的响应式对象

let name = ref("张三"); // 响应式数据
let age = ref(18);
let tel = "13888888888";
let address = "北京";
// const fixName = () => {name = '李四'}

// 方法
function ChangeName() {
name.value = "李四"; // .value 是访问响应式对象的方法
}
function addAge() {
age.value += 1;
}
function telNumber() {
alert(tel); // alert 是一个提醒框
}
</script>

<template>
<div class="own">
<h2>姓名: {{ name }}</h2>
<h2>年龄: {{ age }}</h2>
<h2>地址: {{ address }}</h2>
<button @click="ChangeName">修改名字</button>
<button @click="addAge">增加年龄</button>
<button @click="telNumber">查看联系方式</button>
</div>
</template>

<style scoped>
.own {
background: #ccc;
padding: 20px;
box-shadow: 0 0 10px skyblue;
border-radius: 10px;
margin: auto;
}
</style>

reactive

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<script setup lang="ts">
import { reactive } from 'vue'; // 导入 reactive 方法, 用于只能创建响应式对象和ref的区别就是,ref是单个值,reactive是对象
// 数据
let car = reactive({ brand: '奔驰', price: 100 })
let games = reactive([{ id: '1', name: '王者荣耀' }, { id: '2', name: '英雄联盟' }, { id: '3', name: '和平精英' }])
let obj = reactive({ a: { b: { c: 100 } } })
// 方法
function changeGame1() {
games[0].name = '和平精英'
}
function changeCar() {
Object.assign(car, { brand: '兰博基尼', price: 300 }) // Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
}
function changeName() {
car.brand = '宝马'
}
function changePrice() {
car.price += 10 // 修改响应式对象中的属性,会触发视图更新
}
function abc() {
obj.a.b.c = 200
}
</script>

<template>
<div class="student">
<h2>汽车信息{{ car.brand }}, 价值{{ car.price }}</h2>
<button @click="changePrice">涨价</button>
<button @click="changeName">换车</button>
<button @click="changeCar">换整辆车</button>
<!-- <br /> -->
<h2>游戏列表</h2>
<ul>
<li v-for="item in games" :key="item.id">{{ item.name }}</li> <!-- v-for 循环遍历 -->
</ul>
<button @click="changeGame1">修改游戏1</button>
<h2>测试{{ obj.a.b.c }}</h2>
<button @click="abc">测试 </button>
</div>

</template>

<style scoped>
.student {
background: #ccc;
padding: 20px;
box-shadow: 0 0 10px skyblue;
border-radius: 10px;
margin: auto;
}

li {
font-size: bolder;
}
</style>

两者区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<script setup lang="ts">
import { ref } from "vue"; // ref 也可以使用,但是 ref 是一个函数,返回一个基本类型的响应式对象 { ref, reactive } from 'vue'
// 数据
let car = ref({ brand: "奔驰", price: 100 });
let sum = ref(0);
// 方法

function changeName() {
// car.brand = '宝马'
car.value.brand = "宝马";
// console.log(car)
}
function changePrice() {
car.value.price += 10; // 修改响应式对象中的属性,会触发视图更新
}
function changeCar() {
// car = { brand: '兰博基尼', price: 300 } 页面是不更新的
// Object.assign(car, { brand: '兰博基尼', price: 300 }) // 修改响应式对象中的属性,会触发视图更新
// 用ref的话 car.value = { brand: '兰博基尼', price: 300 }
car.value = { brand: "兰博基尼", price: 300 };
}
function changeSum() {
sum.value += 1;
}
</script>

<template>
<div class="student">
<h2>汽车信息{{ car.brand }}, 价值{{ car.price }}</h2>
<button @click="changePrice">涨价</button>
<button @click="changeName">换车</button>
<button @click="changeCar">换车2</button>
<hr />
<h2>测试求和{{ sum }}</h2>
<button @click="changeSum">+1</button>
</div>
</template>

<style scoped>
.student {
background: #ccc;
padding: 20px;
box-shadow: 0 0 10px skyblue;
border-radius: 10px;
margin: auto;
}

li {
font-size: bolder;
}
</style>

toRefs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<script setup lang="ts">
// 数据
import { reactive, toRefs } from 'vue'
let student = reactive({
name: '张三',
age: 18,
})
let { name, age } = toRefs(student) // toRefs 不仅可以解构拿出数据,还可以作为响应式数据
console.log(name)
console.log(age)

// 方法
function changeName() {
name.value += '~'
}
function addAge() {
age.value += 1
}

</script>

<template>
<div class="student">
<h2>姓名: {{ name }}</h2>
<h2>年龄: {{ age }}</h2>
<button @click="changeName">修改名字</button>
<button @click="addAge">增加年龄</button>
</div>

</template>

<style scoped></style>

Vue2 vs Vue3

Vue 2 → Vue 3 迁移手册(Vite 版)

目标:把一个 Vue 2 项目(多半基于 webpack/CLI)迁到 Vue 3 + Vite,形成一份可复用的清单。文档按“先搭骨架 → 再替换语法 → 最后清扫”的顺序组织,配有对照、示例与常见坑。


0. 一句话总览(Checklist)

  1. 创建新骨架:用 Vite 初始化 Vue 3 项目 → 复制业务代码与静态资源。
  2. 替换生态vue-router@4、状态管理推荐 Pinia(或 vuex@4 保持 API 兼容)、@vue/test-utils@2、图标/组件库升级到 Vue 3 版。
  3. 全局 API 改造new Vue()createApp()Vue.use()app.use()Vue.prototypeapp.config.globalProperties过滤器(filters)移除
  4. 模板与语法v-model、插槽、事件与 emits、异步组件、Teleport/Suspense<script setup>
  5. Composition API 上车setup()ref/reactivecomputedwatch、生命周期钩子对照表。
  6. 构建与资源:Vite 配置、别名、环境变量、CSS 预处理、SVG、图片与静态资源、按需引入。
  7. 类型与质量:TypeScript(可选)、ESLint+Prettier、测试改造。
  8. 收尾:删除废弃 API、兼容性确认、生产部署与性能体检。

1. 初始化与目录结构

1.1 用 Vite 创建项目

1
2
3
4
5
6
# Node 版本建议 ≥ 18
npm create vite@latest my-app -- --template vue-ts # TS 模板(推荐)
# 或:--template vue 走 JS 模板
cd my-app
npm install
npm run dev

1.2 目录差异对照

  • Vue CLI(webpack)src/main.js + public/index.html + vue.config.js;环境文件 .env.*assets 由 webpack 处理。
  • Vite:零配置即开箱,入口 index.html 在项目根;配置文件 vite.config.ts;静态资源由原生 ESM 处理,public/ 下资源原样拷贝。

迁移策略:保留 Vue 3 + Vite 新项目结构,将旧项目 src/业务代码 分模块迁入;第三方库先留空,逐个替换。


2. 生态版本与依赖

2.1 核心依赖

1
2
3
4
5
6
7
8
9
10
11
12
{
"dependencies": {
"vue": "^3.x",
"vue-router": "^4.x",
"pinia": "^2.x" // 或使用 vuex@4 保持风格
},
"devDependencies": {
"vite": "^5.x",
"@vitejs/plugin-vue": "^5.x",
"typescript": "^5.x" // 若用 TS
}
}
  • 依赖安装位置:全部在项目根目录的 node_modules/,版本记录在 package.jsonpackage-lock.json/pnpm-lock.yaml

2.2 生态替换速查

分类 Vue 2 Vue 3(Vite)
路由 vue-router@3 vue-router@4(路由表语法小差异,createRouter
状态 vuex@3 Pinia(推荐)或 vuex@4
测试 @vue/test-utils@1 @vue/test-utils@2
组件库 Element UI, iView, … Element Plus, Naive UI, Arco, Ant Design Vue@3
图标 vue-awesome, font-awesome unplugin-icons@vicons/*Iconify

3. 全局启动方式与 API 变更

3.1 启动方式

Vue 2

1
2
3
4
// main.js
import Vue from "vue";
import App from "./App.vue";
new Vue({ render: (h) => h(App) }).$mount("#app");

Vue 3

1
2
3
4
// main.ts
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");

3.2 插件与全局对象

  • Vue.use(plugin)app.use(plugin)
  • Vue.prototype.$xxxapp.config.globalProperties.$xxx
  • Vue.mixin() 仍可用,但推荐以 composable 取代(见 §5.4)。
  • Filters 移除:模板内 {{ msg | upper }} 不再支持。替代:计算属性或全局方法。

3.3 生产提示与调试

1
2
3
4
5
const app = createApp(App);
app.config.errorHandler = (err, vm, info) => {
/* ... */
};
app.config.performance = import.meta.env.DEV;

4. 模板与指令变化

4.1 v-model

  • Vue 2:组件自定义 v-model 依赖 value + input 事件。
  • Vue 3:统一为 modelValue + update:modelValue,支持多 v-model
1
2
3
4
5
6
7
8
9
10
<!-- 父组件使用 -->
<MyInput v-model="username" />
<!-- 子组件 props/emit -->
<script setup lang="ts">
const props = defineProps<{ modelValue: string }>();
const emit = defineEmits<{ (e: "update:modelValue", v: string): void }>();
function onInput(v: string) {
emit("update:modelValue", v);
}
</script>

4.2 事件与 emits

  • 新增 emits 显式声明,提高类型与可维护性。
1
2
3
4
const emit = defineEmits<{
(e: "save"): void;
(e: "change", id: number): void;
}>();

4.3 插槽

  • 具名与作用域插槽语法更统一:<template #name="{ data }">

4.4 异步组件

1
2
import { defineAsyncComponent } from "vue";
const Foo = defineAsyncComponent(() => import("./Foo.vue"));

4.5 新内置:Teleport / Suspense

  • Teleport:将子内容渲染到 body/任意容器。
  • Suspense:为异步组件提供加载/兜底 UI(配合 <script setup async>)。

5. Composition API 与 <script setup>

5.1 生命周期对照

Vue 2 Vue 3
beforeCreate/created 合并进 setup()
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroy onBeforeUnmount
destroyed onUnmounted

5.2 响应式基础

1
2
3
4
5
6
7
8
import { ref, reactive, computed, watch } from "vue";
const count = ref(0);
const state = reactive({ items: [] as string[] });
const double = computed(() => count.value * 2);
watch(
() => state.items.length,
(n) => console.log(n)
);

5.3 <script setup> 极简范式

1
2
3
4
5
6
7
8
9
10
<script setup lang="ts">
import { ref } from "vue";
const msg = ref("hello");
function greet() {
msg.value = "hi";
}
</script>
<template>
<button @click="greet">{{ msg }}</button>
</template>
  • 自动 import defineProps/defineEmits/defineExpose;更少样板代码。

5.4 从 Mixins 迁到 Composables

  • 将通用逻辑写成函数模块:useXxx(),在多处复用且避免命名冲突。
1
2
3
4
// useFetch.ts
export function useFetch<T>(url: string) {
/* ...返回 data/error/loading */
}

6. 路由、状态与请求

6.1 vue-router@4

1
2
3
4
5
6
import { createRouter, createWebHistory } from "vue-router";
import Home from "@/views/Home.vue";
const routes = [{ path: "/", component: Home }];
export const router = createRouter({ history: createWebHistory(), routes });
// main.ts
createApp(App).use(router).mount("#app");
  • beforeRouteEnter 等路由守卫用法基本一致;元信息/懒加载保持原思路。

6.2 状态:Pinia(推荐)

1
2
3
4
5
6
7
8
9
10
// stores/user.ts
import { defineStore } from "pinia";
export const useUser = defineStore("user", {
state: () => ({ name: "" }),
actions: {
setName(n: string) {
this.name = n;
},
},
});
  • 若沿用 Vuex:升级到 vuex@4,API 与 Vue 2 相近。

6.3 请求:Axios 等库原封不动;建议以 插件 注入到 app.config.globalProperties 或以 composable 封装。


7. Vite 配置与资源处理

7.1 基础配置(vite.config.ts

1
2
3
4
5
6
7
8
9
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
export default defineConfig({
plugins: [vue()],
resolve: { alias: { "@": path.resolve(__dirname, "src") } },
server: { port: 5173, open: true },
build: { sourcemap: false, outDir: "dist" },
});

7.2 环境变量

  • 文件命名:.env.env.development.env.production
  • 访问:import.meta.env.VITE_API_BASE

7.3 CSS 与预处理器

  • 直接安装 sass/less/stylus 即可使用;全局样式可在 vite.config.ts 使用 css.preprocessorOptions 注入变量。

7.4 资源与 SVG

  • public/ 下资源以绝对路径 /xxx 引用;
  • 导入式资源:import logo from '@/assets/logo.png'
  • SVG 建议用 vite-svg-loaderunplugin-icons 进行组件化。

8. TypeScript 与校验/测试

8.1 TS 配置

  • tsconfig.json"moduleResolution": "bundler"(Vite 5+),"types": ["vite/client"]

8.2 ESLint + Prettier

  • 使用 @vue/eslint-config-typescript@vue/eslint-config-prettier;Vite 不做代码质量,交给 ESLint。

8.3 测试

  • 单元测试:vitest + @vue/test-utils@2
  • 端到端:Playwright/Cypress。

9. 常见坑与对照

  1. 过滤器不再支持 → 用计算属性/方法取代;或注册全局函数。
  2. 自定义 v-model 名称变更value/inputmodelValue/update:modelValue
  3. this 不可用(在 setup 中) → 使用闭包变量与 ref/reactive
  4. 全局事件总线new Vue() 作为 bus)→ 使用 mitt 或基于 pinia/路由通信。
  5. $listeners/$attrs 变化 → 使用 useAttrs()emitsdefineProps
  6. scopedSlots 改名 → 统一为 slots;模板中使用 # 语法。
  7. 异步组件写法Vue.component('Async', () => import(...))defineAsyncComponent
  8. v-ifv-for 同层:保持先后顺序,尽量避免同一元素并用;必要时包一层。
  9. IE 不再支持:如需旧浏览器兼容,使用现代构建 + 条件降级方案。
  10. 第三方库不兼容:优先寻找 Vue 3 分支或替代品;无法替换时考虑保留微前端/iframe 隔离。

10. 迁移示例(组件级)

10.1 v-model 组件从 Vue 2 → Vue 3

Vue 2(节选)

1
2
3
4
5
6
<template>
<input :value="value" @input="$emit('input', $event.target.value)" />
</template>
<script>
export default { props: { value: String } };
</script>

Vue 3

1
2
3
4
5
6
7
8
9
<template>
<input
:value="modelValue"
@input="(e) => emit('update:modelValue', e.target.value)" />
</template>
<script setup lang="ts">
const props = defineProps<{ modelValue: string }>();
const emit = defineEmits<{ (e: "update:modelValue", v: string): void }>();
</script>

10.2 Mixins → Composable

Vue 2 Mixin

1
2
3
4
5
6
export default {
created() {
this.fetch();
},
methods: { async fetch() {} },
};

Vue 3 Composable

1
2
3
4
5
6
7
8
9
export function useLoad() {
const loading = ref(false);
async function fetch() {
loading.value = true;
/* ... */ loading.value = false;
}
onMounted(fetch);
return { loading, fetch };
}

11. 打包与部署(Vite)

1
npm run build   # 产物默认在 dist/
  • 默认生成 原生 ESM 静态资源,部署到任意静态服务器(Nginx/Netlify/Vercel)即可。

  • 若有 后端接口

    • 开发期用 server.proxy 解决跨域;
    • 生产期由网关/Nginx 反向代理。

12. YAML/CI(可选)

  • GitHub Actions:构建脚本样例
1
2
3
4
5
6
7
8
9
10
11
12
13
name: build
on: [push]
jobs:
web:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with: { name: dist, path: dist }

13. 迁移节奏建议

  1. 先能跑:空壳 + 路由 + 首页。
  2. 先公共后业务:先迁公共组件与基础设施(路由、状态、请求封装),再迁页面功能。
  3. 边迁边对照:每迁完一个模块就编译、路由走一遍、记录改造点。
  4. 留后手:对不兼容的第三方包可以先隔离或临时降级,完成功能再替换。

14. 附录:关键对照表

14.1 全局 API 对照

Vue 2 Vue 3
new Vue() createApp()
Vue.use() app.use()
Vue.mixin() app.mixin()
Vue.directive() app.directive()
Vue.component() app.component()
Vue.prototype.$xxx app.config.globalProperties.$xxx

14.2 生命周期钩子对照(再次汇总)

createdsetup()mountedonMounteddestroyedonUnmounted 等。


结束语

迁移并不神秘:建新骨架 → 按清单替换 → 逐步验证。这份文档可做你团队的“过线标准”,每次迁完一个模块就对照打勾,稳扎稳打。

css 渐变字体

css 修改渐变字体

1
2
3
4
5
.text-gradient {
background: linear-gradient(to right, purple, blue);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}