vue3中調(diào)用api接口實(shí)現(xiàn)數(shù)據(jù)的渲染以及詳情方式
調(diào)用api接口實(shí)現(xiàn)數(shù)據(jù)的渲染及詳情
首先新建一個(gè)項(xiàng)目
yarn create vite vue3-template --template vue
然后下載相應(yīng)的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 中請(qǐng)求
import axios from '../utils/request';
//請(qǐng)求列表的函數(shù)
export const getTopics = (params) => axios("/topics",{params})
//根據(jù)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(){
? ? /**
?* 數(shù)據(jù)渲染功能
?*/
//聲明 數(shù)據(jù)
const topics = ref([])
//請(qǐng)求數(shù)據(jù)
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(){
? //跳轉(zhuǎn)
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'
// /**
// ?* 數(shù)據(jù)渲染功能
// ?*/
// //聲明 數(shù)據(jù)
// const topics = ref([])
// //請(qǐng)求數(shù)據(jù)
// onMounted(async () => {
// ? ? const res =await getTopics()
// ? ? topics.value = res.data.data
// })
//數(shù)據(jù)渲染
import useTopics from '../componsables/useTopics'
const { topics } = useTopics();
//跳轉(zhuǎn)
// const router = useRouter()
// const go = (id) =>{
// ? ? router.push("/detail?id=" + id)
// }
//跳轉(zhuǎn)
import useTopic from '../componsables/useTopic'
const { go } = useTopic();
</script>
<style>
</style>在 src 下 新建 /views/Detail.vue
<template>
? ?<div>
? ? ?{{topic.title}}
? ? ?
? ? ?<!-- ?表示如果后續(xù)的屬性不存在了 就不獲取了 -->
? ? ?{{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進(jìn)行數(shù)據(jù)的請(qǐng)求
?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即可實(shí)現(xiàn)數(shù)據(jù)的渲染以及跳轉(zhuǎn)功能
vue3常用api梳理
setup參數(shù)
1.props
props 是響應(yīng)式的,當(dāng)傳入新的 props 時(shí),它將被更新。
示例如下:
//父組件
<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>
當(dāng)點(diǎn)擊按鈕執(zhí)行add方法,子組件num會(huì)自動(dòng)更新。

2.context
attrs:Attribute (非響應(yīng)式對(duì)象,等同于 $attrs)slots:插槽 (非響應(yīng)式對(duì)象,等同于 $slots)emit:觸發(fā)事件 (方法,等同于 $emit)expose:暴露公共 property (函數(shù))
生命周期
| 選項(xiàng)式 API | Hook inside setup |
|---|---|
| beforeCreate | Not needed* |
| created | Not needed* |
| beforeMount | onBeforeMount |
| mounted | onMounted |
| beforeUpdate | onBeforeUpdate |
| updated | onUpdated |
| beforeUnmount | onBeforeUnmount |
| unmounted | onUnmounted |
| errorCaptured | onErrorCaptured |
| renderTracked | onRenderTracked |
| renderTriggered | onRenderTriggered |
| activated | onActivated |
| deactivated | onDeactivated |
示例如下:
<template>
<div>
</div>
</template>
<script>
import { onMounted } from 'vue';
export default {
name: 'App',
setup() {
onMounted(() => {
console.log('mounted')
})
}
}
</script>

響應(yīng)式數(shù)據(jù) ref、reactive
ref:將一個(gè)原始數(shù)據(jù)類型(String、Number、BigInt、Boolean、Symbol、Null、Undefined)轉(zhuǎn)換成一個(gè)帶有響應(yīng)式特性的數(shù)據(jù)類型。reactive:將一個(gè)對(duì)象(Object) 轉(zhuǎn)換成帶有響應(yīng)式的特性。
示例如下:
<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>

可能會(huì)覺(jué)得data.xxx 的寫(xiě)法太麻煩,那么我們可以使用torefs來(lái)解構(gòu)。
torefs:可以將一個(gè)響應(yīng)型對(duì)象(reactive) 轉(zhuǎn)化為普通對(duì)象(obj),同時(shí)又把該對(duì)象中的每一個(gè)屬性轉(zhuǎn)化成對(duì)應(yīng)的響應(yīng)式屬性(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>
在實(shí)際的開(kāi)發(fā)過(guò)程中,給對(duì)象整體重新賦值的情況也屢見(jiàn)不鮮,倘若直接重新是不可以的,可以自行嘗試,下面的一種比較推薦的寫(xiě)法,效果同上:
<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 的區(qū)別主要有以下幾點(diǎn):
- watchEffect不需要手動(dòng)傳入依賴
- watchEffect每次初始化時(shí)會(huì)執(zhí)行一次回調(diào)函數(shù)來(lái)自動(dòng)獲取依賴
- watchEffect無(wú)法獲取到原值,只能得到變化后的值
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>

獲取元素
獲取單個(gè)元素使用ref(null),獲取v-for中的ref數(shù)組需要綁定函數(shù)。
示例如下:
<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 = '風(fēng)舞紅楓';
itemRefs.forEach((item, index) => {
item.innerHTML = index;
})
})
return {
name,
arr,
setItemRef
}
}
}
</script>

