vue3<script setup>

vue3支持选项式 API 和组合式 API

两种 API 风格都能够覆盖大部分的应用场景。它们只是同一个底层系统所提供的两套不同的接口。实际上,选项式 API 是在组合式 API 的基础上实现的!

  • 选项式 API 以“组件实例”的概念为中心 (即上述例子中的 this ),对于有面向对象语言背景的用户来说,这通常与基于类的心智模型更为一致。同时,它将响应性相关的细节抽象出来,并强制按照选项来组织代码,从而对初学者而言更为友好。
  • 组合式 API的核心思想是直接在函数作用域内定义响应式状态变量,并将从多个函数中得到的状态组合起来处理复杂问题。这种形式更加自由,也需要你对 Vue的响应式系统有更深的理解才能高效使用。相应的,它的灵活性也使得组织和重用逻辑的模式变得更加强大。
// index.html
<div id="app"></div>

//main.js
import { createApp } from 'vue'
// 从一个单文件组件中导入根组件
import App from './App.vue'
createApp(App).mount('#app')
  • mount(‘#app’)函数返回值是根组件实例,该函数接收一个“容器”参数,可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串,该函数应该始终在整个应用配置和资源注册完成后被调用。
  • createApp(App)函数返回值是应用实例,应用实例必须在调用了 mount() 函数后才会渲染出来,可以利用应用实例做些项目应用配置。
    在这里插入图片描述

<script setup>

<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用 SFC 与组合式 API 时该语法是默认推荐。相比于普通的 <script> 语法,它具有更多优势:

  • 更少的样板内容,更简洁的代码。
  • 能够使用纯 TypeScript 声明 props 和自定义事件。
  • 更好的运行时性能 (其模板会被编译成同一作用域内的渲染函数,避免了渲染上下文代理对象)。
  • 更好的 IDE 类型推导性能 (减少了语言服务器从代码中抽取类型的工作)。
<script setup>
 // 逻辑代码
</script>

<script setup>里面的代码会被编译成组件 setup() 函数的内容。这意味着与普通的 <script> 只在组件被首次引入的时候执行一次不同,<script setup> 中的代码会在每次组件实例被创建的时候执行。
当使用 <script setup> 的时候,任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用。
<script setup> 可以和普通的 <script> 一起使用,声明无法在 <script setup> 中声明的选项。

  • 例如 inheritAttrs 或插件的自定义选项。
  • 声明模块的具名导出 (named exports)。
  • 运行只需要在模块作用域执行一次的副作用,或是创建单例对象。
<script>
// 普通 <script>, 在模块作用域下执行 (仅一次)
runSideEffectOnce()
// 声明额外的选项
export default {
  inheritAttrs: false,
  customOptions: {}
}
</script>

<script setup>
// 在 setup() 作用域中执行 (对每个实例皆如此)
</script>

import 导入组件,重命名组件,命名空间组件,动态组件,递归组件

// FooBar.vue 文件
<script setup>
import MyComponent from './MyComponent.vue'
import Foo from './Foo.vue'
import Bar from './Bar.vue'
import * as Form from './form-components' // as重命名
</script>
<template>
// 递归组件
<FooBar/>
// import 导入的组件名应当被理解为像是在引用一个变量。
  <MyComponent />
  // 动态组件使用:is 绑定变量(组件名)
  <component :is="Foo" />
  <component :is="someCondition ? Foo : Bar" />
  // 命名空间组件,可以使用带 . 的组件标签,例如 <Foo.Bar> 来引用嵌套在对象属性中的组件。
 <Form.Input>
   <Form.Label>label</Form.Label>
 </Form.Input>
</template>

defineProps() 和 defineEmits()

defineProps 和 defineEmits 都是只能在 <script setup> 中使用的编译器宏。他们不需要导入,且会随着 <script setup> 的处理过程一同被编译掉,传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的作用域。因此,传入的选项不能引用在 setup 作用域中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块作用域内。

<script setup lang="ts">
// 不需要导入,defineProps()只能在setup顶层作用域使用,不能在局部函数中使用,props可以在局部函数中使用。
const props = defineProps({
  foo: String
})
const props = defineProps(['soo'])
// 不需要导入,defineEmits()只能在setup顶层作用域使用,不能在局部函数中使用,emits可以在局部函数中使用。
const emits = defineEmits(['change', 'delete'])
// withDefaults()函数用于给ts提供类型声明和默认值。
interface Props {
  msg?: string
  labels?: string[]
}
const props = withDefaults(defineProps<Props>(), {
  msg: 'hello',
  labels: () => ['one', 'two']
})
</script>

defineExpose()

使用 <script setup> 的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定。

<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
const c = () => {console.log('hhh')}
defineExpose({
  a,b,c
})
</script>

defineOptions() vue3.3+版本

这个宏可以用来直接在 <script setup> 中声明组件选项,而不必使用单独的 <script> 块,选项将会被提升到模块作用域中,无法访问 <script setup> 中不是字面常数的局部变量。

<script setup>
defineOptions({
  inheritAttrs: false,
  customOptions: {
    /* ... */
  }})
</script>

defineSlots() TS专用类型提示 vue3.3+版本

<script setup lang="ts">
const slots = defineSlots<{
  default(props: { msg: string }): any
}>()
</script>

useSlots() 和 useAttrs()

在模板中直接通过 $slots 和 $attrs 来访问,在<script setup>中使用useSlots()和useAttrs()函数。

<script setup>
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
</script>

顶层 await

<script setup> 中可以使用顶层 await。结果代码会被编译成 async setup()

ref()全家桶,reactive()全家桶,工具函数

  • ref() 接受所有类型数据,返回一个深层次响应式的、可更改的 ref 对象。此 ref 对象只有一个指向其内部值的属性 .value。ps:ref对象在template模板会自动解包,不需要.value,ref属性配合ref()函数可以返回dom元素和组件实例。
import { ref } from 'vue'
let num = ref(1)
let p = ref(null)
let list = []
let getList = (el) => {
	list.push(el) 
}
<template>
<p ref="p">{{ num }}</p>
<ul>
   <li v-for="i in 3" :key="index" :ref="getList"></li>
 </ul>
</template>
  • shallowRef() 接受所有类型数据,返回一个浅层次响应式的、可更改的 ref 对象。此 ref 对象只有一个指向其内部值的属性 .value。ps:shallowRef()和ref()在同一作用域中使用,ref()更新,shallowRef()也会更新,即使深层次嵌套未代理的属性也会更新。原理:ref()底层调用triggerRef(),shallowRef()底层不调用triggerRef(),而triggerRef()会强制触发收集的依赖,所以shallowRef()依赖也会触发。
  • triggerRef() 强制触发依赖于一个浅层响应式 ref 对象的副作用,这通常在对浅引用的内部值进行深度变更后使用。
<script setup>
import { shallowRef, triggerRef, watchEffect } from 'vue'
let stupid = shallowRef({
age:12
})
watchEffect(() => {
    console.log(stupid.value.age)
})
stupid.value.age = 16 // watchEffect监视不到age变化
triggerRef(stupid)  // watchEffect监视到age变化
</script>
  • toRef() 可以将值、refs 或 getters 规范化为 refs (vue3.3+版本)。也可以基于响应式对象上的一个属性,创建一个对应的 ref对象。这样创建的 ref 对象与其源属性保持同步:改变源属性的值将更新 ref对象 的值,反之亦然,即使源属性当前不存在,toRef() 也会返回一个可用的 ref对象。
<script setup>
import { reactive, toRef, ref } from 'vue'
let num = 0
let num1 = ref(1)
let num2 = reactive({
    age: 18
})
let c = toRef(num2.age) // 等价与 let c = ref(num2.age)与源响应式对象没有联系
let d = toRef(num2, 'age')
let e = toRef(num1, 'value')
let f = toRef(() => num2.age) // 只读属性,不能修改,修改控制台会报错 ,vue3.3+版本
let g = toRef(num) // 等价与 let g = ref(num)
c.value = 3 // 源响应式对象num2.age不改变
d.value = 4 // 源响应式对象num2.age同步改变
e.value = 5 // 源响应式对象num1.value同步改变
num1.value = 7 // e.value同步改变
num2.age = 8 // d.value同步改变
</script>
  • toRefs() 将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref对象。每个单独的 ref 对象都是使用 toRef() 创建的,和toRef() 有相同特性。唯一不同,源属性不存在,不会创建对应的ref对象。
<script setup>
import { reactive, toRefs } from 'vue'
function useFeature() {
    const state = reactive({
        foo: 1,
        bar: 2
    })
    // ...基于状态的操作逻辑
    return toRefs(state) // 在返回时state所有属性都转为ref对象。
}
const { foo, bar } = useFeature() // 可以解构而不会失去响应性,通过foo.value获取相应的值
</script>
  • customRef() 创建一个自定义的 ref,显式声明对其依赖追踪和更新触发的控制方式,customRef() 预期接收一个工厂函数作为参数,这个工厂函数接受 track 和 trigger 两个函数作为参数,并返回一个带有 get 和 set 方法的对象,一般来说,track() 应该在 get() 方法中调用,而 trigger() 应该在 set() 中调用。然而事实上,你对何时调用、是否应该调用他们有完全的控制权。
<script setup>
// 官网防抖案例
import { customRef } from 'vue'
function useDebouncedRef(value, delay = 200) {
  let timeout
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          value = newValue
          trigger()
        }, delay)
      }
    }
  })
}
const text = useDebouncedRef('hello')
</script>
<template>
  <input v-model="text" />
