vue3基础API
创建项目
vite create vite 项目名 --template 模板名
// 栗子
pp create vite@latest // 只包含vue3
pp create vue@latest // 可选择配置
// vue2
pp create vue@legacy
模板可参考
https://github.com/vitejs/vite/tree/main/packages/create-vite
以下内容皆使用 setup 语法糖
ref
用来给定义的基本数据类型绑定响应式数据,访问时需要加上 .value 的方式
template 会自动解析const title = ref('这只是一个标题') console.log(title.value) // 这只是一个标题
`获取 DOM 实例` `获取组件 DOM 必须在 onMounted 中 因为 setup 代替了原来的 created` `声明的变量需和 ref 一致` <Children ref="childrenRef" /> const ChildrenRef = ref(null)
reactive
用来给响应式数据绑定响应式数据, 可直接通过 .属性的方式进行访问
被普通解构的 reactive 会失去响应式const mode = reactive({ name: '张三', age: 18 }) console.log(mode.name) // 张三
toRef
toRef 是根据所绑定的值来决定是否具有响应式
toRef 其实就是用来给 响应式对象解构的const mode = reactive({ name: '张三', age: 18 }) const modeName = toRef(mode, 'name') `如果修改 mode 里被 toRef 解构出来的属性, 那么双方都会改变` `如果只是修改被解构出来的变量,则原对象不会有影响`
toRefs
toRefs 其实就是批量解构对象
内部也是通过对象循环调用了toRefconst mode = reactive({ name: '张三', age: 18 }) const { name, age } = toRefs(mode)
toRaw
将响应式对象修改为普通对象
const data = toRaw(toRawMode)
computed
计算属性
`基本写法` const sum = computed(() => o.value * 99) `完整写法 get set 方法` const sum = computed({ get() { return o.value * 99 }, set(newVal) { console.log('set') } })
watch
侦听
`侦听普通数据类型` `如果侦听的是一个完整的 reactive 对象,则会隐式的开启深度侦听(deep: true)` watch(reactiveObj, (newVal,oldVal) => { console.log(newVal, oldVal) })
侦听对象单一属性
需要将参数一以回调函数的形式传入,也需要手动开启 deep: true
如果侦听多个,就以数组形式传递watch(() => [obj.name, obj2.name], (newVal, oldVal) => { .... }, { deep: true } )
WatchEffect
会立即执行一次的侦听
有两个参数
参数一为 当被侦听的对象改变时 会先执行一次 function
参数二为 配置参数一 function 的触发时机 默认为 prewatchEffect((onInvalidate) => { console.log(num.value, '我是被侦听的值, 我会立即执行一次, 每次被修改我都会执行一次') onInvalidate(() => { console.log('如果 num 的值被改变了, 我会先执行一次') }) }, { // 参数二 flush: "post", // pre 组件更新前执行, sync 强制效果始终同步触发, post 组件更新后执行 onTrigger(e) { //作为一个调试工具,可在开发中方便调试 console.log('触发', e) } } )
defineProps
父组件传递子组件值的方式和vue2相同
接收父组件传递的值,无需引入可直接使用
// 直接结构 props 会失去响应式 const props = defineProps({ searchVal: { type: String, // 类型 // required: true, // 必传 default: '', // 默认值 // 自定义类型校验 // validator(value) { // The value must match one of these strings // return ['String', 'Number'].includes(value) // } } }) const { searchVal } = toRefs(props)
defineEmits
通过 defineEmits 注册自定义事件,再操作的时候触发 emits 调用我们注册的事件, 实现传参
父组件接收事件同vue2相同
子组件派发事件,无需引入
const emits = defineEmits(['changeParentName', 'update:age']) const Fn1 = () => { emits('changeParentName', '我不叫张三了') } const Fn2 = () => { emits('update:age', '我不再是18岁了') }
defineExpose
获取子组件的实例和内部属性(暴露出来的)
在 setup 模式下,所有的数据只是默认 return 给 template 使用,不会暴露到组件外,所以父组件是无法通过挂载 ref 变量获取到子组件内的数据
const name = ref('张三') const changeName = () => { name.value = '张三二号' } `将方法、变量暴露给父组件使用,父组件才可通过 ref API拿到子组件暴露的数据` defineExpose({ name, changeName })
provide / inject
provide 可以在祖先组件中指定我们想要提供给后代组件的数据或方法
inject 可以再后代组件中获取到祖先组件传递的数据和方法
需要引入
// provide const mode = ref({ name: '张三' }) const changeMode = () => { mode.value.name = '也不叫张三了' } // provide 提供两个参数 // 参数一 注入名 可以是一个字符串或是一个 Symbol // 参数二 提供的值 provide('provide', { mode, changeMode }) // inject // 参数一 注入名字 // 参数二 提供的默认值 // 在一些场景中,默认值可能需要通过调用一个函数或初始化一个类来取得。为了避免在用不到默认值的情况下进行不必要的计算或产生副作 用,我们可以使用工厂函数来创建默认值: // 默认值也可以是 const value = inject('message', '这是默认值') const { mode, changeMode } = inject('provide', () => new ExpensiveClass())
defineAsyncComponent
异步加载组件
`基本用法` const Children = defineAsyncComponent(() => import('...')) `加载与错误状态` const Children = defineAsyncComponent({ // 加载函数 loader: () => import('...'), // 加载中时使用的组件 loadingComponent: LoadingComponent, // 展示加载组件前的延迟时间 默认为 200s delay: 200. // 加载失败后展示的组件 errorComponent: ErrorComponent, // 如果提供了一个 timeout 时间限制,并超时了 // 也会显示这里配置的报错组件,默认值是:Infinity timeout: 3000 })
Suspense
Suspense 允许应用程序在等待异步组件时渲染一些其它内容
在 Vue2 中,必须使用条件判断(例如 v-if、 v-else等)来检查数据是否已加载并显示一些其它内容
在 Vue3 新增了 Suspense 了,就不必跟踪何时加载数据并呈现相应的内容。
Suspense插槽指定了 default(默认展示的组件) fallback(页面还未加载出来时展示的组件)
// AsyncChildren.vue <template> AsyncChildren </template> <script setup> import { getUserInfo } from "@/Api/user.js"; // 执行一个异步方法 await getUserInfo() </script> // parent.vue <template> <el-button type="primary" @click="AsyncChildrenIsShow = true" > 点击加载异步组件 </el-button> <Suspense v-if="AsyncChildrenIsShow"> <!-- 异步组件, 需要渲染的页面 --> <template #default> <AsyncChildren/> </template> <!-- 页面还未加载成功时展示的页面 --> <template #fallback> <div> loading...... </div> </template> </Suspense> </template> <script setup> import { ref, defineAsyncComponent } from 'vue' const AsyncChildren = defineAsyncComponent(() => import('./AsyncChildren.vue')) const AsyncChildrenIsShow = ref(false) </script>
自定义指令
在setup内以v开头的驼峰命名的自定义指令函数,会自动注入。
const vFocus = { mounted: (el) => el.focus(), }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?