this不可用
在 setup() 內(nèi)部,this 不是該活躍實(shí)例的引用,因?yàn)?setup() 是在解析其它組件選項(xiàng)之前被調(diào)用的,所以 setup() 內(nèi)部的 this 的行為與其它選項(xiàng)中的 this 完全不同。
可以使用下方語(yǔ)句代替
const {proxy} = getCurrentInstance()以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue+Vant實(shí)現(xiàn)7天日歷展示并在切換日期時(shí)實(shí)時(shí)變換功能
本文介紹了如何利用Vue和Vant框架結(jié)合moment.js插件來(lái)實(shí)現(xiàn)一個(gè)7天日歷展示功能,在這個(gè)功能中,用戶可以在切換日期時(shí)看到界面的實(shí)時(shí)變化,此外,文章還提供了代碼實(shí)現(xiàn)和效果測(cè)試的詳細(xì)步驟,幫助開(kāi)發(fā)者能夠順利完成類似的項(xiàng)目開(kāi)發(fā)2024-10-10
Vue實(shí)現(xiàn)當(dāng)前頁(yè)面刷新的五種方法總結(jié)
這篇文章主要介紹了Vue中實(shí)現(xiàn)頁(yè)面刷新的5種方法,包括使用$router.go(0)、location.reload()、通過(guò)router-view的key屬性、使用v-if指令手動(dòng)觸發(fā)組件重新渲染,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-02-02
基于vue實(shí)現(xiàn)網(wǎng)站前臺(tái)的權(quán)限管理(前后端分離實(shí)踐)
這篇文章主要介紹了基于vue實(shí)現(xiàn)網(wǎng)站前臺(tái)的權(quán)限管理(前后端分離實(shí)踐),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
用vue構(gòu)建多頁(yè)面應(yīng)用的示例代碼
這篇文章主要介紹了用vue構(gòu)建多頁(yè)面應(yīng)用的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
vue調(diào)用本地?cái)z像頭實(shí)現(xiàn)拍照功能
這篇文章主要介紹了vue調(diào)用本地?cái)z像頭實(shí)現(xiàn)拍照功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
Nuxt pages下不同的頁(yè)面對(duì)應(yīng)layout下的頁(yè)面布局操作
這篇文章主要介紹了Nuxt pages下不同的頁(yè)面對(duì)應(yīng)layout下的頁(yè)面布局操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
Vue實(shí)現(xiàn)用戶自定義字段顯示數(shù)據(jù)的方法
今天小編就為大家分享一篇Vue實(shí)現(xiàn)用戶自定義字段顯示數(shù)據(jù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
vue使用recorder.js實(shí)現(xiàn)錄音功能
這篇文章主要為大家詳細(xì)介紹了vue使用recorder.js實(shí)現(xiàn)錄音功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
vue element el-form 多級(jí)嵌套驗(yàn)證的實(shí)現(xiàn)示例
本文主要介紹了vue element el-form 多級(jí)嵌套驗(yàn)證的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08

