案例知識點
- 兄弟組件兒的通信 使用了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='width: 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>