vue3中調(diào)用api接口實現(xiàn)數(shù)據(jù)的渲染以及詳情方式
調(diào)用api接口實現(xiàn)數(shù)據(jù)的渲染及詳情
首先新建一個項目
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 中請求
import axios from '../utils/request';
//請求列表的函數(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([])
//請求數(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([])
// //請求數(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ù)的請求
?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即可實現(xiàn)數(shù)據(jù)的渲染以及跳轉(zhuǎn)功能
vue3常用api梳理
setup參數(shù)
1.props
props 是響應(yīng)式的,當(dāng)傳入新的 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>
當(dāng)點擊按鈕執(zhí)行add方法,子組件num會自動更新。

2.context
attrs:Attribute (非響應(yīng)式對象,等同于 $attrs)slots:插槽 (非響應(yīng)式對象,等同于 $slots)emit:觸發(fā)事件 (方法,等同于 $emit)expose:暴露公共 property (函數(shù))
生命周期
| 選項式 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:將一個原始數(shù)據(jù)類型(String、Number、BigInt、Boolean、Symbol、Null、Undefined)轉(zhuǎn)換成一個帶有響應(yīng)式特性的數(shù)據(jù)類型。reactive:將一個對象(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>

可能會覺得data.xxx 的寫法太麻煩,那么我們可以使用torefs來解構(gòu)。
torefs:可以將一個響應(yīng)型對象(reactive) 轉(zhuǎn)化為普通對象(obj),同時又把該對象中的每一個屬性轉(zhuǎn)化成對應(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>
在實際的開發(fā)過程中,給對象整體重新賦值的情況也屢見不鮮,倘若直接重新是不可以的,可以自行嘗試,下面的一種比較推薦的寫法,效果同上:
<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ū)別主要有以下幾點:
- watchEffect不需要手動傳入依賴
- watchEffect每次初始化時會執(zhí)行一次回調(diào)函數(shù)來自動獲取依賴
- 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數(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 不是該活躍實例的引用,因為 setup() 是在解析其它組件選項之前被調(diào)用的,所以 setup() 內(nèi)部的 this 的行為與其它選項中的 this 完全不同。
可以使用下方語句代替
const {proxy} = getCurrentInstance()以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue如何實現(xiàn)對請求參數(shù)進(jìn)行簽名
這篇文章主要介紹了vue如何實現(xiàn)對請求參數(shù)進(jìn)行簽名問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
element編輯表單el-radio回顯之后無法選擇的問題解決
今天主要來談一下element-ui編輯表單中的el-radio回顯之后無法選擇的問題,主要涉及到vue的雙向綁定,以及element-ui編輯表單中的el-radio的默認(rèn)類型,感興趣的可以了解一下2021-08-08
vue emit之Property or method “$$v“ i
這篇文章主要介紹了vue emit之Property or method “$$v“ is not defined的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
vue 導(dǎo)航錨點_點擊平滑滾動,導(dǎo)航欄對應(yīng)變化詳解
這篇文章主要介紹了vue 導(dǎo)航錨點_點擊平滑滾動,導(dǎo)航欄對應(yīng)變化詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
vite創(chuàng)建一個標(biāo)準(zhǔn)vue3+ts+pinia項目
本文主要介紹了vite創(chuàng)建一個標(biāo)準(zhǔn)vue3+ts+pinia項目,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

