文章目录
效果展示:
- 由于用户名是
<h2/>
标签,所以会比较大,撑大了父元素让整个布局显得有点乱 - 不过写完才发现,就懒得优化了
一、创建并配置好vue脚手架
1,创建Vue脚手架,选择Vue2的默认版本
2,vscode打开我们创建的脚手架
准备工作:
- 删除
components
文件夹中的文件 - 删除App.vue中的内容并且重新配置模板
- 关闭eslint语法检查(不关闭会报错)
- 在
vue.config.js
文件中新增配置项lintOnSave:false
二、创建组件并完成静态页面
组件结构很简单,
Header
组件用来搜索,
Main
组件用来展示
接着开始写静态页面
Header组件
<template lang=""><div><div class="search"><input type="text"><button>点我搜索</button></div></div></template><script>exportdefault{}</script><style scoped>.search{
display: flex;
justify-content: center;}</style>
Main组件
<template lang=""><div><div class="show_container"><div class="card"><a href=""><img src="../assets/download.jpg" alt=""></a><h2>UserName</h2></div></div></div></template><script>exportdefault{}</script><style scoped>.show_container{
margin-top:50px;
width:90vw;
display: flex;
justify-content: space-between;
flex-wrap: wrap;}
img{
width:100px;
height:100px;
object-fit: cover;}
h2{
text-align: center;}</style>
App组件
- 引入、注册并使用Header和Main两个组件
<template lang=""><div class="main_container"><Header></Header><Main></Main></div></template><script>import Header from'./components/Header.vue'import Main from'./components/Main.vue'exportdefault{
components:{
Header,
Main
}}</script><style scoped>.main_container {
display: flex;
flex-direction: column;
align-items: center;}*{
margin:0;
padding:0;}</style>
- 输入
yarn serve
执行项目静态页面效果如下
三、使用axios发送ajax请求
首先要弄懂啥是静态页面,啥是动态页面,千万别以为页面上有个动图就是动态页面了;通俗点来讲,静态页面没有交互效果,上面的都是死数据;而动态页面用户可以很好的进行交互,可以根据自己的想法得到想要的数据。
先别急着来请求数据,我们向github请求数据总得带关键词吧,而关键词也就是我们Header组件中用户输入的内容,那么开干吧!
- 首先给
<input/>
输入框进行双向数据绑定:v-model=‘keyWord’
- 接着给
<input/>
绑定回车事件,给button绑定点击事件,并指向同一函数searchUsers
以下为Header组件
<template lang=""><div><div class="search"><input type="text" v-model="keyWord" @keyup.enter="searchUsers"><button @click="searchUsers">点我搜索</button></div></div></template><script>exportdefault{data(){return{
keyWord:''}},
methods:{searchUsers(){}},}</script><style scoped>.search {
display: flex;
justify-content: center;}</style>
- 接下来就是要根据获取到的
keyWord
发送ajax
请求了,那么在哪个组件中发呢?必然是Main组件,因为请求回来的数据将在Main组件中渲染。 - 这时候我们将要想办法将Header中的数据
keyWord
传给其兄弟组件Main。有N中办法,我选择的是全局事件总线(我会单独写一篇关于它的)
- 首先在
main.js
中定义全局事件总线
import Vue from'vue'import App from'./App.vue'
Vue.config.productionTip =falsenewVue({render:h=>h(App),beforeCreate(){//将vm挂载在到Vue的显式原型上Vue.prototype.$bus =this}}).$mount('#app')
- 在Main组件中自定义事件并指定回调
mounted(){//定义事件,指定回调函数searchAjaxthis.$bus.$on('key',this.searchAjax)},
methods:{//q是Header组件传过来的keyWordsearchAjax(q){}}
- 在Header组件中触发自定义事件并传送自己的参数
methods:{searchUsers(){//将数据传给Main组件this.$bus.$emit('key',this.keyWord)}},
- 这时候在Main组件中已经可以拿到Header组件中的keyWord了
开始玩
axios
,我们的api是
https://api.github.com/search/users
(querry参数)
- 安装
axios
;命令:yarn add axios -S
- 在Main组件中引入
axios
;命令:import axios from 'axios'
- 根据拿到的
keyWord
作为querry参数发送请求
searchAjax(q){axios({
url:'https://api.github.com/search/users',
method:'get',
params:{// q:q可简写为下
q
}}).then(response=>{
console.log(response);}).catch(error=>{
console.log(error.message);})}
- 测试并观察返回的数据结构:随便输入关键词回车,观察控制台中返回的数据结构,发现data下的
items
数组是我们所需要的
- 我们先准备一个容器数组
users
用来存放筛选后的items
数组
data(){return{
users:[]}},
- 接着用
map()
方法加工items
数组并将加工结果传给users
.then(response=>{this.users = response.data.items.map(item=>({
id: item.id,
userName: item.login,
avatar: item.avatar_url,
page: item.html_url,}))})
- 最后一步,渲染数据,在Main组件中
<templatelang=""><div><divclass="show_container"><divclass="card"v-for="(user, index) in users":key="user.id"><a:href="user.page"><img:src="user.avatar"alt=""></a><h2>{{user.userName}}</h2></div></div></div></template>
完成!你学废了吗?
效果如下
你以为这就完了吗?NONONO,优化在后面。。。
四、优化实现人性化效果
1、优化一:首先用户这个东西是很可怕的哇,要考虑用户什么也不输入就回车的情况
优化后的Header组件如下
<template lang=""><div><div class="search"><input type="text" v-model="keyWord" @keyup.enter="searchUsers"><button @click="searchUsers">点我搜索</button></div></div></template><script>exportdefault{data(){return{
keyWord:''}},
methods:{searchUsers(){//在这儿判断以下用户是否啥也没输就开始搜索了if(this.keyWord.trim()){//将数据传给Main组件this.$bus.$emit('key',this.keyWord)}else{//如果啥也没输弹出警告alert('别给老子输空串儿!')}}},}</script><style scoped>.search {
display: flex;
justify-content: center;}</style>
优化后效果如下
2、优化二:在Main组件中,当没有数据的时候页面一片空白,非常的不美观;
- 当开始搜索时,数据返回有一段时间,得让用户知道已经开始搜了,只是还没传过来(别骂了,是你网速的问题)
- 如果搜索失败,给个报错页面,提示下报错信息就完了(甩锅王)
开干!
优化后的Main组件如下
<template lang=""><div><div class="show_container"><!-- 用条件语句决定显示哪一个标签 --><h2 v-if="isFirst">尊贵的天龙人,请输入用户名查找</h2><h2 v-else-if="isBegin">查找中,别急,快了</h2><div v-else-if="isError"><h2>不好意思,出了点问题</h2><h2>{{error}}</h2></div><div v-elseclass="card" v-for="(user, index) in users":key="user.id"><a :href="user.page"><img :src="user.avatar" alt=""></a><h2>{{user.userName}}</h2></div></div></div></template><script>import axios from'axios'exportdefault{data(){return{
users:[],
error:'',// 三个数据驱动四种状态,分别是一开始,搜索中,出错,正常显示
isFirst:true,
isBegin:false,
isError:false}},mounted(){//定义事件,指定回调函数searchAjaxthis.$bus.$on('key',this.searchAjax)},
methods:{searchAjax(q){// 开始搜索,将第一次置为false,将开始搜索置为truethis.isFirst =falsethis.isBegin =trueaxios({
url:'https://api.github.com/search/users',
method:'get',
params:{// q:q可简写为下
q
}}).then(response=>{// 数据回来了,将开始搜索置为false便于下一步显示数据this.isBegin =falsethis.users = response.data.items.map(item=>({
id: item.id,
userName: item.login,
avatar: item.avatar_url,
page: item.html_url,}))}).catch(error=>{// 出错,首先将isBegin置为false// 然后将isError置为true,显示错误信息this.isBegin =falsethis.isError =truethis.error = error.message
})}}}</script><style scoped>.show_container {
margin-top:50px;
width:90vw;
display: flex;
justify-content: space-between;
flex-wrap: wrap;}
img {
width:100px;
height:100px;
object-fit: cover;}
h2 {
text-align: center;}</style>
优化后效果如下
- 以下是请求成功的情况
- 以下是请求失败的情况
总结
- 小孩子才写总结
- 昨天刚成年
版权归原作者 web舔狗 所有, 如有侵权,请联系我们删除。