今天的越写悦快乐系列文章为大家带来Vue项目如何使用JSON Server快速生成Mock数据,做过前端开发的小伙伴都知道,Vue在前端圈的流行程度,它可以快速构建响应式的Web页面,配置数据驱动的方式来操作虚拟DOM,构建易用、灵活、高效的Web页面。今天的文章我为大家介绍一下如何使用JSON Server快速构建Mock数据,利用Express路由转发客户端请求,然后返回响应数据给Vue组件,Vue组件通过比对虚拟DOM并计算变更来更新页面,最后把更新结果渲染在页面上。
开发环境
- Window 10.0.17763
- Node 10.15.3
- Yarn 1.16.0
- Vue CLI 3.7.0
- Git 2.21.0
基本原理
基本原理 - 图片来自简书App- 启动开发服务器
- 通过Mock服务器代理页面发送的请求
- Mock服务器根据路由解析请求并返回数据
- 数据返回后交由Vue组件(Single File Components)来处理并渲染
- 渲染完成后显示在页面
Vue Page是一个SFC,也可以包含多个Component。
挂载App的含义是将创建Vue对象与某个DOM节点(也就是HTML中的标签)进行绑定。
安装
- npm方式
npm install -g json-server
- yarn方式
yarn global add json-server
- pnpm方式
pnpm install -g json-server
配置代理
我们在vue.config.js
文件中添加devServer
module.exports = {
lintOnSave: false,
devServer: {
proxy: 'http://localhost:3000/'
},
css: {
sourceMap: true
}
};
生成Mock数据
我们在项目目录下创建__mock__
目录并创建faker.js
文件,其文件内容如下。
module.exports = function () {
var faker = require("faker");
faker.locale = "zh_CN";
var _ = require("lodash");
return {
people: _.times(100, function (n) {
return {
id: n,
name: faker.name.findName(),
avatar: faker.internet.avatar()
}
}),
address: _.times(100, function (n) {
return {
id: faker.random.uuid(),
city: faker.address.city(),
county: faker.address.county()
}
})
}
}
我们可以通过
json-server __mock__/faker.js
启动服务,此时默认监听的端口是3000,接下来在浏览器地址栏输入http://localhost:3000/address
查看返回的数据
配置运行脚本
要通过yarn
运行脚本,需要在package.json
文件中的scripts
中添加
{
"name": "vant-tour",
"version": "1.0.0",
"private": true,
"description": "An Vant Tour",
"license": "MIT",
"author": "Watony Weng <softweitao@126.com>",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
+ "mock": "json-server --watch __mock__/faker.js"
},
"dependencies": {
"axios": "^0.18.0",
"vant": "^1.6.14",
"vue": "^2.6.10",
"vue-router": "^3.0.5"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.4.0",
"@vue/cli-plugin-eslint": "^3.4.0",
"@vue/cli-service": "^3.4.0",
"babel-plugin-import": "^1.8.0",
"faker": "^4.1.0",
"less": "^3.8.1",
"less-loader": "^4.1.0",
"postcss-pxtorem": "^4.0.1",
"vue-cli-plugin-axios": "0.0.4",
"vue-template-compiler": "^2.6.10"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"browserslist": [
"Android >= 4.0",
"iOS >= 7"
]
}
验证
有这样一个场景,需要一个地址列表并且可以模糊搜索,那么我们可以这样操作,先给出示例例页面的截图。
页面截图 - 图片来自简书App创建单文件组件(SFC)
创建src/views/home/index.vue
文件,下面给出这个文件的示例。
<template>
<div>
<van-nav-bar :title="pageTitle"/>
<van-search
v-model="value"
placeholder="请输入搜索关键词"
show-action
@search="onSearch">
<div
slot="action"
@click="onSearch">搜索</div>
</van-search>
<van-list
v-model="loading"
:finished="finished"
finished-text="我是有底线的"
@load="onLoad">
<van-cell
v-for="(item, index) in list"
:key="item"
:title="item"
@click.native="onClickItem(index)"
/>
</van-list>
</div>
</template>
<script>
import { Cell, List, NavBar, Toast, Search } from 'vant'
export default {
name: 'Home',
components: {
[Cell.name]: Cell,
[List.name]: List,
[NavBar.name]: NavBar,
[Toast.name]: Toast,
[Search.name]: Search
},
data() {
return {
pageTitle: '地址列表',
value: '',
url: '',
loading: false,
finished: false,
list: [],
items: null
}
},
watch: {
value(newVal, oldVal) {
if (newVal.length == 0) {
this.items = null
this.list = []
this.onLoad()
}
}
},
methods: {
onLoad() {
this.loading = false
this.url = 'address'
this.axios
.get(
this.url,
{},
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}
)
.then(result => {
const data = result.data
if (data.length <= 0) {
Toast.fail('暂无数据')
} else {
this.items = data
for (var i = 0; i < data.length; i++) {
this.list.push(data[i].city)
}
this.finished = true
}
})
},
onClickItem(index) {
console.log('onClickItem ' + JSON.stringify(this.items[index]))
},
onSearch() {
if (this.value.length == 0) {
Toast.fail('关键词去哪了')
return
}
this.url = 'address?q=' + this.value
this.axios
.get(
this.url,
{},
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}
)
.then(result => {
const data = result.data
this.items = null
this.list = []
if (data.length <= 0) {
Toast.fail('暂无数据')
} else {
this.items = data
for (var i = 0; i < data.length; i++) {
this.list.push(data[i].city)
}
this.finished = true
}
})
}
}
}
</script>
<style lang="less">
</style>
配置路由
我们在路由文件src/router.js
中添加Home
组件的声明。
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const routes = [
{
path: '*',
redirect: '/home'
},
{
name: 'home',
component: () => import('./views/home'),
meta: {
title: '手机端'
}
}
]
routes.forEach(route => {
route.path = route.path || '/' + (route.name || '')
})
const router = new Router({ routes })
router.beforeEach((to, from, next) => {
const title = to.meta && to.meta.title
if (title) {
document.title = title
}
next()
})
export { router }
配置插件
我们使用Axios
来发送请求,此时我们需添加插件vue-cli-plugin-axios
,通过这个插件会自动添加axios
依赖并且在src/plugins
下生成axios.js
文件,其文件内容如下。
'use strict'
import Vue from 'vue'
import axios from 'axios'
axios.defaults.headers.get['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
axios.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded; charset=UTF-8'
let config = {
timeout: 60 * 1000,
responseType: 'json'
}
axios.defaults.transformRequest = [
function(data) {
let ret = ''
for (let it in data) {
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
}
return ret
}
]
const _axios = axios.create(config)
_axios.interceptors.request.use(
function(config) {
return config
},
function(error) {
return Promise.reject(error)
}
)
_axios.interceptors.response.use(
function(response) {
return response
},
function(error) {
return Promise.reject(error)
}
)
Plugin.install = function(Vue, options) {
Vue.axios = _axios
window.axios = _axios
Object.defineProperties(Vue.prototype, {
axios: {
get() {
return _axios
}
},
$axios: {
get() {
return _axios
}
}
})
}
Vue.use(Plugin)
export default Plugin
启动
- 启动代理服务
yarn mock
- 启动应用
yarn serve
- 打开浏览器输入
http://localhost:8080/
即可看到列表页面
参考
示例
个人总结
总结一下今天分享的内容,我们从Vue CLI出发,使用有赞的Vant搭建了一个手机端的页面,该页面使用List组件进行渲染,数据来源自JSON Server
生成的模拟数据,随后我们添加了搜索组件并监听输入框的值将搜索结果实时显示在列表项中,那么对于项目中使用的工具、库和框架,我们需要有一个更加感性的认识,Vue
框架是如何渲染页面的,页面的数据从何而来,如何发起请求,组件中如何调用axios
这些知识点在实践的过程中会有一个不一样的认识,当然也需要我们了解前端发展的新趋势,在移动互联网的后时代如何把握和利用小程序的红利构建不一样的产品形态,创建不一样的用户价值,构建属于我们的新时代,我相信这仅仅是开始,我们一直在路上,期待遇见更好的自己,期待和大家一起成长,也希望大家保持学习的热情,继续努力,成就非凡梦想。若是我的文章对你有所启发,那将是我莫大的荣幸。
网友评论