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 其实就是批量解构对象
内部也是通过对象循环调用了toRef

const 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 的触发时机 默认为 pre

watchEffect((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

img
img
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(),
}
posted @   加利福尼亚的阳光  阅读(102)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
点击右上角即可分享
微信分享提示