</template>
  • isRef() 检查某个值是否为 ref响应式对象。
<script setup>
import { ref, reactive } from 'vue'
let a = reactive({
age:18
})
let c = ref(1)
isRef(c) // true
isRef(c.value) // false
isRef(a) // false
isRef(a.age) // false
</script>
  • unref() 如果参数是 ref响应式对象,则返回内部值,否则返回参数本身,内部原理类似:val = isRef(val) ? val.value : val,ps:不能直接引用修改数据,要通过val.value方式修改数据。
<script setup>
import { unref } from 'vue'
let a = reactive({
age:18
})
let b = {
age:12
}
let c = ref(1)

let d = unref(c) // unref(c)函数返回值是响应式数据ref对象c.value值,d不是响应式数据。
let f = unref(a) // unref(a)函数返回值是reactive()响应式对象,f是reactive()响应式对象。
let g = unref(a.age) // unref(a.age)函数返回值是响应式数据,d不是响应式数据
</script>

reactive()全家桶

  • reactive() 接受引用类型数据,返回一个对象的响应式代理。响应式转换是“深层”的:它会影响到所有嵌套的属性。一个响应式对象也将深层地解包任何 ref 属性,同时保持响应性。值得注意的是,当访问到某个响应式数组或 Map 这样的原生集合类型中的 ref 元素时,不会执行 ref 的解包。ps:数组类型不能直接进行赋值操作,要用数组上的方法。
