1. 首先安装node环境
1.1 nvm安装
- 管理员运行安装 nvm-setup.exe
- nvm 国内镜像 复制粘贴下面的代码
node_mirror: https://npmmirror.com/mirrors/node/
npm_mirror: https://npmmirror.com/mirrors/npm/
1.2 安装node
//执行下面的代码
nvm -v
nvm list available //查看自己想要安装的node版本
nvm install 20.18.0
nvm use 20.18.0
node -v
npm -v
//nvm常用命令
nvm version // 查看NVM版本,是否安装成功
nvm list available // 查看可安装的node版本
nvm list // 查看已安装的node版本
nvm install 版本号 // 安装node
nvm uninstall 版本号 // 卸载node
nvm use 版本号 // 切换使用node版本
nvm current // 当前使用node版本
nvm node_mirror [url] // 切换node镜像[https://npm.taobao.org/mirrors/node/]
nvm npm_mirror [url] // 切换npm镜像[https://npm.taobao.org/mirrors/npm/]
nvm alias default version // 设置默认版本
1.3 安装npm的镜像,加快构建速度
//目前可用 (2025.7月)
//淘宝镜像
npm config set registry https://registry.npm.taobao.org
npm config set registry https://registry.npmmirror.com
//使用腾讯云镜像
npm config set registry https://mirrors.cloud.tencent.com/npm/
//或使用官方npm源(科学上网)
npm config set registry https://registry.npmjs.org/
1.4 报错处理
vite
项目启动报错问题:failed to load config from D\...\...vite.config.js
错误
vite报错.png
解决办法:查找package.json内对应的vite版本进行安装
npm install -D vite@^版本号
安装成功后,可执行 npm run dev
命令启动文件
2.使用vite构建vue3项目
2.1具体操作如下
npm create vue@latest
npm i
npm run dev
2.2 报错注意和处理:
1.png
//npm i 报错处理
npm error code CERT_HAS_EXPIRED
npm error errno CERT_HAS_EXPIRED
request to https://registry.npm.taobao.org/@vitejs%2fplugin-vue failed, reason: certificate has expired
更换镜像地址
npm cache clean --force
npm config set registry https://mirrors.cloud.tencent.com/npm/
3. 封装一个组件
- 组件
<template>
<!-- 组件模板 -->
<div class="my-component">
<!-- 组件内容 -->
<div class="card">
<header v-if="$slots.header" class="card-header">
<slot name="header"></slot>
</header>
<div class="card-body">
<slot></slot> <!-- 默认插槽 -->
</div>
<footer v-if="$slots.footer" class="card-footer">
<slot name="footer"></slot>
</footer>
</div>
</div>
</template>
<script setup>
const props = defineProps({
// 基础类型检查
title: {
type: String,
required: true
},
// 多个可能的类型
value: {
type: [String, Number],
default: ''
},
// 带有默认值的对象
config: {
type: Object,
default: () => ({})
},
// 自定义验证函数
validator: {
type: Function,
default: (value) => value > 0
}
})
// 组件逻辑
const emit = defineEmits(['update:modelValue', 'submit', 'cancel'])
function handleClick() {
emit('submit', { data: 'some data' })
}
</script>
<style scoped>
/* 组件样式 */
.my-component {
/* 样式规则 */
}
</style>
4、Vue 3 父子组件传值详解
在 Vue 3 中,父子组件之间的数据传递主要通过 props(父传子)和 emits(子传父)实现。以下是完整的父子组件传值方法:
1. 父组件向子组件传值 (Props)
基本用法
父组件:
<template>
<ChildComponent :title="parentTitle" :count="parentCount" />
</template>
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'
const parentTitle = ref('这是父组件的标题')
const parentCount = ref(0)
</script>
子组件:
<template>
<div>
<h2>{{ title }}</h2>
<p>计数: {{ count }}</p>
</div>
</template>
<script setup>
// 定义 props
const props = defineProps({
title: {
type: String,
required: true
},
count: {
type: Number,
default: 0
}
})
</script>
Props 验证
可以指定 props 的类型、默认值和验证函数:
defineProps({
// 基础类型检查
age: Number,
// 多个可能的类型
id: [String, Number],
// 必填的字符串
username: {
type: String,
required: true
},
// 带有默认值的数字
size: {
type: Number,
default: 100
},
// 自定义验证函数
email: {
validator(value) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
}
}
})
2. 子组件向父组件传值 (Emits)
基本用法
子组件:
<template>
<button @click="handleClick">通知父组件</button>
</template>
<script setup>
// 定义 emits
const emit = defineEmits(['updateCount', 'sendMessage'])
function handleClick() {
// 触发事件并传递数据
emit('updateCount', 5)
emit('sendMessage', { text: 'Hello from child' })
}
</script>
父组件:
<template>
<ChildComponent
@update-count="handleUpdateCount"
@send-message="handleMessage"
/>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue'
function handleUpdateCount(newCount) {
console.log('接收到新计数:', newCount)
}
function handleMessage(payload) {
console.log('接收到消息:', payload.text)
}
</script>
使用 v-model 实现双向绑定
Vue 3 支持多个 v-model 绑定:
子组件:
<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</template>
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>
父组件:
<template>
<ChildComponent v-model="inputValue" />
<!-- 等同于 -->
<ChildComponent
:modelValue="inputValue"
@update:modelValue="newValue => inputValue = newValue"
/>
</template>
<script setup>
import { ref } from 'vue'
const inputValue = ref('')
</script>
多个 v-model 绑定
子组件:
<template>
<input
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"
/>
<input
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"
/>
</template>
<script setup>
defineProps(['firstName', 'lastName'])
defineEmits(['update:firstName', 'update:lastName'])
</script>
父组件:
<template>
<ChildComponent
v-model:firstName="first"
v-model:lastName="last"
/>
</template>
<script setup>
import { ref } from 'vue'
const first = ref('')
const last = ref('')
</script>
3. 其他通信方式
使用 ref 访问子组件
父组件:
<template>
<ChildComponent ref="childRef" />
<button @click="callChildMethod">调用子组件方法</button>
</template>
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'
const childRef = ref(null)
function callChildMethod() {
childRef.value.childMethod()
}
</script>
子组件:
<script setup>
// 暴露方法给父组件
defineExpose({
childMethod: () => {
console.log('子组件方法被调用')
}
})
</script>
使用 provide/inject (跨层级通信)
祖先组件:
<script setup>
import { provide } from 'vue'
provide('theme', 'dark')
provide('user', {
name: 'John',
age: 30
})
</script>
后代组件:
<script setup>
import { inject } from 'vue'
const theme = inject('theme', 'light') // 第二个参数是默认值
const user = inject('user')
</script>
4. 最佳实践
- 单向数据流:props 应该是单向向下传递的,子组件不应该直接修改 props
-
明确命名:自定义事件名使用 kebab-case (如
update-count
) - 适度使用:简单通信用 props/emits,复杂状态考虑 Pinia 等状态管理工具
- 类型安全:使用 TypeScript 可以增强 props 和 emits 的类型检查
<script setup lang="ts">
// 使用 TypeScript 的示例
interface User {
id: number
name: string
}
const props = defineProps<{
title: string
users: User[]
isActive?: boolean
}>()
const emit = defineEmits<{
(e: 'update:title', value: string): void
(e: 'select', user: User): void
}>()
</script>
通过以上方法,你可以灵活地在 Vue 3 父子组件之间传递数据和通信。