vue3中调用api接口实现数据的渲染以及详情方式

 更新时间:2022年08月15日 15:09:18   作者:摩羯座**  
这篇文章主要介绍了vue3中调用api接口实现数据的渲染以及详情方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

调用api接口实现数据的渲染及详情

首先新建一个项目

yarn create vite vue3-template --template vue

然后下载相应的api

npm i axios router

首先配置

App.vue

<script setup>
</script>
<template>
  <router-view></router-view>
</template>
<style>
</style>

main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')

封装axios src/utils/request.js

import axios from 'axios'
const instance = axios.create({
    baseURL:"https://cnodejs.org/api/v1"
})
export default instance

在src/api/topics.js 中请求

import axios from '../utils/request';
//请求列表的函数
export const getTopics = (params) => axios("/topics",{params})
//根据id获取详情
export const getTopic = (id,params) => axios.get(`/topic/${id}`,{params})

新建hooks src/componsables/useTopics.js

import { ref,onMounted } from 'vue'
import { getTopics } from '../api/topics'
export default function useTopics(){
    /**
 * 数据渲染功能
 */
//声明 数据
const topics = ref([])
//请求数据
onMounted(async () => {
    const res =await getTopics()
    topics.value = res.data.data
})
return {
    topics
}
}

新建hooks src/componsables/useTopic.js

import { useRouter } from 'vue-router'
export default function useTopics(){
  //跳转
const router = useRouter()
const go = (id) =>{
    router.push("/detail?id=" + id)
}
return {
    go
}
}

在 src 下 新建 /views/Index.vue

<template>
  <div>
      <ul>
          <li v-for="topic in topics" :key="topic.id" @click="go(topic.id)">
           {{topic.title}}
          </li>
      </ul>
  </div>
</template>
<script setup>
// import { onMounted,ref} from 'vue';
// import { getTopics } from '../api/topics'
// import { useRouter } from 'vue-router'
// /**
//  * 数据渲染功能
//  */
// //声明 数据
// const topics = ref([])
// //请求数据
// onMounted(async () => {
//     const res =await getTopics()
//     topics.value = res.data.data
// })
//数据渲染
import useTopics from '../componsables/useTopics'
const { topics } = useTopics();
//跳转
// const router = useRouter()
// const go = (id) =>{
//     router.push("/detail?id=" + id)
// }
//跳转
import useTopic from '../componsables/useTopic'
const { go } = useTopic();
</script>
<style>
</style>

在 src 下 新建 /views/Detail.vue

<template>
   <div>
     {{topic.title}}
     
     <!-- ?表示如果后续的属性不存在了 就不获取了 -->
     {{topic.author?.loginname}}
     {{topic.create_at}}
   </div>
</template>
<script setup>
 import { ref, onMounted } from 'vue';
 import { useRoute } from 'vue-router';
 import { getTopic } from '../api/topics';
 
 let topic = ref({})
 const route = useRoute()
 //获取id
 const { id } = route.query
 //拿着id进行数据的请求
 onMounted( async () => {
     const res = await getTopic(id)
     topic.value = res.data.data
 })
</script>
<style>
</style>

在src 下 新建 router/index.js

import { createWebHashHistory ,createRouter} from "vue-router"
import Index from '../views/Index.vue'
const routes = [
     {
         path:'/',
         component:Index
     },
     {
         path:'/detail',
         component:()=> import('../views/Detail.vue')
     },
     {
         path:"/store",
         component:()=> import('../views/Store.vue')
     }
]
 const router = createRouter({
    history:createWebHashHistory(),
    routes
})
export default router

即可实现数据的渲染以及跳转功能

vue3常用api梳理

setup参数

1.props

props 是响应式的,当传入新的 props 时,它将被更新。

示例如下:

//父组件
<template>
  <div>
    <com :num="num"></com>
    <button @click="add">++</button>
  </div>
</template>
<script>
import { ref } from 'vue';
import com from './components/com.vue';
export default {
  name: 'App',
  components: { com },
  setup() {
    const num = ref(1);
    const add = () => {
      num.value++
    }
    return {
      num,
      add
    }
  }
}
</script>
//子组件
<template>
  <div class="hello">
    {{num}}
  </div>
</template>
<script>
export default {
  props: {
    num: Number
  }
}
</script>

当点击按钮执行add方法,子组件num会自动更新。