<script setup>
import { reactive, ref } from 'vue'
// 创建深层响应式reactive()对象
let a = reactive({
age:18
})
let b = ref(1)
 // 取值是c.value = 1,b.value和c.value链接修改其中一个,另一个同步修改,并且ref对象解包,不需要c.b.value。
let c = reactive(b)
let d = reactive({})
d.value = b // 和上面相同,进行链接。并且ref对象解包,不需要d.value.value。
let e = reactive([ref(5)])
console.log(e[0].value) // ref对象不会解包,需要.value。
</script>
  • shallowReactive() reactive() 的浅层作用形式。ps:shallowReactive()和reactive()在同一作用域中使用,reactive()更新,shallowReactive()也会更新,即使深层次嵌套未代理的属性也会更新。
<script setup>
import { shallowReactive } from 'vue'
// 创建浅层响应式reactive()对象
let a = shallowReactive({
age:18
name: {
a:'小红' // 不是reactive响应式对象。
}
})
</script>
  • readonly() 接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理,只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与 reactive() 相同,但解包得到的值是只读的。ps:源数据改变,代理数据也会改变。
<script setup>
import { readonly, ref } from 'vue'
// 创建深层响应式reactive()对象
let a = readonly({
age:18
})
let b = ref(1)
let c = reactive(b)
console.log(c); // 深层响应式只读reactive()对象
let e = reactive([ref(5)])
console.log(e[0].value) // ref对象不会解包,需要.value。
</script>
  • shallowReadonly() readonly() 的浅层作用形式。
