嗨!~ 大家好,我是YK菌 🐷 ,一个微系前端 ✨,爱思考,爱总结,爱记录,爱分享 🏹,欢迎关注我呀 😘 ~ [微信号:
yk2012yk2012
,微信公众号:ykyk2012
]
「这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战 (opens new window)」
今天我们来用Vue做第三个小demo,一个Github用户搜索的小案例,之前我们用React也做过,这次用Vue做一次,使用axios来发起网络请求。
# 0. 使用Vue-cli配置代理
# 方法①
在vue.config.js中添加如下配置:
devServer:{
proxy:"http://localhost:5000"
}
说明:
- 优点:配置简单,请求资源时直接发给前端(8080)即可。
- 缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
- 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)
# 方法②
编写vue.config.js配置具体代理规则:
module.exports = {
devServer: {
proxy: {
'/api1': {// 匹配所有以 '/api1'开头的请求路径
target: 'http://localhost:5000',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/api1': ''}
},
'/api2': {// 匹配所有以 '/api2'开头的请求路径
target: 'http://localhost:5001',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/api2': ''}
}
}
}
}
/*
changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
changeOrigin默认值为true
*/
说明:
- 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
- 缺点:配置略微繁琐,请求资源时必须加前缀。
# 1. 准备工作
界面拆分
# 2. 静态页面
# index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>demo_ajax</title>
<link rel="stylesheet" href="./static/users_page/bootstrap.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
# App.vue
<template>
<div class="container">
<search />
<users-main />
</div>
</template>
<script>
import Main from "./components/Main.vue";
import Search from "./components/Search.vue";
export default {
components: { Search, UsersMain: Main }, //不能用main作为标签名,就换一个名字
};
</script>
<style>
</style>
# Search.vue
<template>
<section class="jumbotron">
<h3 class="jumbotron-heading">Search Github Users</h3>
<div>
<input type="text" placeholder="enter the name you search" />
<button>Search</button>
</div>
</section>
</template>
<script>
export default {};
</script>
<style>
</style>
# Main.vue
<template>
<div class="row">
<div class="card">
<a href="https://github.com/reactjs" target="_blank">
<img
src="https://avatars.githubusercontent.com/u/6412038?v=3"
style="width: 100px"
/>
</a>
<p class="card-text">reactjs</p>
</div>
<div class="card">
<a href="https://github.com/reactjs" target="_blank">
<img
src="https://avatars.githubusercontent.com/u/6412038?v=3"
style="width: 100px"
/>
</a>
<p class="card-text">reactjs</p>
</div>
<div class="card">
<a href="https://github.com/reactjs" target="_blank">
<img
src="https://avatars.githubusercontent.com/u/6412038?v=3"
style="width: 100px"
/>
</a>
<p class="card-text">reactjs</p>
</div>
<div class="card">
<a href="https://github.com/reactjs" target="_blank">
<img
src="https://avatars.githubusercontent.com/u/6412038?v=3"
style="width: 100px"
/>
</a>
<p class="card-text">reactjs</p>
</div>
<div class="card">
<a href="https://github.com/reactjs" target="_blank">
<img
src="https://avatars.githubusercontent.com/u/6412038?v=3"
style="width: 100px"
/>
</a>
<p class="card-text">reactjs</p>
</div>
</div>
</template>
<script>
export default {};
</script>
<style>
.card {
float: left;
width: 33.333%;
padding: .75rem;
margin-bottom: 2rem;
border: 1px solid #efefef;
text-align: center;
}
.card > img {
margin-bottom: .75rem;
border-radius: 100px;
}
.card-text {
font-size: 85%;
}
</style>
# 3. 初始化显示
# main.vue
<template>
<div>
<h2 v-if="firstView">请输入用户名搜索</h2>
<h2 v-if="loading">Loading...</h2>
<h2 v-if="errorMsg">{{errorMsg}}</h2>
<div class="row">
<div class="card" v-for="(user, index) in users" :key="index">
<a :href="user.url" target="_blank">
<img
:src="user.avatar_url"
style="width: 100px"
/>
</a>
<p class="card-text">{{user.name}}</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
// 界面有四个状态
firstView: true,
loading: false,
users: null, //[{url:'', avatar_url: '', name: ''}]
errorMsg: ''
};
},
};
</script>
# 4. 交互功能实现
输入关键字点击搜索,界面发生变化
这里我们使用发布订阅的库 pubsub-js
# Search.vue
<template>
<section class="jumbotron">
<h3 class="jumbotron-heading">Search Github Users</h3>
<div>
<input
type="text"
placeholder="enter the name you search"
v-model="searchName"
/>
<button @click="search">Search</button>
</div>
</section>
</template>
<script>
import PubSub from "pubsub-js";
export default {
data() {
return {
searchName: "",
};
},
methods: {
search() {
const searchName = this.searchName.trim();
if (searchName) {
// 发布搜索的消息
PubSub.publish("search", searchName);
}
},
},
};
</script>
<style>
</style>
# Main.vue
<template>
<div>
<h2 v-if="firstView">请输入用户名搜索</h2>
<h2 v-if="loading">Loading...</h2>
<h2 v-if="errorMsg">{{ errorMsg }}</h2>
<div class="row" v-else>
<div class="card" v-for="(user, index) in users" :key="index">
<a :href="user.url" target="_blank">
<img :src="user.avatar_url" style="width: 100px" />
</a>
<p class="card-text">{{ user.name }}</p>
</div>
</div>
</div>
</template>
<script>
import PubSub from "pubsub-js";
import axios from "axios";
export default {
data() {
return {
// 界面有四个状态
firstView: true,
loading: false,
users: null, // [{url:'', avatar_url: '', name: ''}]
errorMsg: "",
};
},
mounted() {
// 订阅搜索的消息
PubSub.subscribe("search", (msg, searchName) => {
// 说明需要发ajax请求搜索
const url = `https://api.github.com/search/users?q=${searchName}`;
//更新状态(请求中)
this.firstView = false;
this.loading = true;
this.users = null;
this.errorMsg = "";
// 发ajax状态
axios
.get(url)
.then((response) => {
const result = response.data;
const users = result.items.map((item) => ({
url: item.html_url,
avatar_url: item.avatar_url,
name: item.login,
}));
// 成功, 更新状态(成功)
this.loading = false;
this.users = users;
})
.catch((error) => {
// 失败, 更新状态(失败)
this.loading = false;
this.errorMsg = "请求失败";
});
});
},
};
</script>
# 5. 效果展示
最后可以看下我们的效果
最后,欢迎关注我的专栏,和YK菌做好朋友