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项目打包后文件过大问题

    这篇文章主要介绍了如何解决vue项目打包后文件过大问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • vue项目部署到Apache服务器中遇到的问题解决

    vue项目部署到Apache服务器中遇到的问题解决

    这篇文章主要介绍了vue项目部署到Apache中遇到的问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • vue如何实现对请求参数进行签名

    vue如何实现对请求参数进行签名

    这篇文章主要介绍了vue如何实现对请求参数进行签名问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • element编辑表单el-radio回显之后无法选择的问题解决

    element编辑表单el-radio回显之后无法选择的问题解决

    今天主要来谈一下element-ui编辑表单中的el-radio回显之后无法选择的问题,主要涉及到vue的双向绑定,以及element-ui编辑表单中的el-radio的默认类型,感兴趣的可以了解一下
    2021-08-08
  • 详解​Vue虚拟DOM如何提高前端开发效率

    详解​Vue虚拟DOM如何提高前端开发效率

    这篇文章主要为大家介绍了详解​Vue虚拟DOM如何提高前端开发效率,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • vue emit之Property or method “$$v“ is not defined的解决

    vue emit之Property or method “$$v“ i

    这篇文章主要介绍了vue emit之Property or method “$$v“ is not defined的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • vue 导航锚点_点击平滑滚动,导航栏对应变化详解

    vue 导航锚点_点击平滑滚动,导航栏对应变化详解

    这篇文章主要介绍了vue 导航锚点_点击平滑滚动,导航栏对应变化详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vite创建一个标准vue3+ts+pinia项目

    vite创建一个标准vue3+ts+pinia项目

    本文主要介绍了vite创建一个标准vue3+ts+pinia项目,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • vue3中defineEmits的使用举例详解

    vue3中defineEmits的使用举例详解

    这篇文章主要给大家介绍了关于vue3中defineEmits使用的相关资料,在Vue3中可以使用defineEmits函数来定义组件的自定义事件,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • 手把手教你搭建vue3.0项目架构

    手把手教你搭建vue3.0项目架构

    这篇文章手把手教你搭建vue3.0项目架构,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-11-11

最新评论