<script setup>
import { shallowReadonly } from 'vue'
// 创建浅层响应式reactive()对象
let a = shallowReadonly({
age:18
name: {
a:'小红' // 不是reactive响应式对象。
}
})
</script>
  • toRaw() 可以返回由 reactive()、readonly()、shallowReactive() 或者 shallowReadonly() 创建的代理对应的原始对象。ps:解除响应式
 <script setup>
import { ref, reactive,toRaw } from 'vue'
let a = reactive({
age:18
})
let c = ref(1)
toRaw(a) // toRaw()函数返回值是原始js对象。
toRaw(c) // toRaw()函数返回值是ref深层响应式对象。
</script>

工具函数

  • markRaw() 将一个对象标记为不可被转为代理。返回该对象本身。ps:参数是响应式对象,返回值是响应式对象,参数是原始对象,返回值是原始对象。
 <script setup>
import { ref, reactive, markRaw } from 'vue'
let a = {
age:18
}
let b = markRaw(a)
let c = ref(b) // c是ref深层响应式对象。
let d = ref(a) // d是ref深层响应式对象。
let e = reactive(a) // e不是响应式对象。
let f = reactive(b) // e不是响应式对象。
</script>
  • isProxy() 检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 创建的代理。
 <script setup>
import { ref, reactive, isProxy, readonly, shallowReactive, shallowReadonly } from 'vue'
let a = {
age:18
}
let b = reactive(a) // true
let c = readonly(b) // true
let d = ref(a) // false
let e = shallowReactive(a) // true
let f = shallowReadonly (b) // true
</script>
  • isReactive() 检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。
 <script setup>
import { ref, reactive, isReactive, readonly, shallowReactive, shallowReadonly } from 'vue'
let a = {
age:18
}
let b = reactive(a) // true
let c = readonly(b) // false
let d = ref(a) // false
let e = shallowReactive(a) // true
let f = shallowReadonly (b) // false
</script>
  • isReadonly() 检查传入的值是否为只读对象。只读对象的属性可以更改,但他们不能通过传入的对象直接赋值。通过 readonly() 和 shallowReadonly() 创建的代理都是只读的,因为他们是没有 set 函数的 computed() ref。
 <script setup>
import { ref, reactive, isReactive, readonly, shallowReactive, shallowReadonly } from 'vue'
let a = {
age:18
}
let b = reactive(a) // false
let c = readonly(b) // true
let d = ref(a) // false
let e = shallowReactive(a) // false
let f = shallowReadonly (b) // true
</script>
  • toValue() 将值、refs 或 getters 规范化为值。这与 unref() 类似,不同的是此函数也会规范化 getter 函数。如果参数是一个 getter,它将会被调用并且返回它的返回值。
 <script setup>
import { ref, toValue } from 'vue'
toValue(1) // 1
toValue(ref(1)) // 1
toValue(() => 1) // 1
</script>
  • computed() 接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。
 <script setup>
import { computed } from 'vue'
// 只能计算响应式数据,返回一个只读ref对象。
computed(() => {})
// 可写的 ref 对象。
computed({
  get: () => {}
  set: (val) => {}
})
</script>
  • watch() 侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。watch() 默认是懒侦听的,即仅在侦听源发生变化时才执行回调函数。
 <script setup>
import { watch } from 'vue'
// 只能侦听响应式数据,第一个参数是侦听器的源,第二个参数是在发生变化时要调用的回调函数,第三个可选的参数是一个配置对象。
const stop = watch(origin,(newval,oldval,fn) => {},{}) 
stop() // 停止监听
// origin可以是一个函数,返回一个侦听值,可以是一个响应式对象,可以是以上类型的值组成的数组。

