老师你好,这一小节我用reactive改写后有两个问题麻烦解答下

来源:3-13 模块化难度上升 - useURLLoader

Hania冲鸭

2022-12-18

问题一:我用reactive改写后运行正确,但是想请老师帮忙看下代码逻辑是否有什么问题
问题二:在template模板里引用data时,为什么data里的属性会从 toRefs 转成了 ref ?

import { reactive, ref, toRefs } from 'vue'
import axios from 'axios'

function useURLLoader (url: string) {
  // const result = ref(null)
  // const loading = ref(true)
  // const loaded = ref(false)
  // const error = ref(null)
  const reData = reactive({
    result: null,
    loading: true,
    loaded: false,
    error: null
  })

  axios.get(url).then((rawData) => {
    // loading.value = false
    // loaded.value = true
    // result.value = rawData.data
    reData.loading = false
    reData.loaded = true
    reData.result = rawData.data
  }).catch(e => {
    reData.error = e
    reData.loading = false
  })
  const data = toRefs(reData)
  return { data }
}

export default useURLLoader
<template>
  <img alt="Vue logo" src="./assets/logo.png">
  Hello
  <h1 v-if="data.loading.value">Loading......</h1>
  <img v-if="data.loaded.value" :src="data.result.value.message">
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import useURLLoader from './hooks/useURLLoader'
// import HelloWorld  from './components/HelloWorld.vue';


export default defineComponent({
  name: 'App',
  // components: {
  //   HelloWorld
  // }
  setup() {
    const { data } = useURLLoader('https://dog.ceo/api/breeds/image/random')
    return { data }
  }
});
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

写回答

2回答

张轩

2022-12-21

同学你好

是这样的,假如是 ref 对象是放置到一个 object 返回的,那么在访问的时候就必须使用 value 属性,template 不会帮你自动展开,就像你写的那样。

// 也就是说你的 return 是这样,
return { data }
// 其实是这样 
return { data: { loading: Ref类型的值, ...其他值 }}
// 那么模版中就是要 data.loading.value
// 假如你直接返回的是 Ref 对象不在外面再包裹一层,比如直接返回
return { ...data }
// 其实返回的是
return { loading: Ref类型的值, ...其他值 }
// 那么这个时候,模版中就可以直接使用了。
<h1 v-if="loading">Loading......</h1>
<img v-if="loaded" :src="result.message">


0
0

张轩

2022-12-19

同学你好

1 写的没什么问题 挺好的

2 这就是 toRefs 的作用啊,它的作用就是把一个 reactive 对象其中的每一项都转换成 ref。所以你函数返回的其实是一个个的 ref 对象,还有你的template 中应该是不用添加一个个的value 属性的,一个ref 对象写在模版里面的时候,会自动解析它的 value 属性。

0
3
Hania冲鸭
回复
张轩
https://gitee.com/hania/vue3-basic.git
2022-12-20
共3条回复

Vue3 + TS 仿知乎专栏企业级项目

带你完成前后端分离复杂项目,率先掌握 vue3 造轮子技能

3142 学习 · 2313 问题

查看课程