本文个人博客地址: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等;
推荐几个模板站: