vue3.0--setup()

1.setup()定义:

  setup () 是vue3新增加的组件。vue3采用了组合式 API ,为了使用组合式API,我们需要一个入口,在vue3组件中,称之为setup。(简单点来说,就是vue2里面的data,method,computed,所有数据方法全写在setup里)

 

2.setup()使用场景:

  2.1需要在非单文件组件中使用组合式 API 时。(非单文件组件指的是一个文件中包含多个vue组件)

  2.2需要在基于选项式 API 的组件中集成基于组合式 API 的代码时。(在已使用选项式api的同时要使用组合式API)

 

3.setup注意点

4.基本使用

<script>
import { ref } from 'vue'

export default {
  setup() {  //1.setup() 自身并不含对组件实例的访问权,即在 setup() 中访问 this 会是 undefined。
    const count = ref(0)

    return {  //2.需要return才可以被其他使用,<script setup>不需要return
      count
    }
  },

  mounted() { //3.返回值可以给选项式api通过this获取使用
    console.log(this.count) // 0
  }
}
</script>

<template>  //4.在模板中访问从setup返回的ref时,它会自动浅层解包,因此你无须再在模板中为它写.value
<button @click="count++">{{ count }}</button> //当通过this访问时也会解包
</template>

另:setup() 应该同步地返回一个对象。唯一可以使用 async setup() 的情况是,该组件是 Suspense 组件的后裔。

 

5.setup的参数

  5.1第一个参数props(1.接收的props本质是proxy实例对象2.如果父组件传了你没接收则报警告)

export default {
  props: {   //1.必须使用props接收,否则setup中接收的值都为undefined
    title: String
  },
  setup(props) {
  //2.请注意如果你解构了 props 对象,解构出的变量将会丢失响应性。因此我们推荐通过 props.xxx 的形式来使用其中的 props。 console.log(props.title)
  //3.非要结构的情况下
  // 将 `props` 转为一个其中全是 ref 的对象,然后解构
  const { title } = toRefs(props)
  // `title` 是一个追踪着 `props.title` 的 ref
  console.log(title.value)
  // 或者,将 `props` 的单个属性转为一个 ref
  const title = toRef(props, 'title')
} }

  5.2第二个context

// 父组件 在子组件传递一个text
  <template>
    <div class="box" style="margin: 0 auto;text-align: center;">
      <h1>我是父组件</h1>
    </div>
    <son :data="data" text="文本传输" ref='son'></son>
  </template>
  <script setup>

 

  <script>

//子组件
import { h, ref } from 'vue'
export default {
  props:{ data:{ type:String } },
  //1.该上下文对象是非响应式的,可以安全地解构: setup(props, { attrs, slots, emit, expose }) { // 透传 Attributes(非响应式的对象,等价于 $attrs)
  console.log(context.attrs)
  // 插槽(非响应式的对象,等价于 $slots)
  console.log(context.slots)
  // 触发事件(函数,等价于 $emit)
  console.log(context.emit)
  // 暴露公共属性(函数)
  console.log(context.expose)

  //2.attrs 和 slots 都是有状态的对象,它们总是会随着组件自身的更新而更新。这意味着你应当避免解构它们,并始终通过 attrs.x 或 slots.x 的形式使用其中的属性。 //即可以解构context,但是不可以再解构attrs和slots
  //3.和 props 不同,attrs 和 slots 的属性都不是响应式的。如果你想要基于 attrs 或 slots 的改变来执行副作用,那么你应该在 onBeforeUpdate 生命周期钩子中编写相关逻辑。
  
  //4.可以获取父组件给该组件定义的text的属性值
  console.log('context>>>', context.attrs.text); //有值
  //5.attrs(获取当前标签上的所有属性的对象),但是该属性是props中没有声明接收的所有的对象。如果你使用props去获取值,同时props中你声明了你要获取的值,则:获取的值是undefined
  console.log('props>>>', props.data); //有值
  //attrs获取值是不需要props中没有声明接收 ,如果用attrs 接收 props 中的值会显示undefined(!!传的值一旦被props接收了,$attrs就不会接收,如果props不接收,默认会存放在props)
  console.log('contextTestProps>>>', context.attrs.data); //undefined

  ?? <script setup>默认是关闭的,setup不确定是否是关闭
  //6.让组件实例处于 “关闭状态” 即不向父组件暴露任何东西【可以向父组件暴露,父组件通过ref.value.暴露值就可以获取或者执行暴露的值或者函数】
  expose()
  //7.有选择地暴露局部状态
  const publicCount = ref(0) 
  expose({ count: publicCount })
  //8.解决因为setup返回了渲染函数,而不能返回其他的函数或者变量,使用expose来进行暴露
  //setup 返回的是h函数则将直接代替template,template将失效,则不会使用到setup的变量,因此不用顾忌到setup没办法再返回其他变量或者函数给模板使用
  const count = ref(0)
  const increment = () => ++count.value
  expose({ increment })
  //h函数是创建节点, 可实现展示template如何渲染到html中的过程
  return () => h('div', count.value)

  8.父组件给子组件写的插槽存放在$slots
    8.1普通插槽
    

      8.2具名插槽(vue3废弃slot,需要使用v-slot:name,简写#name)

     

  }
}

 

posted on 2022-12-14 17:11  ChoZ  阅读(4524)  评论(0编辑  收藏  举报

导航