请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

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

问题一:我用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回答

同学你好

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

1
2
3
4
5
6
7
8
9
10
11
12
// 也就是说你的 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 回复 有任何疑惑可以回复我~
张轩 2022-12-19 11:22:37

同学你好

1 写的没什么问题 挺好的

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

0 回复 有任何疑惑可以回复我~
  • 提问者 Hania冲鸭 #1
    我按照老师说的,在template中不使用value属性,直接用data.loading和data.loaded,但是这样loading和loaded的值不会改变,图片展示不出来
    回复 有任何疑惑可以回复我~ 2022-12-19 21:03:01
  • 张轩 回复 提问者 Hania冲鸭 #2
    同学你好 如果可以的话 请提供一下你的代码库(git)给我吧,我看一下代码,本地运行一下就清楚很多啦,看图有什么不是很直观。
    回复 有任何疑惑可以回复我~ 2022-12-20 09:43:36
  • 提问者 Hania冲鸭 回复 张轩 #3
    https://gitee.com/hania/vue3-basic.git
    回复 有任何疑惑可以回复我~ 2022-12-20 13:42:10
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号