2.context

  • attrs:Attribute (非响应式对象,等同于 $attrs)
  • slots:插槽 (非响应式对象,等同于 $slots)
  • emit:触发事件 (方法,等同于 $emit)
  • expose:暴露公共 property (函数)

生命周期

选项式 APIHook inside setup
beforeCreateNot needed*
createdNot needed*
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted
errorCapturedonErrorCaptured
renderTrackedonRenderTracked
renderTriggeredonRenderTriggered
activatedonActivated
deactivatedonDeactivated

示例如下:

<template>
  <div>
  </div>
</template>
<script>
import { onMounted } from 'vue';
export default {
  name: 'App',
  setup() {
    onMounted(() => {
      console.log('mounted')
    })
  }
}
</script>

响应式数据 ref、reactive

  • ref:将一个原始数据类型(String、Number、BigInt、Boolean、Symbol、Null、Undefined)转换成一个带有响应式特性的数据类型。
  • reactive:将一个对象(Object) 转换成带有响应式的特性。

示例如下:

<template>
  <div>
    <div>{{age}}</div>
    <div>{{data.height}} {{data.weight}}</div>
    <button @click="change">修改</button>
  </div>
</template>
<script>
import { reactive, ref } from 'vue';
export default {
  name: 'App',
  setup() {
    const age = ref(18);
    const data = reactive({
      sex: 1,
      height: 178,
      weight: 110
    })
    const change = () => {
      age.value = 20;
      data.height = 180;
      data.weight = 1111;
    }
    return {
      age,
      data,
      change
    }
  }
}
</script>

可能会觉得data.xxx 的写法太麻烦,那么我们可以使用torefs来解构。

torefs:可以将一个响应型对象(reactive) 转化为普通对象(obj),同时又把该对象中的每一个属性转化成对应的响应式属性(ref)。

示例如下,效果同上:

<template>
  <div>
    <div>{{age}}</div>
    <div>{{height}} {{weight}}</div>
    <button @click="change">修改</button>
  </div>
</template>
<script>
import { reactive, ref, toRefs } from 'vue';
export default {
  name: 'App',
  setup() {
    const age = ref(18);
    const data = reactive({
      sex: 1,
      height: 178,
      weight: 110
    })
    const change = () => {
      age.value = 20;
      data.height = 180;
      data.weight = 1111;
    }
    return {
      age,
      ...toRefs(data),
      change
    }
  }
}
</script>

在实际的开发过程中,给对象整体重新赋值的情况也屡见不鲜,倘若直接重新是不可以的,可以自行尝试,下面的一种比较推荐的写法,效果同上:

<template>
  <div>
    <div>{{content.height}} {{content.weight}}</div>
    <button @click="change">修改</button>
  </div>
</template>
<script>
import { reactive, toRefs } from 'vue';
export default {
  name: 'App',
  setup() {
    const data = reactive({
      content:{
        sex: 1,
        height: 178,
        weight: 110
      }
    })
    const change = () => {
      data.content ={
        sex: 2,
        height: 180,
        weight: 120
      }
    }
    return {
      ...toRefs(data),
      change
    }
  }
}
</script>

coumputed

<template>
  <div>
    <div>{{age}} {{age2}}</div>
    <button @click="add">++</button>
  </div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
  name: 'App',
  setup() {
    const age = ref(18);
    const age2 = computed(() => {
      return age.value * 2
    })
    const add = () => {
      age.value++
    }
    return {
      age,
      age2,
      add
    }
  }
}
</script>

watch && watchEffect

watchEffect 它与 watch 的区别主要有以下几点:

  • watchEffect不需要手动传入依赖
  • watchEffect每次初始化时会执行一次回调函数来自动获取依赖
  • watchEffect无法获取到原值,只能得到变化后的值

watch示例:

<template>
  <div>
    <div>{{age}} {{age2}}</div>
    <div>{{data.height}} {{data2.height}}</div>
    <button @click="add">++</button>
  </div>
</template>
<script>
import { ref, reactive, watch } from 'vue';
export default {
  name: 'App',
  setup() {
    const age = ref(18);
    const age2 = ref(0);
    const data = reactive({
      height: 178
    })
    const data2 = reactive({
      height: 0
    })
    
    /* eslint-disable */
    watch([age, ()=> data.height], ([newAge, newHeight], [oldAge, oldHeight]) =>{
      age2.value = oldAge;
      data2.height = oldHeight;
    })
    /* eslint-disable */
    const add = () => {
      age.value++,
      data.height++
    }
    return {
      age,
      age2,
      data,
      data2,
      add
    }
  }
}
</script>

