• setup获取props和自定义事件、通过expose暴露给ref获取属性和方法、setup顶层async、setup返回函数



    1. setup获取props和自定义事件

    child 组件:

    <template>
      <div>
        <h3>我是child组件 -- {{ title }}h3>
        <button @click="setTitle">修改父title中的数据button>
      div>
    template>
    
    <script>
    export default {
      // props单向数据流,子不能修改父
      // 写法1:
      // props: ['title'],
    
      // 写法2:
      props: {
        title: {
          type: String
        }
      },
      // setup里面不能使用this,在此处this它的指向为undefined
      // 参数1:props对象,可以用它来接受props数据,但是此对象一定不能解构
      // 参数2:context对象,里面包含了 slots emit expose attrs
    
      setup(props, { emit }) {
        console.log(props.title)
        // console.log(slots)
        const setTitle = () => {
          // 发送一个自定义事件,让父组件去绑定实现,这样完成修改title
          emit('onSetTitle', Date.now() + ' - @@')
        }
    
        return { setTitle }
      }
    }
    script>
    
    <style lang="scss" scoped>
    
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    父组件:

    <template>
      <div>
        <child  :title="title" @onSetTitle="setTitle">aaaachild>
      div>
    template>
    
    <script>
    import { ref } from 'vue'
    import child from './components/child.vue'
    export default {
      components: { child },
      setup() {
        const title = ref('我是父组件标题')
    
        const setTitle = tit => {
          title.value = tit
        }
    
        return { title, setTitle }
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    2. 通过expose暴露给ref获取属性和方法

    child组件:

    <template>
      <div>
        <h3>我是child组件 -- {{ title }}h3>
        <button @click="setTitle">修改父title中的数据button>
      div>
    template>
    
    <script>
    export default {
      // props单向数据流,子不能修改父
      // 写法1:
      // props: ['title'],
    
      // 写法2:
      props: {
        title: {
          type: String
        }
      },
    
      // setup里面不能使用this,在此处this它的指向为undefined
      // 参数1:props对象,可以用它来接受props数据,但是此对象一定不能解构
      // 参数2:context对象,里面包含了 slots emit expose attrs
      setup(props, { emit, expose }) {
        console.log(props.title)
        const setTitle = () => {
          // 发送一个自定义事件,让父组件去绑定实现,这样完成修改title
          emit('onSetTitle', Date.now() + ' - @@')
        }
    
        // expose 如果你不用它,则在父组件中使用ref得到当前的实例,并且里面所有的方法和属性你都能调用,没有封装性。使用它后,你可以指定需要暴露给父组件ref调用的方法或属性。
        expose({
          name: 'abc'
        })
    
        return { setTitle }
      }
    }
    script>
    
    <style lang="scss" scoped>
    
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    父组件:

    <template>
      <div>
        <child ref="childRef" :title="title" @onSetTitle="setTitle">aaaachild>
      div>
    template>
    
    <script>
    import { ref } from 'vue'
    import child from './components/child.vue'
    export default {
      components: { child },
      setup() {
        const title = ref('我是父组件标题')
        const childRef = ref(null)
    
        const setTitle = tit => {
          title.value = tit
    
          console.log(childRef.value)
        }
    
        return { title, setTitle, childRef }
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    3. setup顶层async

    当 setup 需要返回一个 promise 对象时,即在顶层 setup 前添加 async 必须使用 Suspense 包裹,否则会报错。也就是说,当你的 async 不是加在顶层 setup 上时,不用拿 Suspense 包裹。

    子组件:

    <template>
      <div>
        <h3>我是child组件h3>
        <button>修改父title中的数据button>
      div>
    template>
    
    <script>
    export default {
      // setup需要返回一个 {} | ()=>{} | promise=> 必须使用 Suspense包裹
      // 顶层async
      async setup() {
        return {  }
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    父组件:

    <template>
      <div>
        <Suspense>
            <child />
        Suspense>
      div>
    template>
    
    <script>
    import child from './components/child.vue'
    export default {
      components: { child },
      setup() {
        return {}
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    于是我们就可以在子组件中通过 axios 进行网络请求。

    子组件:

    <template>
      <div>
        <h3>我是child组件h3>
        <button>修改父title中的数据button>
      div>
    template>
    
    <script>
    import axios from 'axios'
    import { onMounted, ref } from 'vue'
    export default {
      // setup需要返回一个 {} | ()=>{} | promise=> 必须使用 Suspense包裹
      // 顶层async
      async setup() {
        let films = ref([])
    
        onMounted(async () => {
          let ret = await axios.get(
            'https://api.iynn.cn/film/api/v1/getNowPlayingFilmList?cors=T&cityId=110100&pageNum=1&pageSize=10'
          )
          films.value = ret.data.data.films
        })
    
        return { films }
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    父组件:

    <template>
      <div>
        <Suspense>
            <child />
        Suspense>
      div>
    template>
    
    <script>
    import child from './components/child.vue'
    export default {
      components: { child },
      setup() {
        return {}
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    异步组件 + setup 配置顶层 async + Suspense 组件中的 default 和 fallback:

    子组件:

    <template>
      <div>
        <h3>我是child组件h3>
        <button>修改父title中的数据button>
      div>
    template>
    
    <script>
    import axios from 'axios'
    import { onMounted, ref } from 'vue'
    export default {
      // setup需要返回一个 {} | ()=>{} | promise=> 必须使用 Suspense包裹
      // 顶层async
      async setup() {
        let films = ref([])
    
        onMounted(async () => {
          let ret = await axios.get(
            'https://api.iynn.cn/film/api/v1/getNowPlayingFilmList?cors=T&cityId=110100&pageNum=1&pageSize=10'
          )
          films.value = ret.data.data.films
        })
    
        return { films }
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    父组件:

    <template>
      <div>
        <Suspense>
          
          <template #default>
            <child />
          template>
          
          <template #fallback>
            <loading />
          template>
        Suspense>
      div>
    template>
    
    <script>
    import { ref, defineAsyncComponent } from 'vue'
    // 异步组件 + setup配置选项顶层 async  配合 Suspense 组件
    const child = defineAsyncComponent(() => import('./components/child.vue'))
    export default {
      components: { child },
      setup() {
        return {}
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在这里插入图片描述

    4. setup返回函数

    返回函数 ,它就相当于 render方法,不需要 template 模板。

    子组件:

    <script>
    import { ref, h } from 'vue'
    export default {
      // 返回函数  它就相当于 render方法,模板,不需要template
      setup() {
        return () => {
          return h('div', null, [
            h('h3', null, '我是一个标题'),
            h(
              'button',
              {
                onClick: () => console.log('我是点击事件')
              },
              '按钮'
            )
          ])
        }
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    父组件:

    <template>
      <div>
        <child />
      div>
    template>
    
    <script>
    // import { ref } from 'vue'
    import child from './components/child.vue'
    export default {
      components: { child },
      setup() {
        return {}
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    也可以用 jsx 语法实现上面的需求:

    父组件:

    <template>
      <div>
        <child />
      div>
    template>
    
    <script>
    import child from './components/child'
    export default {
      components: { child },
      setup() {
        return {}
      }
    }
    script>
    
    <style lang="scss" scoped>style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    子组件(快捷键 rfc):

    const Child = () => {
      return (
        <div>
          <h3>jsxh3>
          <button>jsxbutton>
        div>
      )
    }
    
    export default Child
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

  • 相关阅读:
    dreamweaver网页设计作业制作 学生个人网页单页 WEB静态网页作业模板 大学生个人主页博客网页代码 dw个人网页作业成品简单页面
    记录:R语言生成热图(非相关性)
    Linux高并发服务器开发—静态库和makefile
    从char到string
    数论练习题
    中科大-数字图像分析-期末考试试卷回忆版汇总
    Linux下SpringBoot项目部署(centos系统)
    python用pandas库写入xlsx文件时速度过慢如何优化
    马上就2023年了,Go语言成了吗?
    LLMs之HFKR:HFKR(基于大语言模型实现异构知识融合的推荐算法)的简介、原理、性能、实现步骤、案例应用之详细攻略
  • 原文地址:https://blog.csdn.net/weixin_45605541/article/details/127986919