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-01element編輯表單el-radio回顯之后無法選擇的問題解決
今天主要來談一下element-ui編輯表單中的el-radio回顯之后無法選擇的問題,主要涉及到vue的雙向綁定,以及element-ui編輯表單中的el-radio的默認(rèn)類型,感興趣的可以了解一下2021-08-08vue emit之Property or method “$$v“ i
這篇文章主要介紹了vue emit之Property or method “$$v“ is not defined的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06vue 導(dǎo)航錨點_點擊平滑滾動,導(dǎo)航欄對應(yīng)變化詳解
這篇文章主要介紹了vue 導(dǎo)航錨點_點擊平滑滾動,導(dǎo)航欄對應(yīng)變化詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08vite創(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