本章我们结合前面所学到的知识点, 可以来写一个搜索查询的小案例, 功能如需下:
电影列表搜索
- 具体的代码如下
前端代码
<template>
<div class="MovieList">
<div class="search">
<el-input v-model="searchText" placeholder="请输入内容"></el-input>
<el-button icon="el-icon-search" circle @click="searchList"></el-button>
</div>
<div class="content">
<div class="item" v-for="item of list" :key="item.id">
<div class="img">
<img :src="changeUrl(item.img)" alt="">
</div>
<div class="detail">
<div class="title">{{ item.nm }}</div>
<div class="resource-name">{{ item.enm }}</div>
<div class="movie-type">{{ item.cat }}</div>
<div class="time">{{ item.pubDesc }}</div>
</div>
<div class="score">
<p>{{ item.sc }}</p>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'MovieList',
data() {
return {
searchText: '',
list: [],
}
},
components: {},
methods: {
async searchList() {
const { data: { list } } = await this.$http.get('/movie/subject_search', {
params: {
kw: this.searchText,
},
})
this.list = list
},
changeUrl(url) {
return url.replace(/w.h/, '128.180')
},
},
}
</script>
<style scoped lang="less">
.MovieList {
.search {
display: flex;
width: 350px;
.el-input {
margin-right: 10px;
}
}
.content {
width: 375px;
.item {
display: flex;
justify-content: space-between;
font-size: 12px;
color: rgb(153, 153, 153);
margin-bottom: 10px;
.img {
width: 64px;
img {
width: 100%;
}
}
.detail {
flex: 1;
padding-left: 10px;
color: #222;
.title {
font-size: 16px;
font-weight: bold;
}
}
.score {
width: 48px;
color: #fa0;
}
}
}
}
</style>
后端代码
const Koa = require('koa')
const Router = require('koa-router')
const router = new Router()
const bodyparser = require('koa-bodyparser')
const axios = require('axios')
const app = new Koa()
app.use(bodyparser())
router.get('/movie/subject_search', async (ctx, next) => {
const { request, response } = ctx
const { query: { kw } } = request
const { data: { movies } } = await axios.get('http://m.maoyan.com/ajax/search', {
params: {
kw,
cityId: 10,
},
})
response.body = movies
})
app.use(router.routes())
app.use(router.allowedMethods())
app.listen(3000, () => {
console.log(`http://localhost:3000`)
})
登录验证
前面我们学习了jwt的登录验证, 在这一章, 我们将这个知识, 运用到里面
前端代码
<template>
<div class="Login">
<div class="content">
<div class="username">
<el-input placeholder="请输入用户名"
v-model="username">
<template slot="prepend">
<i class="el-icon-user"></i>
</template>
</el-input>
</div>
<div class="password">
<el-input placeholder="请输入密码"
show-password
v-model="password">
<template slot="prepend">
<i class="el-icon-lock"></i>
</template>
</el-input>
</div>
<div class="button">
<el-button type="primary" @click="login">L O G I N</el-button>
</div>
<div class="about">
<el-tooltip class="item" effect="dark" content="微信扫码登录" placement="top">
<i class="el-icon-chat-line-round"></i>
</el-tooltip>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Login',
components: {},
data() {
return {
username: '',
password: '',
}
},
methods: {
async login() {
const { msgCode, message, data } = await this.$http.post('/login', {
username: this.username,
password: this.password,
})
if (msgCode === 200) {
// 将token放入本地存储里面
this.$storage.set('userInfo', data)
this.$message({
message,
type: 'success',
})
// 跳转到电影列表页面
this.$router.push('/movie-list')
} else {
this.$message({
message,
type: 'error',
})
}
},
},
}
</script>
<style scoped lang="less">
.Login {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background: url("../assets/img/login_bg.jpg") no-repeat center center;
.content {
width: 300px;
.username, .password {
margin-bottom: 10px;
i {
font-size: 18px;
}
}
.button {
margin-bottom: 10px;
.el-button {
width: 100%;
}
}
.about {
display: flex;
justify-content: flex-end;
align-items: center;
i {
cursor: pointer;
}
}
}
}
</style>
后端代码
router.post('/login', async (ctx, next) => {
const { request, response } = ctx
const { body } = request
try {
const { username, password } = body
if (username && password) {
// 生成token
const token = sign({ username, password }, PRIVATE_KEY, { expiresIn: 60 * 60 })
response.body = {
msgCode: 200,
message: '登录成功',
data: {
token,
username,
},
}
} else {
response.body = {
msgCode: 400,
message: '请填写用户名和密码',
}
}
} catch (e) {
response.body = e
}
})
// 生成token之后, 我们在需要验证的接口上面对token进行验证, 如果token验证失败, 那么我们就返回失败信息到前端
const verifyUser = async (ctx, next) => {
const { request, response } = ctx
const { header: { token } } = request
const isVerify = verify(token, PRIVATE_KEY)
try {
const { username, password } = isVerify
await next()
} catch (e) {
response.body = {
msgCode: 404,
message: 'token验证失败',
errorMessage: e,
}
}
}
// 添加对电影列表查询接口的登录验证, 如果验证失败, 则直接返回404
router.get('/movie/subject_search', verifyUser, async (ctx, next) => {
const { request, response } = ctx
const { query: { kw } } = request
const { data: { movies } } = await axios.get('http://m.maoyan.com/ajax/search', {
params: {
kw,
cityId: 10,
},
})
response.body = movies
})
到这一步, 我们就已经完成了一个简单的校验过程, 但是这里所有的文件, 都是在一个文件里面, 在下一章, 我们将对文件进行拆分