Composition
本文最后更新于 81 天前,如有失效请评论区留言。

Composition API

什么是 Composition API?

Composition API = Reactivity API + Lifecycle hooks

响应式加上生命周期就组成了基础的 组合式API

const { reactive, watchEffect, onMounted } = Vue
export default {
  setup () {
    const state = reactive({ count: 0 })
    watchEffect(() => console.log(state.count))
    onMounted(() => console.log('mounted'))
    return {
      state,
      increment: () => { state.count++ }
    }
  }
}

一个简单的例子,所有内容只需要写到setup函数中,为什么还要有个setup,vue作者是为了考虑options选项的兼容性,方便选项式API更好的迁移

在最后return你需要使用的到模板上

生命周期

组件的生命周期从render函数开始,执行setup函数中的组合式API,把template转成render,然后触发beforeCreate hook (vue3的组合式API生命周期hook中没有),然后初始化inject、methods、data、computed、watch、provide这些Options API,然后触发created hook,查看是否存在预编译的模板(预编译的模板是在构建过程中已经被编译为可直接生成虚拟 DOM 的渲染函数,这样在页面渲染时就无需再进行模板的编译,可以直接生成虚拟 DOM,进而提高页面的渲染速度),触发beforeMount hook,render渲染组件和子组件,触发mounted hook,完成一个基本的加载

img

当数据发生变化时触发beforeUpdate hook,render更新进入patch 进行diff算法计算出最小的改动,然后触发updated hook。

最后当组件被卸载之前(可能是跳转页面、v-if、v-for等数据改变导致该组件不存在了),触发beforeUnmount,卸载子组件,停止相关的响应式(计算属性和侦听器),最后触发unmounted hook。

父子触发的生命周期流程

父setup > 父beforeCreate > 父created> 父beforeMount > 子setup > 子beforeCreate > 子created > 子beforeMount > 子mounted > 父mounted

父beforeUpdate > 子beforeUpdate > 子updated > 父updated

父beforeUnmount > 子beforeUnmount > 子unmounted > 父unmounted

watchEffect和watch区别

watchEffect首次会执行一次(因为要收集依赖),只要里面有任何值的改动都会重新执行。

watch 需要定义一个监听源,然后返回里带有新值和老值,首次不会执行。

举个例子:

image-20240207223103779

image-20240207223427632

只需要把fetch方法写入watchEffect内部即可自动根据传入的props.id 更新

使用watchEffect实现自动fetch

源代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <div id="app">
  </div>

  <script>
    const { createApp, ref, watchEffect, toRef } = Vue
    function usePost (getId, getA) {
      console.log('usePost', getId());
      return useFetch(() => `https://jsonplaceholder.typicode.com/todos/${getId()}`, () => getA())
    }
    function useFetch (getUrl, getA) {
      const data = ref(null)
      const error = ref(null)
      const isPending = ref(true)
      watchEffect(() => {
        console.log(getA())
        console.log(getUrl())
        // console.log(data.value); 这里不能调用否则会递归
        data.value = null
        error.value = null
        isPending.value = true
        fetch(getUrl())
          .then(res => res.json())
          .then(_data => {
            data.value = _data
            console.log(data.value); // 这里可以调用
            isPending.value = false
          })
          .catch(err => {
            error.value = err
            isPending.value = false
          })
      })
      return {
        data,
        error,
        isPending
      }
    }
    const Post = {
      props: ['id', 'a'],
      setup (props) {
        console.log('props', props.id);
        const { data, error, isPending } = usePost(() => props.id, () => props.a)
        const foo = ref('foo')
        return {
          data,
          error,
          isPending,
        }
      },
      template: `
      <div v-if="isPending">loading...</div>
      <div v-else-if="data">{{ data }}</div>
      <div v-else-if="error">Error: {{ error.message }}</div>
      `
    }
    const App = {
      components: { Post },
      data () {
        return {
          id: 1,
          a: 1,
        }
      },
      template: `
      <button @click="id++">change ID</button>
      <button @click="a++">change a</button>
      <Post :id="id" :a="a"/>
      `
    }
    createApp(App).mount('#app')
  </script>
</body>

</html>

拆分解耦

使用Composition API更好的拆分,如果你有很多地方都有共同的逻辑处理,你甚至可以把onmounted方法都提取出去,作为一个公共的方法

image-20240207223620652

当功能多了后不同的功能分散在不同的地方,你会需要来回跳转和滚动,不便于查看和封装

image-20240207225514998

使用Composition API后

image-20240207230312881

版权声明:本文为BIMiracle原创,依据CC BY-SA 4.0许可证进行授权,转载请附上出处链接及本声明。
暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