您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    Vue 3 的组合 API 如何央求数据?
    时间:2020-10-20 12:04 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    Vue 3 的组合 API 如何央求数据?

    前言

    之前在学习 React Hooks 的进程中,看到一篇外网文章,经过 Hooks 来央求数据,并将这段逻辑笼统成一个新的 Hooks 给其他组件复用,我也在我的博客里翻译了一下:《在 React Hooks 中如何央求数据?》,感兴味可以看看。虽然是去年的文章,在阅读之后一下子就掌握了 Hooks 的运用方式,而且数据央求是在业务代码中很常用的逻辑。

    Vue 3 曾经发布一段时间了,其组合 API 多少有点 React Hooks 的影子在外面,明天我也计划经过这种方式来学习下组合 API。

    项目初始化

    为了快速启动一个 Vue 3 项目,我们直接运用当下最抢手的工具 Vite 来初始化项目。整个进程一气呵成,行云流水。

    npm init vite-app vue3-app 

    # 翻开生成的项目文件夹 

    cd vue3-app 

    # 安装依赖 

    npm install 

    # 启动项目 

    npm run dev 

    我们翻开 App.vue 将生成的代码先删掉。

    组合 API 的入口

    接上去我们将经过 Hacker News API 来获取一些抢手文章,Hacker News API前往的数据结构如下:

      "hits": [ 

        { 

          "objectID""24518295"

          "title""Vue.js 3"

          "url""https://github.com/vuejs/vue-next/releases/tag/v3.0.0"

        }, 

        {...}, 

        {...}, 

      ] 

    我们经过 ui > li 将旧事列表展现到界面上,旧事数据从 hits 遍历中获取。

    <template> 

      <ul> 

        <li 

          v-for="item of hits" 

          :key="item.objectID" 

        > 

          <a :href="item.url">{{item.title}}</a> 

        </li> 

      </ul> 

    </template> 

     

    <script> 

    import { reactive } from 'vue' 

     

    export default { 

      setup() { 

        const state = reactive({ 

          hits: [] 

        }) 

        return state 

      } 

    </script> 

    在解说数据央求前,我看先看看 setup() 办法,组合 API 需求经过 setup() 办法来启动,setup() 前往的数据可以在模板内运用,可以复杂了解为 Vue 2 外面 data() 办法前往的数据,不同的是,前往的数据需求先经过 reactive() 办法停止包裹,将数据变成照应式。

    组合 API 中央求数据

    在 Vue 2 中,我们央求数据时,通常需求将发起央求的代码放到某个生命周期中(created或 mounted)。在 setup() 办法内,我们可以运用 Vue 3 提供的生命周期钩子将央求放到特定生命周期内,关于生命周期钩子办法与之前生命周期的比照如下:

    Vue 3 的组合 API 如何央求数据?


    生命周期

    可以看到,基本上就是在之前的办法名前加上了一个 on,且并没有提供 onCreated 的钩子,由于在 setup() 内执行就相当于在 created 阶段执行。下面我们在 mounted 阶段来央求数据:

    import { reactive, onMounted } from 'vue' 

     

    export default { 

      setup() { 

        const state = reactive({ 

          hits: [] 

        }) 

        onMounted(async () => { 

          const data = await fetch

            'https://hn.algolia.com/api/v1/search?query=vue' 

          ).then(rsp => rsp.json()) 

          state.hits = data.hits 

        }) 

        return state 

      } 

    最后效果如下:

    Vue 3 的组合 API 如何央求数据?

    Demo

    监听数据变动

    Hacker News 的查询接口有一个 query 参数,前面的案例中,我们将这个参数固定了,如今我们经过照应式的数据来定义这个变量。

    <template> 

      <input type="text" v-model="query" /> 

      <ul> 

        <li 

          v-for="item of hits" 

          :key="item.objectID" 

        > 

          <a :href="item.url">{{item.title}}</a> 

        </li> 

      </ul> 

    </template> 

     

    <script> 

    import { reactive, onMounted } from 'vue' 

     

    export default { 

      setup() { 

        const state = reactive({ 

          query: 'vue'

          hits: [] 

        }) 

        onMounted((async () => { 

          const data = await fetch

            `https://hn.algolia.com/api/v1/search?query=${state.query}` 

          ).then(rsp => rsp.json()) 

          state.hits = data.hits 

        }) 

        return state 

      } 

    </script> 

    如今我们在输入框修正,就能触发 state.query 同步更新,但是并不会触发 fetch 重新调用,所以我们需求经过 watchEffect() 来监听照应数据的变化。

    import { reactive, onMounted, watchEffect } from 'vue' 

     

    export default { 

      setup() { 

        const state = reactive({ 

          query: 'vue'

          hits: [] 

        }) 

        const fetchData = async (query) => { 

          const data = await fetch

            `https://hn.algolia.com/api/v1/search?query=${query}` 

          ).then(rsp => rsp.json()) 

          state.hits = data.hits 

        } 

        onMounted(() => { 

          fetchData(state.query) 

          watchEffect(() => { 

            fetchData(state.query) 

          }) 

        }) 

        return state 

      } 

    由于 watchEffect() 初次调用的时分,其回调就会执行一次,形成初始化时会央求两次接口,所以我们需求把 onMounted 中的 fetchData 删掉。

    onMounted(() => { 

    - fetchData(state.query) 

      watchEffect(() => { 

        fetchData(state.query) 

      }) 

    }) 


    Demo

    watchEffect() 会监听传入函数内一切的照应式数据,一旦其中的某个数据发作变化,函数就会重新执行。假设要取消监听,可以调用 watchEffect() 的前往值,它的前往值为一个函数。下面举个例子:

    const stop = watchEffect(() => { 

      if (state.query === 'vue3') { 

        // 当 query 为 vue3 时,中止监听 

        stop() 

      } 

      fetchData(state.query) 

    }) 

    当我们在输入框输入 "vue3" 后,就不会再发起央求了。


    Demo

    前往事情办法

    如今有个成绩就是 input 内的值每次修正都会触发一次央求,我们可以添加一个按钮,点击按钮后再触发 state.query 的更新。

    <template> 

      <input type="text" v-model="input" /> 

      <button @click="setQuery">搜索</button> 

      <ul> 

        <li 

          v-for="item of hits" 

          :key="item.objectID" 

        > 

          <a :href="item.url">{{item.title}}</a> 

        </li> 

      </ul> 

    </template> 

     

    <script> 

    import { reactive, onMounted, watchEffect } from 'vue' 

     

    export default { 

      setup() { 

        const state = reactive({ 

          input: 'vue'

          query: 'vue'

          hits: [] 

        }) 

        const fetchData = async (query) => { 

          const data = await fetch

            `https://hn.algolia.com/api/v1/search?query=${query}` 

          ).then(rsp => rsp.json()) 

          state.hits = data.hits 

        } 

        onMounted(() => { 

          watchEffect(() => { 

            fetchData(state.query) 

          }) 

        }) 

         

        const setQuery = () => { 

          state.query = state.input 

        } 

        return { setQuery, state } 

      } 

    </script> 

    可以留意到 button 绑定的 click 事情的办法,也是经过 setup() 办法前往的,我们可以将 setup() 办法前往值了解为 Vue2 中 data() 办法和 methods 对象的兼并。

    原先的前往值 state 变成了如今前往值的一个属性,所以我们在模板层取数据的时分,需求停止一些修正,在前面加上 state.。

    <template> 

      <input type="text" v-model="state.input" /> 

      <button @click="setQuery">搜索</button> 

      <ul> 

        <li 

          v-for="item of state.hits" 

          :key="item.objectID" 

        > 

          <a :href="item.url">{{item.title}}</a> 

        </li> 

      </ul> 

    </template> 


    Demo

    前往数据

    修正作为强迫症患者,在模板层经过 state.xxx 的方式获取数据真实是舒服,那我们是不是可以经过对象解构的方式将 state 的数据前往呢?

    <template> 

      <input type="text" v-model="input" /> 

      <button class="search-btn" @click="setQuery">搜索</button> 

      <ul class="results"

        <li 

          v-for="item of hits" 

          :key="item.objectID" 

        > 

          <a :href="item.url">{{item.title}}</a> 

        </li> 

      </ul> 

    </template> 

     

    <script> 

    import { reactive, onMounted, watchEffect } from 'vue' 

     

    export default { 

      setup(props, ctx) { 

        const state = reactive({ 

          input: 'vue'

          query: 'vue'

          hits: [] 

        }) 

        // 省略部分代码... 

        return { 

          ...state, 

          setQuery, 

        } 

      } 

    </script> 

    答案是『不可以』。修正代码后,可以看到页面虽然发起了央求,但是页面并没有展现数据。

    state 在解构后,数据就变成了静态数据,不能再被跟踪,前往值相似于:

    export default { 

      setup(props, ctx) { 

        // 省略部分代码... 

        return { 

          input: 'vue'

          query: 'vue'

          hits: [], 

          setQuery, 

        } 

      } 

    Vue 3 的组合 API 如何央求数据?

    Demo

    为了跟踪基础类型的数据(即非对象数据),Vue3 也提出了处置方案:ref() 。

    import { ref } from 'vue' 

     

    const count = ref(0) 

    console.log(count.value) // 0 

     

    count.value++ 

    console.log(count.value) // 1 

    下面为 Vue 3 的官方案例,ref() 办法前往的是一个对象,无论是修正还是获取,都需求取前往对象的 value 属性。

    (责任编辑:admin)