本地后台
注意: 若没有 node_modules
文件夹 则 cnpm i
完善配置
src 目录结构
app.js
'use strict'
var path = require('path')
const express = require('express')
const bodyParser = require('body-parser')
const fs = require('fs')
let app = express()
// 注册 body-parser 中间件
app.use(bodyParser({ extended: false }))
// app.use(bodyParser.urlencoded({ extended: false }));
//1.0 初始化orm
const orm = require('orm')
app.use(
orm.express('mysql://root:root@127.0.0.1:3306/dtcmsdb4', {
define: function(db, models, next) {
next()
}
})
)
//2.0 将所有api的请求响应content-type设置为application/json
app.all('/api/*', (req, res, next) => {
//设置允许跨域响应报文头
//设置跨域
//res.header("Access-Control-Allow-Origin", "*");
//res.header("Access-Control-Allow-Headers", "X-Requested-With"); // X-Requested-With
//res.header("Access-Control-Allow-Methods", "*");
res.header('Access-Control-Allow-Origin', '*')
// 设置服务器支持的所有头信息字段
res.header(
'Access-Control-Allow-Headers',
'Content-Type,Content-Length, Authorization, Accept,X-Requested-With'
)
// 设置服务器支持的所有跨域请求的方法
res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
res.setHeader('Content-Type', 'application/json;charset=utf-8')
next()
})
//2.0 设置路由规则
const apiRoute = require('./routes/apiRoute.js')
app.use('/', apiRoute)
app.use(express.static(path.join(__dirname, 'public')))
app.listen(8082, () => {
console.log('vue-cms的api服务已启动, :8082');
});
开启后台
运行命令 node ./src/app.js
输入接口url
启动成功
请求接口封装
原因:因为线上或开发过程中,网址域名可能变化,若不采取方案则会引起一个域名改变修改多处代码
实施办法
利用 异步 promise
封装
小程序端
在根目录下新建 request
文件夹
index.js
index.js
代码
let ajaxtimes=0;
export const request=(params)=>{
let header={...params.header};
if (params.url.includes("/my/")) {
header["Authorization"]=wx.getStorageSync('token')
}
ajaxtimes++;
wx.showLoading({
title: '加载中',
mask: true
})
const baseUrl="https://api-hmugo-web.itheima.net/api/public/v1"
return new Promise((resolve,reject)=>{
wx.request({
...params,
header:header,
url:baseUrl+params.url,
success:(result)=>{
resolve(result);
},
fail:(err)=>{
reject(err);
} ,
complete:()=>{
ajaxtimes--;
if(ajaxtimes==0){
wx.hideLoading();
}
}
});
})
}
使用页面
使用页面代码
import { request } from "../../request/index";
wx-Page({
data: {
swiperlist:[ ],
cateslist:[ ],
floorlist:[],
},
/**
* 生命周期函数--监听页面加载
* 页面加载 就会触发
*/
onLoad: function (options) {
// wx.request({
// url: 'https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata',
// success: (result) => {
// console.log(result);
// this.setData({
// swiperlist:result.data.message
// })
// },
// })
this.getswiperlist();
this.getcatelist();
this.getfloorlist();
},
getswiperlist(){
request({ url: '/home/swiperdata'})
.then(result => {
this.setData({
swiperlist:result.data.message
})
})
},
getcatelist(){
request({ url: '/home/catitems'})
.then(result => {
this.setData({
cateslist:result.data.message
})
})
},
getfloorlist(){
request({ url: '/home/floordata'})
.then(result => {
var data =JSON.stringify(result.data.message);
var data1=data.replace(/goods_list/g, 'goods_list/index')
var data2=JSON.parse(data1)
this.setData({
floorlist:data2,
})
})
},
});
Vue 浏览器端(H5)
同理使用 Promise
封装
在根目录下新建 util
文件夹 ,在此文件夹下 编写 api.js
api.js
api.js 代码
const BASE_URL = 'http://localhost:8082'
export const myRequest = (options)=>{
return new Promise((resolve,reject)=>{
uni.request({
url:BASE_URL+options.url,
method: options.method || 'GET',
data: options.data || {},
success: (res)=>{
if(res.data.status !== 0) {
return uni.showToast({
title: '获取数据失败'
})
}
resolve(res)
},
fail: (err)=>{
uni.showToast({
title: '请求接口失败'
})
reject(err)
}
})
})
}
使用页面
methods: {
// 获取轮播图的数据
async getSwipers () {
const res = await this.$myRuquest({
url: '/api/getlunbo'
})
this.swipers = res.data.message
},
全部代码
<template>
<view class="home">
<swiper indicator-dots circular>
<swiper-item v-for="item in swipers" :key="item.id">
<image :src="item.img"></image>
</swiper-item>
</swiper>
<!-- 导航区域 -->
<view class="nav">
<view class="nav_item" v-for="(item,index) in navs" :key="index" @click="navItemClick(item.path)">
<view :class="item.icon"></view>
<text>{{item.title}}</text>
</view>
</view>
<!-- 推荐商品 -->
<view class="hot_goods">
<view class="tit">推荐商品</view>
<goods-list @goodsItemClick="goGoodsDetail" :goods="goods"></goods-list>
</view>
</view>
</template>
<script>
import goodsList from '../../components/goods-list/goods-list.vue'
export default {
data() {
return {
swipers: [],
goods: [],
navs: [
{
icon: 'iconfont icon-ziyuan',
title: 'Shop_超市',
path: '/pages/goods/goods'
},
{
icon: 'iconfont icon-guanyuwomen',
title: '联系我们',
path: '/pages/contact/contact'
},
{
icon: 'iconfont icon-tupian',
title: '社区图片',
path: '/pages/pics/pics'
},
{
icon: 'iconfont icon-shipin',
title: '学习视频',
path: '/pages/videos/videos'
}
]
}
},
onLoad() {
this.getSwipers()
this.getHotGoods()
},
components: {"goods-list":goodsList},
methods: {
// 获取轮播图的数据
async getSwipers () {
const res = await this.$myRuquest({
url: '/api/getlunbo'
})
this.swipers = res.data.message
},
// 获取热门商品列表数据
async getHotGoods () {
const res = await this.$myRuquest({
url: '/api/getgoods?pageindex=1'
})
this.goods = res.data.message
},
// 导航点击的处理函数
navItemClick (url) {
uni.navigateTo({
url
})
},
// 导航到商品详情页
goGoodsDetail (id) {
uni.navigateTo({
url: '/pages/goods-detail/goods-detail?id='+id
})
}
}
}
</script>
<style lang="scss">
.home{
swiper{
750rpx;
height: 380rpx;
image{
height: 100%;
100%;
}
}
.nav {
display: flex;
.nav_item {
25%;
text-align: center;
view{
120rpx;
height: 120rpx;
background: $shop-color;
border-radius: 60rpx;
margin: 10px auto;
line-height: 120rpx;
color: #fff;
font-size: 50rpx;
}
.icon-tupian{
font-size: 45rpx;
}
text{
font-size: 30rpx;
}
}
}
.hot_goods {
background: #eee;
overflow: hidden;
margin-top: 10px;
.tit{
height: 50px;
line-height: 50px;
color: $shop-color;
text-align: center;
letter-spacing: 20px;
background: #fff;
margin: 7rpx 0;
}
}
}
</style>