当前位置:
首页
文章
前端
详情

vue3.x玩转setup

一、入门

<!DOCTYPE html>
<html>

<head>
    <title>vue3.x</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div>
        {{ readersNumber }} {{ book.title }}
    </div>

    <script type="text/javascript">
        Vue.createApp({
            setup() {
                let readersNumber = Vue.ref(0)
                const book = Vue.reactive({ title: 'Vue 3 Guide' })

                readersNumber.value++;

                return {
                    readersNumber,
                    book
                }
            }
        }).mount('#app')
    </script>
</body>

</html>

setup 接收2个参数 propscontext

二、生命周期

你可以通过在生命周期钩子前面加上 “on” 来访问组件的生命周期钩子。

下表包含如何在 setup () 内部调用生命周期钩子:

选项式 API Hook inside setup
beforeCreate Not needed*
created Not needed*
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
errorCaptured onErrorCaptured
renderTracked onRenderTracked
renderTriggered onRenderTriggered
activated onActivated
deactivated onDeactivated

setup 是围绕 beforeCreatecreated 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。

export default {
  setup() {
    // mounted
    onMounted(() =&gt; {
      console.log('Component is mounted!')
    })
  }
}

三、应用

1、props

export default {
  props: {
    title: String
  },
  setup(props) {
    console.log(props.title)
  }
}

注意: props是响应式的,所以不能使用ES6解构,因为它会破坏 prop 的响应性

如果需要解析 props 的话,可以通过 toRefs 实现:

import { toRefs } from 'vue'

setup(props) {
    const { title } = toRefs(props)

    console.log(title.value)
}

如果 title 属性是可选的,就得使用 toRef 代替 toRefs

import { toRef } from 'vue'
setup(props) {
    const title = toRef(props, 'title')
    console.log(title.value)
}

2、Context

context 是一个普通的非响应式的 JavaScript 对象,类似vue2.x的this,因为在 setup()this 不是对实例的引用。

context 暴露了三个组件属性:

export default {
  setup(props, context) {
    // Attribute (非响应式对象)
    console.log(context.attrs)

    // 插槽 (非响应式对象)
    console.log(context.slots)

    // 触发事件 (方法)
    console.log(context.emit)
  }
}

解构示例:

export default {
  setup(props, { attrs, slots, emit }) {
    ...
  }
}

attrsslots 是有状态的对象,它们会随组件本身的更新而更新。
这意味着你应该避免对它们进行解构,并始终以 attrs.x 或 slots.x 的方式引用 property。

注意:与 props 不同,attrsslots 是非响应式的。如果你打算根据 attrsslots 更改应用副作用,那么应该在 onUpdated 生命周期钩子中执行此操作。

3、访问组件的 property

执行 setup 时,组件实例尚未被创建。因此,你只能访问以下 property:

  • props
  • attrs
  • slots
  • emit

换句话说,你将无法访问以下组件选项:

  • data
  • computed
  • methods

4、结合模板使用

<template>
  <div>{{ readersNumber }} {{ book.title }}</div>
</template>

<script>
  import { ref, reactive } from 'vue'

  export default {
    setup() {
      const readersNumber = ref(0)
      const book = reactive({ title: 'Vue 3 Guide' })

      return {
        readersNumber,
        book
      }
    }
  }
</script>

5、使用渲染函数

import { h, ref, reactive } from 'vue'

export default {
  setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })

    return () =&gt; h('div', [readersNumber.value, book.title])
  }
}

cdn静态页示例:

<script src="https://unpkg.com/vue@next"></script>

<div>
  <!-- 渲染setup返回的div -->
</div>

<script type="text/javascript">
    Vue.createApp({
        setup() {
            let readersNumber = Vue.ref(0)
            const book = Vue.reactive({ title: 'Vue 3 Guide' })

            readersNumber.value++;

            return () => Vue.h('div', [readersNumber.value, book.title]) // <div>{{ readersNumber }} {{ book.title }}</div>
        }
    }).mount('#app')
</script>

免责申明:本站发布的内容(图片、视频和文字)以转载和分享为主,文章观点不代表本站立场,如涉及侵权请联系站长邮箱:xbc-online@qq.com进行反馈,一经查实,将立刻删除涉嫌侵权内容。