項目背景
今天項目里的實習(xí)生在做搜索功能時扳肛,導(dǎo)航欄的搜索框與搜索頁面的搜索框,在內(nèi)容上竟然是各自獨(dú)立的乘碑。挖息。。兽肤。套腹。
無論他怎么鼓搗,在搜索欄上進(jìn)行搜索资铡,搜索頁面都沒有任何反應(yīng)电禀。他解釋說因為是兩個獨(dú)立的組件且不構(gòu)成父子關(guān)系,所以無法進(jìn)行值的傳遞共用笤休,即便使用路由傳參尖飞,也就第一次能獲取到并觸發(fā)請求,后續(xù)搜索框再搜索內(nèi)容店雅,也無法再次觸發(fā)搜索請求(其實政基,watch是可以做到的。闹啦。沮明。。)
考慮到整個項目的統(tǒng)一性窍奋,以及未來的需求可變性(簡單來說荐健,就是以防萬一產(chǎn)品又出幺蛾子)圣勒,整個項目的搜索功能,我更傾向于用vuex來做
思路簡介
通過vuex來實現(xiàn)全局搜索功能的數(shù)據(jù)共用摧扇,假設(shè)你已經(jīng)學(xué)過10分鐘的vuex(完全沒學(xué)過的。挚歧。扛稽。先去看個10分鐘教程先)
代碼簡單實現(xiàn)
<!--首先編寫一個簡單的搜索模塊-->
const search = {
state: {
searchKey: ''
},
mutations: {
SET_SEARCH_KEY(state,key) {
state.searchKey = key
}
},
actions: {
setSearchKey(context,key) {
context.commit('SET_SEARCH_KEY',key)
}
}
}
export default search
<!--再將這個search模塊導(dǎo)入到store文件中-->
import Vue from 'vue'
import Vuex from 'vuex'
import search from './modules/search'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
search
}
})
<!--上面的寫法可能跟你看的新手教程不太一樣,因為實際項目里需要用到vuex的地方蠻多的滑负,因此整體內(nèi)容量也比較大在张,所以一般都會采用分modules的形式,方便管理也方便后續(xù)繼續(xù)擴(kuò)展-->
export default store
<!--最后就是在main.js中注冊它啦-->
import Vue from 'vue'
import router from './router'
import store from './store'
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
到目前為止矮慕,簡單的搜索模塊就做好了帮匾,那么該如何使用呢?
分成兩部分痴鳄,一個是導(dǎo)航欄有搜索框瘟斜,一個是搜索頁有搜索框也有搜索結(jié)果列表
<!--假設(shè)這里是導(dǎo)航欄的搜索框-->
<template>
<div>
<input v-model="inputKey" @keyup.enter.native="handleKey"/>
</div>
</template>
<script>
export default {
data() {
return {
inputKey: ''// 這里就是搜索的關(guān)鍵字
}
},
methods: {
handleKey() {
// 在這里痪寻,調(diào)用store里search模塊的setSearchKey方法
this.$store.dispatch('setSearchKey', this.inputKey)
}
}
}
<!--基本邏輯就是螺句,在導(dǎo)航欄的搜索框里輸入內(nèi)容,點擊回車橡类,觸發(fā)search()方法蛇尚,調(diào)用store里search模塊的setSearchKey方法,最終實現(xiàn)關(guān)鍵字searchKey的改變-->
</script>
<!--假設(shè)這里是搜索頁的結(jié)果列表-->
<template>
<div>
<ul>
<li v-for="item in list" :key="item">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
list: []// 結(jié)果列表
searchText: ''// 一般我們不建議直接修改store里的值顾画,因此最好用另一個變量儲存
}
},
computed: {
<!--實時獲取store里的searchKey-->
searchKey() {
this.$store.state.search.searchKey
}
}
watch: {
<!--監(jiān)聽searchKey取劫,一旦該值有變化,立刻觸發(fā)相應(yīng)操作-->
searchKey(val){
this.searchText = val
this.search()
}
}
methods: {
search() {
// 在這里研侣,真正地向后臺發(fā)起請求
axios.get(url,this.searchText).then((res) => {
this.list = res.list
})
}
}
}
</script>
到這里為止谱邪,就可以成功實現(xiàn),在導(dǎo)航欄的搜索框進(jìn)行搜索庶诡,搜索頁面也能立刻顯示最新內(nèi)容(即使兩個組件之間不構(gòu)成父子組件)虾标,例如簡書的導(dǎo)航欄搜索, 底下的結(jié)果列表的變化
簡書搜索功能示例