// 第二个参数是在发生变化时要调用的回调函数,个回调函数接受三个参数:新值、旧值,以及一个用于注册副作用清理的回调函数。该回调函数会在副作用下一次重新执行前调用,可以用来清除无效的副作用。

// immediate:在侦听器创建时立即触发回调。第一次调用时旧值是 undefined。
// deep:如果源是对象,强制深度遍历,以便在深层级变更时触发回调。ps:reactive()响应式对象默认开启,ref响应式对象默认不开启。
// flush:调整回调函数的刷新时机。
// onTrack / onTrigger:调试侦听器的依赖。
</script>
  • watchEffect() 立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。默认情况下,侦听器将在组件渲染之前执行。
 <script setup>
import { watchEffect } from 'vue'
// 第一个参数是回调函数和watch第二个参数回调函数类似,第二个参数配置项和watch第三个参数配置对象类似。
const stop = watchEffect((fn) => {},{})
stop() // 停止侦听
// 第一个参数回调函数,自动追踪函数中用到的依赖。
// fn 一个用于注册副作用清理的回调函数。该回调函数会在副作用下一次重新执行前调用,可以用来清除无效的副作用。

// 第二个参数是flush:调整回调函数的刷新时机。
</script>
  • watchPostEffect() watchEffect() 使用 flush: ‘post’ 选项时的别名。
  • watchSyncEffect() watchEffect() 使用 flush: ‘sync’ 选项时的别名。
  • effectScope() 创建一个 effect 作用域,可以捕获其中所创建的响应式副作用 (即计算属性和侦听器),这样捕获到的副作用可以一起处理。
 <script setup>
const scope = effectScope()
scope.run(() => {
  const doubled = computed(() => counter.value * 2)
  watch(doubled, () => console.log(doubled.value))
  watchEffect(() => console.log('Count: ', doubled.value))
})
// 处理掉当前作用域内的所有 effect
scope.stop()
</script>
  • getCurrentScope() 如果有的话,返回当前活跃的 effect 作用域。
  • onScopeDispose() 在当前活跃的 effect 作用域上注册一个处理回调函数。当相关的 effect 作用域停止时会调用这个回调函数。这个方法可以作为可复用的组合式函数中 onUnmounted 的替代品,它并不与组件耦合,因为每一个 Vue 组件的 setup() 函数也是在一个 effect 作用域中调用的。

生命周期

  • onMounted()
    注册一个回调函数,在组件挂载完成后执行。组件在以下情况下被视为已挂载:其所有同步子组件都已经被挂载 (不包含异步组件或 树内的组件)。其自身的 DOM 树已经创建完成并插入了父容器中。注意仅当根容器在文档中时,才可以保证组件 DOM 树也在文档中。这个钩子在服务器端渲染期间不会被调用。
  • onUpdated() 注册一个回调函数,在组件因为响应式状态变更而更新其 DOM 树之后调用。父组件的更新钩子将在其子组件的更新钩子之后调用。这个钩子会在组件的任意 DOM 更新后被调用,这些更新可能是由不同的状态变更导致的。这个钩子在服务器端渲染期间不会被调用。
  • onUnmounted() 注册一个回调函数,在组件实例被卸载之后调用。一个组件在以下情况下被视为已卸载:其所有子组件都已经被卸载。所有相关的响应式作用 (渲染作用以及 setup() 时创建的计算属性和侦听器) 都已经停止。这个钩子在服务器端渲染期间不会被调用。
  • onBeforeMount() 注册一个钩子,在组件被挂载之前被调用。当这个钩子被调用时,组件已经完成了其响应式状态的设置,但还没有创建 DOM 节点。它即将首次执行 DOM 渲染过程。这个钩子在服务器端渲染期间不会被调用。
  • onBeforeUpdate() 注册一个钩子,在组件即将因为响应式状态变更而更新其 DOM 树之前调用。这个钩子可以用来在 Vue 更新 DOM 之前访问 DOM 状态。在这个钩子中更改状态也是安全的。这个钩子在服务器端渲染期间不会被调用。
  • onBeforeUnmount() 注册一个钩子,在组件实例被卸载之前调用。当这个钩子被调用时,组件实例依然还保有全部的功能。这个钩子在服务器端渲染期间不会被调用。
  • onErrorCaptured() 注册一个钩子,在捕获了后代组件传递的错误时调用。
  • onActivated() 注册一个回调函数,若组件实例是 缓存树的一部分,当组件被插入到 DOM 中时调用。这个钩子在服务器端渲染期间不会被调用。
  • onDeactivated() 注册一个回调函数,若组件实例是 缓存树的一部分,当组件从 DOM 中被移除时调用。这个钩子在服务器端渲染期间不会被调用。
  • onServerPrefetch() 注册一个异步函数,在组件实例在服务器上被渲染之前调用。如果这个钩子返回了一个 Promise,服务端渲染会在渲染该组件前等待该 Promise 完成。这个钩子仅会在服务端渲染中执行,可以用于执行一些仅存在于服务端的数据抓取过程。

