leafage诞生记(二nuxt.js如何在组件和页面请求数据)

布吉岛      2022-02-13     474

关键词:

本文个人博客地址:https://www.abeille.top/posts/detail/213489UI

上一篇 创建了前端工程,接下来开始写代码。

因为初始化项目,只是最小的一些基本依赖,再开发中,需要一些第三方的库来支持,比如样式/组件库。

在开发Leafage网站的过程中,我试用过viewui(原来叫iview)、element-ui、ant design vue、vuetify这几个组件库,但是约到后面会发现,使用组件库是比较容易开发界面,但是限制很多,而且很多文档写的不好,稍微复杂点的组合或者配置,很难实现,还有最重要的一点,除了vuetify之外的几个组件库, 都不是默认支持响应式的,需要自己适配,后来发现了nuxtjs的官网用的是css样式库tailwindcss,与它同样类似的还有bulma,bulma和tailwindcss都是css开发的,不包含任何框架依赖,但是bulma更类似于bootstrap,区别是不依赖jquery等任何Javascript,参考nuxtjs官网的开发,选择使用tailwindcss。

作为一个java开发的程序员,从零开始写前端,还不用组件库,是很难肯痛苦的事情,那找一个好看的模板来模仿,总是容易的吧,然后就开始网罗各大模板网站,有的模板可能需要花几块钱,买一个自己满意的,然后参照来写或者直接进行修改。

页面开发完成之后,需要请求服务接口,由于现在还没有开发后台服务,所以需要使用mock.js来进行api的模拟。

首先安装mock.js依赖:

yarn add mock.js -D

安装完成后,打开plugins目录,添加 mock.ts 文件(如果使用的是javascript,则创建mock.js),配置mock接口,示例如下:

import Mock from 'mockjs'

Mock.mock(/posts\.json/, {
  'list|1-10': [{
    'id|+1': 1,
    'title': 'my title'
  }]
})

配置完成之后,需要在nuxt.config.ts文件中进行配置,才会生效,否则,会执行默认的配置;

  // Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
  plugins: [
    '~/plugins/mock'
  ],

接下来就使用axios请求接口,获取数据了。

1、配置axios

因为初始化项目时,安装了axios工具,现在就可以在页面(pages目录下的.vue)或者组件(components目录下的.vue)中使用axios来请求数据。nuxtjs默认会配置axios的一些配置,如果想要进行自己的一些配置,那么在plugins目录下创建axios.ts文件,然后进行相关设置,参考如下:

import { Plugin } from '@nuxt/types'
import { AxiosRequestConfig, AxiosError } from 'axios'

const statusCode: any = {
  400: '请求参数错误',
  401: '权限不足, 请重新登录',
  403: '服务器拒绝本次访问',
  500: '内部服务器错误',
  501: '服务器不支持该请求中使用的方法',
  502: '网关错误',
  504: '网关超时'
}

export const accessor: Plugin = ({ error, app: { $axios }, redirect }) => {

  $axios.onRequest((config: AxiosRequestConfig) => {
    return config
  })

  $axios.onError((err: AxiosError<any>) => {
    const status: any = err.response?.status
    if (status === 404) {
      redirect('/error')
    } else {
      error({ message: statusCode[status] })
      return Promise.reject(err)
    }
  })
}

需要注意的是,当使用typescript时,引入axios的时候,不是

import axios form 'axios'

而是需要通过@nuxt/types引入Plugin,然后引入axios的AxiosRequestConfig和 AxiosError如果用到axios更多属性,则同样需要引入;

import { Plugin } from '@nuxt/types'
import { AxiosRequestConfig, AxiosError } from 'axios

和mockjs同样的,配置完成后,需要在nuxt.config.ts中的plugins项下加入此配置文件;

  // Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
  plugins: [
    '~/plugins/mock',
    '~/plugins/axios'
  ],

2、使用axios