watchEffect示例:

<template>
  <div>
    <div>{{age}} {{age2}}</div>
    <div>{{data.height}} {{data2.height}}</div>
    <button @click="add">++</button>
  </div>
</template>
<script>
import { ref, reactive, watchEffect } from 'vue';
export default {
  name: 'App',
  setup() {
    const age = ref(18);
    const age2 = ref(0);
    const data = reactive({
      height: 178
    })
    const data2 = reactive({
      height: 0
    })
    watchEffect(() => {
      age2.value = age.value;
      data2.height = data.height;
    })
    const add = () => {
      age.value++,
      data.height++
    }
    return {
      age,
      age2,
      data,
      data2,
      add
    }
  }
}
</script>

获取元素

获取单个元素使用ref(null),获取v-for中的ref数组需要绑定函数。

示例如下:

<template>
  <div>
    <div ref="name"></div>
    <div v-for="(val,index) in arr" :key="index" :ref="setItemRef"></div>
  </div>
</template>
<script>
import { ref, onMounted } from 'vue';
export default {
  name: 'App',
  setup() {
    const name = ref(null);
    const arr = new Array(10);
    const itemRefs = []
    const setItemRef = el => {
      if (el) {
        itemRefs.push(el)
      }
    }
    onMounted(() => {
      name.value.innerHTML = '风舞红枫';
      itemRefs.forEach((item, index) => {
        item.innerHTML = index;
      })
    })
    return {
      name,
      arr,
      setItemRef
    }
  }
}
</script>

this不可用

在 setup() 内部,this 不是该活跃实例的引用,因为 setup() 是在解析其它组件选项之前被调用的,所以 setup() 内部的 this 的行为与其它选项中的 this 完全不同。

可以使用下方语句代替

const {proxy} = getCurrentInstance()

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。 

相关文章

  • vue 如何使用vue-cropper裁剪图片你知道吗

    vue 如何使用vue-cropper裁剪图片你知道吗

    这篇文章主要为大家介绍了vue 使用vue-cropper裁剪图片,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • Vue+Vant实现7天日历展示并在切换日期时实时变换功能

    Vue+Vant实现7天日历展示并在切换日期时实时变换功能

    本文介绍了如何利用Vue和Vant框架结合moment.js插件来实现一个7天日历展示功能,在这个功能中,用户可以在切换日期时看到界面的实时变化,此外,文章还提供了代码实现和效果测试的详细步骤,帮助开发者能够顺利完成类似的项目开发
    2024-10-10
  • Vue实现当前页面刷新的五种方法总结

    Vue实现当前页面刷新的五种方法总结

    这篇文章主要介绍了Vue中实现页面刷新的5种方法,包括使用$router.go(0)、location.reload()、通过router-view的key属性、使用v-if指令手动触发组件重新渲染,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-02-02
  • 基于vue实现网站前台的权限管理(前后端分离实践)

    基于vue实现网站前台的权限管理(前后端分离实践)

    这篇文章主要介绍了基于vue实现网站前台的权限管理(前后端分离实践),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 用vue构建多页面应用的示例代码

    用vue构建多页面应用的示例代码

    这篇文章主要介绍了用vue构建多页面应用的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • vue调用本地摄像头实现拍照功能

    vue调用本地摄像头实现拍照功能

    这篇文章主要介绍了vue调用本地摄像头实现拍照功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • Nuxt pages下不同的页面对应layout下的页面布局操作

    Nuxt pages下不同的页面对应layout下的页面布局操作

    这篇文章主要介绍了Nuxt pages下不同的页面对应layout下的页面布局操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • Vue实现用户自定义字段显示数据的方法

    Vue实现用户自定义字段显示数据的方法

    今天小编就为大家分享一篇Vue实现用户自定义字段显示数据的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • vue使用recorder.js实现录音功能

    vue使用recorder.js实现录音功能

    这篇文章主要为大家详细介绍了vue使用recorder.js实现录音功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • vue element el-form 多级嵌套验证的实现示例

    vue element el-form 多级嵌套验证的实现示例

    本文主要介绍了vue element el-form 多级嵌套验证的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08

最新评论