Vue3核心语法
- 组合式API
- setup
- 组件名称
- 基本语法
- 响应式
- ref 与 reactive
- toRefs与toRef
- computed计算属性
- watch
- watchEffect
- 内置内容
- 内置的特殊属性ref、is、key
- 内置的特殊元素
组合式API
setup
组件名称
Vue3.3版本之后通过defineOptions直接在setup中声明组件选项,之前的版本需要通过安装插件来实现
- vite:
- defineOptions方法支持:
npm i unplugin-vue-define-options/vite -D
,然后配置plugins: [require('unplugin-vue-define-options/vite')()]
- name属性支持:
npm i vite-plugin-vue-setup-extend -D
,然后配置plugins: [require('vite-plugin-vue-setup-extend')()]
,来扩展组件的setup方法
- defineOptions方法支持:
- webpack:
- defineOptions方法支持:
npm i unplugin-vue-define-options/webpack -D
,然后配置plugins: [require('unplugin-vue-define-options/webpack')()]
- defineOptions方法支持:
基本语法
-
自定义指令:必须遵循的命名规范:v
指令名
Directive,模板使用:<h1 v-my-directive>This is a Heading</h1>
const vMyDirective = { beforeMount: (el) => { // 在元素上做些操作 } }
-
defineProps、defineEmits:不需要导入,且会随着
<script setup>
的处理过程一同被编译掉- defineProps 接收与 props 选项相同的值
- defineEmits 接收与 emits 选项相同的值
-
withDefaults:给 props 提供默认值
export interface Props { msg?: string labels?: string[] } const props = withDefaults(defineProps<Props>(), { msg: 'hello', labels: () => ['one', 'two'] })
-
defineExpose:显式指定在
<script setup>
组件中要暴露出去的属性,供父组件读取const a = 1 const b = ref(2) defineExpose({ a, b })
-
defineModel:声明一个双向绑定 prop,通过父组件的 v-model 来使用
<!-- 父组件 --> <Child v-model="myRef"></Child> <script setup> const myRef = ref() </script> <!-- 子组件 --> <script setup> const model = defineModel({ default: 1 }) </script>
-
defineOptions:直接在setup中声明组件选项,仅支持 Vue 3.3+
-
defineSlots:提供插槽名称和 props 类型检查的类型提示,仅支持 Vue 3.3+
-
useSlots、useAttrs:使用 slots 和 attrs,模板中直接通过 $slots 和 $attrs 来访问
-
顶层 await:
<script setup>
中可以使用顶层 await。结果代码会被编译成 async setup()<script setup> const post = await fetch(`/api/post/1`).then((r) => r.json()) </script>
响应式
ref 与 reactive
- ref:定义基本类型、对象类型的响应式数据,对象的value属性是响应式的
- 注意点:
- js中操作数据要加
.value
,模板中则不需要,因为在模板中使用的时候会自动解包。可以使用volar插件自动添加.value
- js中操作数据要加
- 注意点:
- reactive:定义对象类型
层级较深
的响应式数据,- 注意点:
- 给对象整体重新赋值会失去响应式,可以使用Object.assign去整体替换
- 注意点:
toRefs与toRef
将一个响应式对象中的每一个属性转换为ref对象
,3.3+开始支持
computed计算属性
-
只读:第一个参数为 getter 回调函数,返回一个只读的响应式 ref 对象
let myName = ref('wwv') let name = computed(() => { return myName.value.slice(0) })
-
可读可写:第一个参数为带有 get 和 set 函数的对象,创建一个可写的 ref 对象
let name = computed({ get() { return myName.value.slice(0) }, set(val) { const [str] = val.split(' ') myName.value = str + ' OO' } })
watch
侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数,默认是懒侦听的,即仅在侦听源发生变化时才执行回调函数
const refData = ref(0)
const reactData = reactive({ count: 0 })
- 第一个参数:侦听器的源
- 函数,监听函数返回的数据,即对象类型数据中某个属性:
watch(() => reactData.count, (count, prevCount) => {})
- ref 基本类型数据:
watch(refData, (data , prevData) => {})
- 响应式对象类型数据:
watch(reactData, () => {})
- 数组:
watch([reactData, refData], ([reactData, refData], [prevReactData, prevRefData]) => {})
- 函数,监听函数返回的数据,即对象类型数据中某个属性:
- 第二个参数:发生变化时要调用的回调函数
- 第三个参数:
- immediate:在侦听器创建时立即触发回调。第一次调用时旧值是 undefined
- deep:如果源是对象,强制深度遍历,以便在深层级变更时触发回调【监视的是地址值,需要关注对象内部数据】
- flush:调整回调函数的刷新时机
- onTrack / onTrigger:调试侦听器的依赖
- once:回调函数只会运行一次
watchEffect
立即运行一个函数,并响应式地追踪其依赖
与 watch 的区别:
- watch:要明确指出监视的数据
- watchEffect:不用明确指出监视的数据,函数中用到哪些就监视哪些
// watch实现
watch([refData, reactData], (val, oldval) => {
console.log(val, oldval)
})
// watchEffect实现
watchEffect(() => {
console.log(refData.value, reactData)
})
内置内容
内置的特殊属性ref、is、key
- key:主要作为 Vue 的虚拟 DOM 算法提示,在比较新旧节点列表时用于识别 vnode
- ref:用于注册元素或子组件的引用,可以是字符串或函数
- 如果用于
普通 DOM 元素
,引用将是元素本身
:<p ref="p">hello</p>
js:const p = ref()
- 如果用于
子组件
,引用将是子组件的实例
:<ChildComponent :ref="(el) => child = el" />
- 如果用于
- is:用于绑定动态组件
- 注意:用于原生 HTML 元素时,
<tr is="vue:my-row-component"></tr>
,加上vue:
前缀,Vue 就会把该元素渲染为 Vue 组件 - 用于组件:
<component :is="tabs[currentTab]"></component>
- 注意:用于原生 HTML 元素时,
内置的特殊元素
具有类似组件的特性,也是模板语法的一部分。但它们并非真正的组件,同时在模板编译期间会被编译掉。因此,它们通常在模板中用小写字母书写。
<component>
:用于渲染动态组件或元素的“元组件”<slot>
:表示模板中的插槽内容出口<template>
:当我们想要使用内置指令而不在 DOM 中渲染元素时,可以作为占位符使用