基础的使用方法参考axios官方文档(中文文档:http://axios-js.com/zh-cn/docs/ ),包括同步请求、异步请求、并发请求等。

在nuxtjs中除了在vue勾子(Hook)中使用axios的一般场景,针对渲染的时机,它还提供了另外两种请求请求数据的函数,fetch() 和 asyncData()。

两个函数的共同点是,都是异步函数,所以在使用时需要await关键字,两者的区别是:

asyncData():

  • 只能在页面中使用,即pages目录下的.vue文件中,他会阻塞页面的加载,所以不能请求很大的数据量或者很多同步接口;
  • 不能使用this关键字;
  • 不能被调用,只在页面加载时,自动执行;

fetch():

  • 可以在组件中使用,也可以在页面中使用,即在components目录和pages目录下的.vue文件中都可以;
  • 可以使用this关键字;
  • 可以重复调用,即在组件中直接调用fetch()来重新获取数据;

针对两个函数的使用,我们通过一下示例来看看如何使用:

fetch()示例:

import { defineComponent } from "@vue/composition-api";
import { SERVER_URL } from "~/assets/request";

export default defineComponent({
  name: "Main",

  async fetch() {
    this.datas = await this.$axios
      .get(SERVER_URL.posts.concat("?page=0&size=10&order=", this.order))
      .then((res) => res.data);
  },

  data() {
    return {
      datas: [],
      order: "likes",
    };
  },

  methods: {
    retrieve(order: string) {
      this.order = order;
      this.$fetch(); // 这里调用fetch()函数,复用接口请求
    },
  },
});

示例中展示了,fetch()请求接口的使用以及在其他函数中如何被调用执行;

另外,使用fetch()会有一个$fetchState来判断fetch()执行情况,可以根据不同情况处理不同的页面逻辑,示例如下:

<div>
    <p v-if="$fetchState.pending">Fetching mountains...</p>
    <p v-else-if="$fetchState.error">An error occurred :(</p>
    <div v-else class="mb-12">
    </div>
</div>

asyncData示例:

import { defineComponent } from "@vue/composition-api";
import { SERVER_URL } from "~/assets/request";

export default defineComponent({
  name: "Portfolio",

  scrollToTop: true, // 这个配置会在加载页面是自动滚动到页面顶部

  async asyncData({ app: { $axios } }) { // asyncData()函数中不能使用this关键字,所以这里通过入参方式引入全局配置的一些参数,这里需要axios
    let [datas, categories] = await Promise.all([
      await $axios.$get(SERVER_URL.portfolio.concat("?page=0&size=10")),
      await $axios.$get(SERVER_URL.category.concat("?page=0&size=5")),
    ]);
    return { datas, categories };
  },

  data() {
    return {
      code: "",
      datas: [],
    };
  },

  methods: {
    retrieve(code: string) {
      this.code = code;
      this.$axios
        .get(SERVER_URL.portfolio.concat("?page=0&size=12&category=", code))
        .then((res) => (this.datas = res.data));
    },
  },

  head() {
    const title = "Portfolio - Leafage";
    const description =
      "Leafage的作品集,包含旅行记录、生活分享等资源信息,提供原创、优质、完整内容";
    return {
      title,
      meta: [
        { hid: "description", name: "description", content: description },
        // Open Graph
        { hid: "og:title", property: "og:title", content: title },
        {
          hid: "og:description",
          property: "og:description",
          content: description,
        },
        // Twitter Card
        { hid: "twitter:title", name: "twitter:title", content: title },
        {
          hid: "twitter:description",
          name: "twitter:description",
          content: description,
        },
      ],
    };
  },
});

通过代码可以看到,在asyncData()函数使用时,传入了对象参数 app: { $axios },因为asyncData()执行的时候,组件还没有初始化完成,因此只能通过引入全局挂在的配置来使用一些工具,同样可以传入 $store, $router等;

推荐几个模板站:

  1. http://www.bootstrapmb.com/
  2. https://tailwindcomponents.com/
  3. https://www.mobantu.com/6548....

如何在 nuxt.js 上从子组件获取父组件的值?

】如何在nuxt.js上从子组件获取父组件的值?【英文标题】:HowtogetanvaluefromChildcomponenttoParentonnuxt.js?【发布时间】:2019-11-3022:31:48【问题描述】:我一直在尝试将数据从子A($emit)组件传递给父组件,从父组件传递给子B(props)。使用n... 查看详情

如何使用 Nuxt.js 仅在一个组件中使用插件?

】如何使用Nuxt.js仅在一个组件中使用插件?【英文标题】:HowtouseplugininonlyonecomponentusingNuxt.js?【发布时间】:2021-11-1617:45:13【问题描述】:我正在用nuxt.js做一个简单的博客网站,我只需要在一个组件中导入编辑器,我不想使用n... 查看详情

NUXT.js 和 Axios 运行时如何避免代码重复?

】NUXT.js和Axios运行时如何避免代码重复?【英文标题】:HowtoavoidcodeduplicationwhenrunningNUXT.jsandAxios?【发布时间】:2020-11-2205:28:43【问题描述】:如果相似的代码(如示例中)在不同的组件中重复,但我在函数参数中传递的名称略... 查看详情

Nuxt.js 仅客户端组件

...直收到错误消息documentnotdefined。Nuxt.js文档没有提供关于如何仅在客户端加载和生成组件的明确说明。【问题讨论】:虽然有几个类似的问题,但没有一个给出完整的解决方案 查看详情

如何使用 Nuxt.js 从缓存中排除组件?

】如何使用Nuxt.js从缓存中排除组件?【英文标题】:HowtoexcludecomponentfromcachingusingNuxt.js?【发布时间】:2021-08-1411:18:15【问题描述】:我正在尝试在Nuxt.js中使用Vue.jskeep-aliveprop,我正在尝试缓存除一个之外的所有组件,这是我想... 查看详情

Vue.js 和 Nuxt.js

...麻烦,因为整个nuxt的工作方式之间的可见性为0%。问题:如何注册全局组件。如何在客户端行为的某些用户上切换nuxt中的布局。在哪里编写vue.use(somep 查看详情

如何在 Nuxt 中用一个组件创建无限路由

】如何在Nuxt中用一个组件创建无限路由【英文标题】:HowcreatetheinfiniteroutewithonecomponentinNuxt【发布时间】:2021-10-1415:29:07【问题描述】:我最近收到了一个使用Nuxt.js的项目,但遇到了一些问题。我有一个从API获取一些产品并从Vu... 查看详情

nuxt.js的学习路由组件的学习(代码片段)

...周期流程图分析1、异步加载数据asyncDataasyncData方法会在组件(限于页面组件) 查看详情

Tabulator + Nuxt.js:如何在回调中使用 axios?

】Tabulator+Nuxt.js:如何在回调中使用axios?【英文标题】:Tabulator+Nuxt.js:Howtouseaxiosincallbacks?【发布时间】:2020-01-1608:48:53【问题描述】:我尝试在我的Nuxt.js项目中添加Tabulator。我已经完成了下一个组件:<template><divref="table... 查看详情

Nuxt.js 中的组件可以与 Next.js 类似的客户端渲染和服务器渲染混合使用吗?

】Nuxt.js中的组件可以与Next.js类似的客户端渲染和服务器渲染混合使用吗?【英文标题】:CanyoumixupClientrenderingandServerrenderingforcomponentsinNuxt.jssimilartoNext.js?【发布时间】:2021-08-2707:47:41【问题描述】:在Next.js中,您可以在同一页... 查看详情

Nuxt.js + Bootstrap-Vue - 加载单个组件和指令

】Nuxt.js+Bootstrap-Vue-加载单个组件和指令【英文标题】:Nuxt.js+Bootstrap-Vue-Individualcomponentsanddirectivesloading【发布时间】:2018-12-1711:16:25【问题描述】:我正在努力将Bootstrap-Vue库集成到我的基于Nuxt.js的项目中。我通读了officialdocument... 查看详情

如何将 BootstrapVue 在 Nuxt.js 中使用 Purgecss 所需的所有内容列入白名单

】如何将BootstrapVue在Nuxt.js中使用Purgecss所需的所有内容列入白名单【英文标题】:HowdoIwhitelisteverythingIneedforBootstrapVuetoworkwithPurgecssinNuxt.js【发布时间】:2020-02-0506:39:23【问题描述】:我创建了一个Nuxt.js项目,它使用BootstrapVue作... 查看详情

我想为 vue.js (nuxt.js) 中的每个组件加载和填充数据

】我想为vue.js(nuxt.js)中的每个组件加载和填充数据【英文标题】:Iwanttoloadandpopulatethedataforeachcomponentinvue.js(nuxt.js)【发布时间】:2017-11-2807:56:44【问题描述】:我按如下方式启动项目。vueinitnuxt/express我的目录是...components|-slider.vu... 查看详情

如何在nuxt.js中编写vue bootstrap的$bvModal.msgBoxConfirm的测试用例

】如何在nuxt.js中编写vuebootstrap的$bvModal.msgBoxConfirm的测试用例【英文标题】:Howtowritetestcaseof$bvModal.msgBoxConfirmofvuebootstrapinnuxt.js【发布时间】:2020-11-2802:59:22【问题描述】:如何为此组件编写测试用例,如何为此编写单元用例,... 查看详情

Nuxt.js:理解 <nuxt-child> 组件

】Nuxt.js:理解<nuxt-child>组件【英文标题】:Nuxt.js:understanding<nuxt-child>component【发布时间】:2019-03-0923:53:44【问题描述】:在Nuxt.js中,我做了这个文件夹结构:├──parent│  ├──child1.vue│  └──child2.vue├──par... 查看详情

rtp诞生记

...者之一RonFrederick将为我们讲述这个如此重要的协议是如何诞生的。01—前因1992年10月,我开始试验SunVideoPix的图像采集卡,因为我打算基于IP组播写一个网络视频会议工具。该工具以vat(由L 查看详情

如何管理来自 API 的大量路由及其与 Nuxt 路由器模块的组件关联

】如何管理来自API的大量路由及其与Nuxt路由器模块的组件关联【英文标题】:HowtomanagebunchofroutesfromAPIandtheircomponentassociationwithNuxtroutermodule【发布时间】:2020-10-0608:13:28【问题描述】:您好,亲爱的Nuxt/Vue/Node社区,我在我的Nuxt.j... 查看详情

如何在 nuxt.js 中获取 API 和映射数据表的数据

】如何在nuxt.js中获取API和映射数据表的数据【英文标题】:HowtogetAPIandmappingthedatafordata-tableinnuxt.js【发布时间】:2020-11-0718:53:48【问题描述】:我真的需要别人的帮助。我尝试了很多次关于这个问题,但每次尝试都失败了......在... 查看详情