案例知识点
- 兄弟组件儿的通信 使用了Pubsub 订阅与发布
- ajax数据请求 获取前 获取中 获取后 获取为空 获取异常
- 获取成功后显示数据给到 原先定义号的 jsonData users
vue Search案例 消息订阅pubsub与ajax
pubsub消息订阅组件,便于兄弟组件间调用
npm install --save pubsub-js
App.vue
1 <template> 2 <div id="app"> 3 <div class="container"> 4 <Search/> 5 <users-main/> 6 </div> 7 </div> 8 </template> 9 10 <script> 11 import Search from './components/Search.vue' 12 import Main from './components/Main.vue' 13 export default{ 14 components:{ 15 Search, 16 // 内部定义的关键词名称 不可以使用 所以赋值一个名字 17 UsersMain:Main 18 19 } 20 }; 21 </script> 22 23 <style type="stylus"> 24 25 </style>
Main.vue
// 由于请求状态在Main中,ajax写在main中以便同步更新4个状态。 写在search中不便更新状态。
<template> <div> <!-- 搜索我有四种状态 --> <!-- 1.搜索之前 --> <h2 v-if="firstView">输入用户名搜索</h2> <!-- 2.搜索中.... --> <h2 v-if="loading">GitData...</h2> <!-- 4.没有搜索到 --> <h2 v-if="overNull">该关键字没有搜索到Data...</h2> <!-- 3.搜索失败error --> <h2 v-if="errorMsg">{{errorMsg}}</h2> <div v-else class="row" v-for="(user,index) in users" :key="index" :index="index"> <div class="card"> <a :href="user.url" target="_blank"> <img :src="user.avatar_url" style=' 100px'/> </a> <p class="card-text">{{user.name}}</p> </div> </div> </div> </template> <script type="text/ecmascript-6"> import PubSub from 'pubsub-js' import axios from 'axios' export default{ data(){ return { firstView: true, loading:false, overNull:false, errorMsg: '', users:null // [ // {url:'',avatar_url:'',name:''}, // ] } }, mounted(){ // 是否在此发ajax消息 是点击search后 // 订阅搜索的消息 PubSub.subscribe('search',(msg,searchName)=>{ const url = `https://api.github.com/search/users?q=${searchName}` // 更新失败(请求中) this.firstView = false this.loading = true this.overNull = false alert('请求中') // 发送ajax请求 axios.get(url).then(response=> { // 获取数据 data const result = response.data // data中的items 里面有图片的路径 名称 const users = result.items.map(item=>({ url:item.html_url, avatar_url:item.avatar_url, name: item.login })) if(users.length !== 0){ console.log(users) } // 成功更新状态(成功) this.loading = false this.users = users if(users.length == 0){ this.overNull = true } // 失败更新状态(失败) }).catch(error=>{ this.loading = false this.errorMsg = '请求失败' }) }) } }; </script> <style type="stylus" rel="stylesheet/stylus"> .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>
Search.vue
1 <template> 2 <div> 3 <section class="jumbotron"> 4 <h3 class="jumbotron-heading">Search Github Users</h3> 5 <div> 6 <input type="text" placeholder="enter the name you search" v-model="searchName"/> 7 <button @click="search">Search</button> 8 </div> 9 </section> 10 </div> 11 </template> 12 13 <script type="text/ecmascript-6"> 14 import PubSub from 'pubsub-js' 15 export default{ 16 data(){ 17 return { 18 searchName:'' 19 } 20 }, 21 methods:{ 22 search(){ 23 const searchName = this.searchName.trim() 24 if(searchName){ 25 // 发布搜索的消息 26 PubSub.publish('search',searchName) 27 } 28 } 29 } 30 31 }; 32 </script> 33 34 <style type="stylus" rel="stylesheet/stylus"> 35 36 </style>