vue工程利用pubsub-js實現兄弟組件之間的通信
前言
項目是基於vue-cli創建的,不會搭建vue開發環境的同學可以百度,這裏不再贅述。
步驟流程
vue項目搭建完成之後的文件圖如下:
我的上一篇博客已經詳細敘述vue工程中各個文件的作用,不清楚的同學可以移步看這裏
項目中需要用到axios這個包,所以我們先安裝相應的包,項目終端輸入:
npm install axios -S
。後面兄弟組件之間通信我們采用的是“訂閱消息/發布消息”的方法,這個也是一個包,所以也先安裝下依賴包npm i pubsub-js -S
。安裝完成後可以在項目package.json文件中看到對應依賴包。
src文件夾下components下創建main.vue和header.vue兩個組件,分別代表項目中主體區域和頭部區域,等下需要掛載到根組件App下。
- header.vue文件中相關代碼:
<template> <div id="header"> <div class="container"> <div class="row center"> <h1>Search Github Users</h1> <input type="text" v-model="searchName"> <input type="button" value="Search" class="btn btn-primary" placeholder="請輸入github用戶名" @click="search"> </div> </div> </div> </template> <script> import PubSub from 'pubsub-js' export default { name: 'Header', data () { return { searchName: '' } }, methods: { search () { // 發布消息 const searchName = this.searchName.trim() if (searchName) { PubSub.publish('search', searchName) } } } } </script> <style> #header{ height: 200px; } .container .center{ text-align: center; } </style>
main.vue文件中相關代碼:
<template> <div id="main"> <h1 v-if="firstview">請輸入搜索用戶的名稱</h1> <h1 v-if="loading">loading</h1> <h1 v-if="errormsg">{{errormsg}}</h1> <div class="row"> <div class="col-xs-6 col-md-3" v-for="(user,index) in users" :key="index"> <a :href="user.url"> <img :src="user.avatar_url"> </a> <span>{{user.name}}</span> </div> </div> </div> </template> <script> import PubSub from 'pubsub-js' import axios from 'axios' // https://api.github.com/search/users?q= export default { name: 'Main', data () { return { firstview: true, loading: false, errormsg: '', users: null // [{url:' ',name:'',avatar_url:""}] } }, mounted () { // 訂閱消息 PubSub.subscribe('search', (msg, searchName) => { const url = 'https://api.github.com/search/users?q='+searchName // 更新狀態 this.firstview = false this.loading = true this.users=null this.errormsg='' 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> <style> #main > .row ,#main h1{ position: absolute; left: 50%; transform: translateX(-50%); } #main > .row > div{ float: left; width: 100px; padding: 0; text-align: center; color: red; font-size: 18px; margin: 0 10px; } .row a img{ width: 100px; height: 100px; } </style>
這裏主要是詳細解釋下main.vue中相關代碼。在項目的主體區域中,我們需要通過後臺返回的數據進行頁面的渲染。標簽模板中主要是通過v-for="(item,index) in items" :key="index"
指令遍歷得到的數組,進行頁面渲染,利用v-for我們可以輕松得到一組類似的結構,而不必多次寫一些重復的html標簽。在組件模板對象中我們定義了一組數據信息,
這裏的users
主要是保存由後臺返回回來的一組數據,可以供頁面進行渲染加載。另外三種皆為不同的狀態標誌屬性,當我們進行不同的操作,或者發送Ajax請求(成功?失敗)都可以改變相應的狀態值從而使頁面呈現不同狀態。
- pub-sub庫的使用。
項目中我們頭部header需要向後臺發送關鍵字,後臺根據得到的關鍵字進行相應的操作,返回項目需要的數據。main主體區域中需要利用後臺返回的數據,進行頁面的渲染,main區域中必定會利用header中提供的關鍵字發送ajax請求,所以這就牽扯到組件之間的通信問題,pubsub-js就是用來實現組件之間通信的。兄弟組件之間通信如果利用props屬性,需要借助父組件來實現,pubsub跨越組件之間的關系階層進行通信。pubsub-js也就是我們所說的訂閱消息和發布消息,訂閱消息可以理解為事件的監聽,發布消息可以理解為觸發事件。我們在header中點擊搜索會通知main區域向後臺發送Ajax請求,所以我們在header中發布消息,main中訂閱消息。
利用pubsub,首先需要導入這個包。search按鈕點擊的時候,我們可以在按鈕點擊的回調函數裏去發布消息。發布消息是PubSub.publish()
方法,這裏需要提供兩個參數,"發布的消息名","提供給訂閱者的參數",這裏的參數是輸入框的關鍵字。
main區域在組件的生命周期函數mounted(頁面加載完成)中訂閱消息。訂閱消息是PubSub.subscribe()
方法,這裏接受兩個參數,"發布的消息名","事件的監聽函數",這裏事件的監聽函數需要兩個參數:一個是msg(發布的消息名,無用),一個是searchName(發布者傳來的參數)。我們在事件的監聽裏面去發送Ajax請求,更新頁面。
- 項目完成後的效果圖:
後綴
如果你覺得這個對你有幫助,歡迎轉載,煩請註明出處。同時也歡迎大家在GitHub上和我一起進階前端。
找到我:GitHub
找到我:知乎
vue工程利用pubsub-js實現兄弟組件之間的通信