依赖注入

  • provide() 提供一个值,可以被后代组件注入。
  • inject() 注入一个由祖先组件或整个应用 (通过 app.provide()) 提供的值。
// 父组件
<script setup>
import { provide } from 'vue'
// 提供静态值
provide('foo', 'bar')
// 提供响应式的值
const count = ref(0)
provide('count', count)
// 提供时将 Symbol 作为 key
provide(fooSymbol, count)
</script>
// 子组件
<script setup>
import { inject } from 'vue'
// 注入值的默认方式
const foo = inject('foo')
// 注入响应式的值
const count = inject('count')
// 通过 Symbol 类型的 key 注入
const foo2 = inject(fooSymbol)
// 注入一个值,若为空则使用提供的默认值
const bar = inject('foo', 'default value')
// 注入一个值,若为空则使用提供的工厂函数
const baz = inject('foo', () => new Map())
// 注入时为了表明提供的默认值是个函数,需要传入第三个参数
const fn = inject('function', () => {}, false)
</script>
  • 缓存包裹在其中的动态切换组件。 包裹动态组件时,会缓存不活跃的组件实例,而不是销毁它们。任何时候都只能有一个活跃组件实例作为 的直接子节点。当一个组件在 中被切换时,它的 activated 和 deactivated 生命周期钩子将被调用,用来替代 mounted 和 unmounted。这适用于 的直接子节点及其所有子孙节点。
  • 为单个元素或组件提供动画过渡效果。
  • 为列表中的多个元素或组件提供过渡效果。
  • 将其插槽内容渲染到 DOM 中的另一个位置。
  • 一个用于渲染动态组件或元素的“元组件”。要渲染的实际组件由 is prop 决定。当 is 是字符串,它既可以是 HTML 标签名也可以是组件的注册名。或者,is 也可以直接绑定到组件的定义。
  • 表示模板中的插槽内容出口。 元素可以使用 name attribute 来指定插槽名。当没有指定 name 时,将会渲染默认插槽。传递给插槽元素的附加 attributes 将作为插槽 props,传递给父级中定义的作用域插槽。元素本身将被其所匹配的插槽内容替换。
  • 当我们想要使用内置指令而不在 DOM 中渲染元素时, 标签可以作为占位符使用。对 的特殊处理只有在它与以下任一指令一起使用时才会被触发:v-if v-else-ifv-else v-for v-slot如果这些指令都不存在,那么它将被渲染成一个原生的 元素。带有 v-for 的 也可以有一个 key 属性。所有其他的属性和指令都将被丢弃,因为没有相应的元素,它们就没有意义。

自定义指令

全局注册的自定义指令将正常工作。本地的自定义指令在 <script setup> 中不需要显式注册,但他们必须遵循 vNameOfDirective 这样的命名规范。

<script setup>
const vMyDirective = {
  beforeMount: (el) => {
    // 在元素上做些操作
  }}
</script>
<template>
  <h1 v-my-directive>This is a Heading</h1>
</template>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值