vue3 学习2 - setup

265 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 24 天,点击查看活动详情

前言

  • 记录一下学习 setup 的笔记。

开始

可以理解 setup 是 Vue3 中一个新的配置项,值为一个函数,是使用组合式 API 的入口。

1. 先不说组合式API是什么,先去看看 setup 的基础使用。

为了更加方便的演示,我将演示案例,放在app页面的组件 demo 中演示案例。

主页面 app.vue

<template>
  <div>
    我是 app 主页面
    <demo />
  </div>
</template>

<script>
import demo from '@/components/demo.vue'
export default {
  components: {
    demo,
  },
}
</script>

组件 demo.vue

<template>
  <div>我是demo组件,今天学习 setup的基础使用</div>
</template>

<script>
export default {
  setup() {},
}
</script>

总结:

由上可得,setup和之前 vue2 中的 data methond类似,setup 也是一个配置项。它是一个函数;

2. setup 既然是函数,我比较关注四件事:

  • 可以做什么;

  • 返回值;

  • 传入参数;

  • this指向;

2.1 可以做什么

组件中所用到的:数据、方法等等,均要配置在 setup 中。

示例:

<script>
export default {
  setup() {
    // 组件中所用到的:数据、方法等等,均要配置在setup中。
    let name = 'tomato'
    function say() {
      console.log('I like tomato!!!')
    }
  },
}
</script>

2.2 返回值

返回值目前有两种:

  1. setup() 函数中返回的对象会暴露给模板和组件实例。其它的选项也可以通过组件实例来获取 setup() 暴露的属性;
  2. 可以返回一个渲染函数;

主要还是使用第一种返回值,用来暴露数据给模板和组件实例。第二种返回值,暂时了解;

情况一示例:

<template>
  <div>
    <h3>我是demo1组件,今天学习 setup的基础使用</h3>

    <div>我的名字 : {{ name }}</div>

    <div @click="say">说话</div>
  </div>
</template>

<script>
export default {
  setup() {
    // 组件中所用到的:数据、方法等等,均要配置在setup中。
    let name = 'tomato'
    function say() {
      console.log('I like tomato!!!')
    }
    return {
      name,
      say,
    }
  },
}
</script>

image.png

情况二示例:

<script>
// h函数 以后在细说,现在理解它就是渲染函数,根据传入的参数,返回dom结构
import { h } from 'vue'

export default {
  setup() {
    const text = '渲染函数'
    return () => h('h3', text)
  },
}
</script>

image.png

2.3 传入参数

两个参数:

  1. setup 函数的第一个参数是组件的 props。和标准的组件一致,一个 setup 函数的 props 是响应式的,并且会在传入新的 props 时同步更新。
  2. 传入 setup 函数的第二个参数是一个 Setup 上下文对象。上下文对象暴露了其他一些在 setup 中可能会用到的值:

主页面 app.vue

<template>
  <div>
    我是 app 主页面
    <demo :name="appName" :age="appAge" :other="appOther"> </demo>
  </div>
</template>

<script>
import demo from '@/components/demo.vue'
export default {
  components: {
    demo,
  },
  // 这里可以看得出来 vue3中依旧兼容 vue2中的写法 例如data
  data() {
    return {
      appName: 'lazy',
      appAge: '18',
      appOther: '其他属性',
    }
  },
}
</script>

组件 demo.vue

<template>
  <div>
    <h3>我是demo1组件,今天学习 setup的基础使用</h3>
  </div>
</template>

<script>
export default {
  props: {
    name: String,
    age: String,
  },
  setup(props, context) {
    console.log(props)
    //  {name: 'lazy', age: '18'}

    console.log(context)
    // { "attrs": { "other": "其他属性" },"slots": {} }
    // 这里我就演示了一下 原本的 this.$attrs的数据。现在放在了 context 上
    // 除了attrs 还有这些属性 { attrs, slots, emit, expose }
  },
}
</script>

2.4 this指向

setup 中的 thisundefined,这一点 vue3 和 vue2 还是有很大区别的,vue2可以通过 this 获取 data 中的数据 ,method 中的数据,vue3不行,需要注意。

<script>
export default {
  setup() {
    console.log(this)
    // undefined
  },
}
</script>
  1. setup函数的两种返回值:
    1. 若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。(重点关注!)
    2. 若返回一个渲染函数:则可以自定义渲染内容。(了解)
  2. 注意点:
    1. 尽量不要与Vue2.x配置混用
      • Vue2.x配置(data、methos、computed...)中可以访问到setup中的属性、方法。
      • 但在setup中不能访问到Vue2.x配置(data、methos、computed...)。
      • 如果有重名, setup优先。
    2. setup不能是一个async函数,因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)

3. expose

看到官网介绍 setup的时候,有这么一个属性做了介绍。

expose 函数用于显式地限制该组件暴露出的属性,当父组件通过模板引用访问该组件的实例时,将仅能访问 expose 函数暴露出的内容:

app.vue

<template>
  <div>
    我是 app 主页面
    <demo ref="demoRef"> </demo>
  </div>
</template>

<script>
import demo from '@/components/demo.vue'
export default {
  components: {
    demo,
  },
  mounted() {
    console.log(this.$refs.demoRef)
    console.log(this.$refs.demoRef.name)
    this.$refs.demoRef.say()
  },
}
</script>

demo.vue

<script>
export default {
  setup(props, { expose }) {
    expose({
      name: '暴露的数据',
      say() {
        alert('番茄真酷!!')
      },
    })
  },
}
</script>

c346c8c7bb05044866fd38b56219092.jpg 说明:

  1. 其实主要作用就是,隐藏组件内部的属性,通过 expose 暴露我们想要暴露的数据。
  2. 在组件的 setup 使用 expose 需要借助 setup的第二个参数 context;
  3. 访问的时候,我这里演示的是使用 this.refs 去访问

4. 和vue2的选项配置之间的数据访问

  • Vue2 配置(data、methos、computed...)中可以访问到 setup 中的属性、方法。
  • 但在 setup 中不能访问到 Vue2 配置(data、methos、computed...)。
  • 如果有重名, setup 优先。

建议:不要混用 API 以免混淆。

<template>
  <div>
    <!-- 1.验证第一条 vue2中的配置 (这里演示的是data) 可以访问 setup 的属性 -->
    {{ likeName }}
    <!-- setup的名称 -->

    <!-- 3.验证第三条 如果有重名,setup 优先 -->
    {{ hobby }}
    <!-- study -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      likeName: name,
      age: 18,
      hobby: 'play game',
    }
  },
  setup() {
    let name = 'setup的名称'

    // 2. setup 中不能访问到 Vue2 配置 (这里演示的是data)
    // console.log('验证第二条', age) // Uncaught ReferenceError: age is not defined

    let hobby = 'study'

    return {
      name,
      hobby,
    }
  },
}
</script>

总结

总结一下今天的收获:

收获:

  1. 初步熟悉了 setup这个配置项;

  2. 熟悉了它的:作用;传参;返回值;this指向;

  3. 还可以通过 expose,来限制暴露出去的属性;

  4. 学习了 setup 和 vue2 常用的配置项之间数据访问的细节;

遗留疑问:

  1. 组合式API还不知道是什么意思。
  2. setup 的第二个参数,还有一些没有属性没有用到。(本次就体验到了 attr 和 expose)
  3. 数据虽然在组件上显示了,但是不是响应式的。

end

  • 加油啦!