vue3 script setup 语法糖用了才知道有多爽 (三)


这里是完整的目录图片,由于整篇文章篇幅太长,拆分成了几篇来展示
在这里插入图片描述

4. context 之 slots 和 attrs

setup() 中的 context参数

我们都知道在 Vue3 语法当中 setup() 的第一个参数是 props,第二个参数是 context
props 用 defineProps API 来替换掉了
而 context 是一个对象,并且这个对象中有三个属性,分别是 attrs, slots, emit
当我们需要事件派发的时候,直接使用 emit 就可以了
那么 setupContext.attrs 以及 setupContext.slots 在 script setup 语法当中应该怎样使用呢?

<script setup>
import {
    
     useSlots, useAttrs } from 'vue'

const slots = useSlots()
const attrs = useAttrs()
</script>

useSlots 和 useAttrs 是真实的运行时函数,它的返回与 setupContext.slots 和 setupContext.attrs 等价。
它们同样也能在普通的组合式 API 中使用。

已经弃用的 useContext()

在查找相关资料的时候有看到关于 useContext() 的用法 (可以通过 useContext() 从上下文中获取 emit slots 和 attrs),但是现在关于 useContext 已经弃用了,废除了这个语法,被拆分成上面的 useAttrs 和 useSlots
以下图片来自别的参考资料,但是现在已经弃用了
在这里插入图片描述
测试使用报错 : The requested module '/node_modules/.vite/deps/vue.js?v=8da96c73' does not provide an export named 'useContext' (at child.vue:6:33)

<!-- 已弃用 -->
<script setup>
import {
    
     useContext } from "vue";
const {
    
     slots, attrs } = useContext();
</script>

在这里插入图片描述
在这里插入图片描述

5. defineExpose()

Vue 3 可以利用 expose 结合 ref 来让父组件使用子组件的数据 ( 可以对数据进行修改 )和方法
在 Vue 3 的新特性中,如果使用的是 options api 类型的组件,在不声明 expose 的时候,默认暴露当前组件实例的全部内容 (所有的属性和方法),如果使用 expose 选项的话,只有 expose 中的内容才会暴露 (expose:[ ] 就表示什么都不暴露,可以利用这个特性来提高组件的使用规范 )
如果使用的是 setup script 的语法糖, 默认是关闭 expose 的, 子组件未暴露的数据以及方法在父组件中无法直接获取引用,需要子组件使用 defineExpose 将其主动暴漏出来

Vue 3 setup() 语法

父组件

<template>
  <div>
    <h2 @click="clickEvent">我是父组件!</h2>
    <Child ref="son" />
  </div>
</template>
<script>
import {
    
    defineComponent} from 'vue'
import Child from './child.vue' 
export default  defineComponent({
    
    
  components:{
    
    
    Child
  },
  setup(){
    
    
      function clickEvent (){
    
    
        console.log("click here !")
       	// 访问子组件中的属性 
        console.log(this.$refs.son.msg)
		// 调用子组件中的方法
        this.$refs.son.m1()
      }
      return {
    
    
        clickEvent
      }
  }
})
</script>

子组件

<!-- 子组件 -->
<template>
  <span>我是子组件! -- msg: {
   
   { msg }}</span>
</template>
<script>
import {
    
    defineComponent,ref} from 'vue'
  export default defineComponent({
    
    
    setup(){
    
    
      const msg = ref('this is a msg from child component')
      const m1 = ()=>{
    
    
        console.log("this is method m1 at child component")
      }
      return{
    
    
        msg,
        m1
      }
    }
  })
</script>

<script setup> 语法糖的写法

父组件

<template>
  <div>
    <h2 @click="clickEvent">我是父组件!</h2>
    <Child ref="son" />
  </div>
</template>
<script setup>
import {
    
    ref} from 'vue'
import Child from './child.vue' 
  const son = ref(null)
  function clickEvent (){
    
    
    console.log("click here !")
  	// 访问子组件中的属性 
    console.log(son.value.msg)
	// 调用子组件中的方法
    son.value.m1()
  }
</script>

子组件

<template>
  <span>我是子组件! -- msg: {
   
   { msg }}</span>
</template>
<script setup>
import {
    
    ref} from 'vue'
    const msg = ref('this is a msg from child component')
    const m1 = ()=>{
    
    
      console.log("this is method m1 at child component")
    }

    defineExpose({
    
    
      msg,
      m1
    })
</script>

就像这个例子子组件中暴露的这样,将属性 msg , 方法 m1 暴露出来,父组件通过 ref 获取到子组件的实例就可以访问到了

小结

  • defineExpose 可以直接使用,无需引入
  • 当父组件通过模板引用的方式获取到当前组件的实例,获取到的实例会像是这个样子的 {a:number,b:number} (ref 会和在普通实例中一样被自动解包)

vue3 script setup 语法糖用了才知道有多爽 (一)
vue3 script setup 语法糖用了才知道有多爽 (二)

猜你喜欢

转载自blog.csdn.net/YZRHANYU/article/details/129618015