基于Vue.js 与 WordPress Rest API 构建单页应用
前言
Vue.js 是用于构建交互式的 Web 界面的库。它提供了 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API。
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,我们将使用它来请求api。
WordPress REST API为WordPress数据类型提供API端点,允许开发人员通过发送和接收JSON(JavaScript Object Notation)对象与站点进行远程交互 。
demo需要实现功能
- 获取全部的文章列表
- 点击
查看详情
进入文章详情页展示文章内容 - 实现文章列表的分页功能
- 获取所有的文章分类
- 点击分类获取不同分类下的文章列表
环境搭建
vue-cli单页应用的脚手架构建:
https://cn.vuejs.org/v2/guide/installation.html
Axios引入
https://www.kancloud.cn/yunye/axios/234845
element-ui引入
http://element-cn.eleme.io/2.0/#/zh-CN/component/installation
测试 API 的工具
WordPress REST API手册
https://developer.wordpress.org/rest-api/
新建两个.vue文件分别显示文章列表和文章详情
文章列表:articleList.vue
文章详情:article.vue
并在src/router.js
中设置页面路由如下:
import Vue from 'vue'
import Router from 'vue-router'
import ArticleList from '@/components/articleList'
import Article from '@/components/article'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'ArticleList',
component: ArticleList
},
{
path: '/article/:id',
name: 'Article',
component: Article
},
]
})
articleList.vue结构:
<template>
<el-row>
<el-col>
<el-col class="article">
<ul>
<li>
<h1>文章标题</h1>
<div>文章描述</div>
<span>查看详情</span>
</li>
</ul>
</el-col>
</el-col>
</el-row>
</template>
<script>
export default {
data () {
return {
}
},
}
</script>
<style lang="less">
</style>
article.vue结构:
<template>
<el-row>
<el-col class="article">
<h1>标题</h1>
<p class="p"><span>作者:</span><span>发布时间:</span></p>
<div></div>
</el-col>
</el-row>
</template>
<script>
export default {
data () {
return {
}
},
}
</script>
<style lang="less">
</style>
文章列表api获取:
在src
目录下新建api/api.js文件,注意替换域名
import axios from 'axios';
let base = 'http://example.com/wp-json/wp/v2';
//获取文章列表
export const getArticleList = params => {
return axios.get(`${base}/posts`, params).then();
};
在articleList.vue中引入api.js:
import {getArticleList,getCategories} from '../api/api';
定义请求事件,并在页面加载时执行事件,最后定义一个数组来存放请求回来的数据
data () {
return {
articleData: [{
title: {
rendered: ''
},
excerpt: {
rendered: ''
}
}],
}
},
mounted: function () {
this.getarticlelist()
this.getcategories()
},
methods: {
getarticlelist(){
getArticleList().then(res => {
this.articleData = res.data
})
},
}
使用v-for
将数据渲染到页面
<ul>
<li v-for="(item,index) in articleData">
<h1 v-html="item.title.rendered"></h1>
<div v-html="item.excerpt.rendered"></div>
<span>查看详情</span>
</li>
</ul>
到这里一个简单的显示文章列表功能就完成了
文章详情页
为文章列表中的查看详情
绑定事件:
当点击时获取当前点击文章id,根据不同id跳转到响应的详情页
<span @click="article(index)">查看详情</span>
article(index){
let ids = this.articleData[index].id
this.$router.push({
path: '../article/' + ids
})
},
现在已经实现了点击跳转到article详情页,接下来要做的是在详情页中显示当前id下文章的内容,我们需要在当前详情页载入的时候执行事件获取文章内容
在api.js
中定义获取文章详情的api
//获取单篇文章
export const getArticle = ids => {
return axios.get(`${base}/posts/${ids}`).then(res => res.data);
};
article.vue中引入并定义事件:
import {getArticle} from '../api/api';
getarticle(){
//获取id
let ids = this.$route.params.id
//使用获取到的id去请求api
getArticle(ids).then(res => {
this.articleData = res
})
},
绑定事件并渲染出文章结构
<el-col class="article">
<h1 v-html="articleData.title.rendered"></h1>
<p class="p"><span>作者:{{articleData.author}}</span><span>发布时间:{{articleData.date}}</span></p>
<div v-html="articleData.content.rendered"></div>
</el-col>
文章列表分页的实现
element-ui分页组件:
<el-pagination
layout="prev, pager, next" :page-size="per_page"
:total="total" @current-change="handleCurrentChange">
</el-pagination>
上面的组件中定义了handleCurrentChange
事件,用于在点击不同的页数时去为请求的api带上不同的参数
请求所需参数
page:指定要返回的结果页面。
例如,/wp/v2/posts?page=2是帖子结果的第二页
per_page:指定要在一个请求中返回的记录数,指定为从1到100的整数。
例如,/wp/v2/posts?per_page=1只会返回集合中的第一个帖子,为了确定有多少页的数据可用,API返回两个标题字段,每个分页响应
api返回头部带的参数:
X-WP-Total:集合中的记录总数
X-WP-TotalPages:包含所有可用记录的总页数
前面定义了请求文章列表api的方法,只需要将它修改下调用即可,需要给api传递两个参数page和per_page,page的值需要从分页组件中拿到,per_page看需要设定就可以
api请求成功后可以在头部找到X-WP-Total字段,就是我们需要的文章列表总数,因为字段X-WP-Total
的格式不能直接取到值,需要先将它转为数组然后取value
修改后api请求的方法:
let params = {
page: this.page,
per_page: this.per_page,
}
getArticleList({params}).then(res => {
let headerData = Object.values(res.headers)
this.articleData = res.data
this.total = parseInt(headerData[2])
})
在分页事件中调用
handleCurrentChange(val) {
this.loading = true
this.page = val
this.getarticlelist()
},
获取所有的文章分类
获取所有分类比较简单,获取数据使用v-for
渲染就可以了
api.js
//获取文章分类
export const getCategories= params => {
return axios.get(`${base}/categories`, params).then(res => res.data);
};
html
<ul>
<li v-for="item in categoriesData">{{item.name}}
</li>
</ul>
js
mounted: function () {
getcategories(){
getCategories().then(res => {
this.categoriesData = res
})
}
}
点击分类获取不同分类下的文章列表
添加点击事件
为每一个分类添加点击事件,并为选中的分类添加样式
<ul>
<li v-for="(item,index) in categoriesData" @click="categorie(index)"
:class="{ 'active': active == index }">{{item.name}}
</li>
</ul>
改造文章列表请求api
为文章列表请求api添加categories
字段,这个字段为所需分类的id
let params = {
page: this.page,
per_page: this.per_page,
categories: this.categories
}
编写事件
点击事件时需要做以下几件事情:
+ 获取当前点击分类id
+ 为当前分类添加选中样式
+ 让请求中的page字段为1
+ 获取请求结果重新渲染文章列表
categorie(index){
this.categories = this.categoriesData[index].id
this.page = 1
this.active = index
this.getarticlelist()
}
服务器部署
根目录下执行npm run dev
生成dist静态文件夹,将dist文件夹中内容部署到http服务器上即可通过域名访问
demo地址
https://github.com/qianxiaoduan/Vue-WordPress-Rest-API
http://vue-blog.cosdk.com/