① vue 組件通信方式,六種方法
「阿彌陀佛,善哉善哉。」
「魔鏡啊!魔鏡,誰是這世界上最美麗的女人?」
「願上帝保佑你,阿門!」
等等,這些語句是不是特別經典?特別有畫面感?眼前立馬浮現出家人、後母和牧師?
通過言語,可以判斷一個人的職業、身份、地位。
通過特殊語句可以與神明通話,可以和精靈共舞。
(1)props / $emit 適用 父子組件通信
父組件注入,子組件接收。
這種方法是 Vue 組件的基礎,相信大部分同學耳聞能詳,所以此處就不舉例展開介紹。
注意:props是單向數據流,既只能從父級傳到子級,如果想要達到雙向,子級能夠修改父級,則需要給props加sync修飾符。(文章後部分有詳細介紹)
(2)ref 與 $parent / $children 適用 父子組件通信
ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實例
$parent / $children:訪問父 / 子實例
(3)$attrs / $listeners 適用於 隔代組件通信
$attrs:包含了父作用域中不被 prop 所識別 (且獲取) 的特性綁定 ( class 和 style 除外 )。
當一個組件沒有聲明任何 prop 時,這里會包含所有父作用域的綁定 ( class 和 style 除外 ),並且可以通過 v-bind="$attrs" 傳入內部組件。通常配合 inheritAttrs 選項一起使用。
$listeners:包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監聽器。它可以通過 v-on="$listeners" 傳入內部組件
(4)provide / inject 適用於 隔代組件通信
祖先組件中通過 provider 來提供變數,然後在子孫組件中通過 inject 來注入變數。provide / inject API 主要解決了跨級組件間的通信問題,不過它的使用場景,主要是子組件獲取上級組件的狀態,跨級組件間建立了一種主動提供與依賴注入的關系。
(5)EventBus ($emit / $on) 適用於 父子、隔代、兄弟組件通信
這種方法通過一個空的 Vue 實例作為中央事件匯流排(事件中心),用它來觸發事件和監聽事件,從而實現任何組件間的通信,包括父子、隔代、兄弟組件。
(6)Vuex 適用於 父子、隔代、兄弟組件通信
Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。每一個 Vuex 應用的核心就是 store(倉庫)。「store」 基本上就是一個容器,它包含著你的應用中大部分的狀態 ( state )。
Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地得到高效更新。
改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化。
vuex的詳細使用方法: vuex管理狀態倉庫使用詳解
Vue 組件間通信是面試常考的知識點之一,這題有點類似於開放題,你知道的回答出越多方法越加分,表明你對 Vue 掌握的越熟練。
舉例props使用
a.vue 引用了一個detail組件
詳解eventBus通信方法
第一步:首先需要創建事件匯流排並將其導出,以便其它模塊可以使用或者監聽它。
兩個初始化事件中心的方法:
第二步:創建了 EventBus ,接下來你需要做到的就是在你的組件中載入它,並且調用同一個方法,就如你在父子組件中互相傳遞消息一樣。
假設你有兩個Vue頁面需要通信: A 和 B ,A頁面 在按鈕上面綁定了點擊事件,發送一則消息,想通知 B頁面。
接下來,我們需要在 B頁面 中接收這則消息。
同理我們也可以在 B頁面 向 A頁面 發送消息。這里主要用到的兩個方法:
如果使用不善,EventBus會是一種災難,到底是什麼樣的「災難」了?大家都知道vue是單頁應用,如果你在某一個頁面刷新了之後,與之相關的EventBus會被移除,這樣就導致業務走不下去。還要就是如果業務有反復操作的頁面,EventBus在監聽的時候就會觸發很多次,也是一個非常大的隱患。這時候我們就需要好好處理EventBus在項目中的關系。通常會用到,在vue頁面銷毀時,同時移除EventBus事件監聽。
如果想移除事件的監聽,可以像下面這樣操作:
$on事件是不會自動清楚銷毀的,需要我們手動來銷毀,否則在b組件每次載入一次就會創建一個監聽,會重復監聽到數據。
可以使用EventBus.$off('aMsg')來移除應用內所有對此某個事件的監聽。
或者直接調用EventBus.$off()來移除所有事件頻道,不需要添加任何參數 。
總結: 所以,如果想要用bus 來進行頁面組件之間的數據傳遞,需要注意兩點,組件A$emit事件應在beforeDestory生命周期內。其次,組件B內的$on記得要銷毀。
② 我說這是全網最全vue組件通信方式
prop
event
style和class
natvie修飾符
$listeners
v-model
sync修飾符
$parent 和 $children
$slots 和 $scopedSlots
ref
最常見的組件通信方式,由父組件向子組件傳遞。prop可接收一個數組或對象
子組件向父組件發送通知,並傳遞參數
子組件
父組件
父組件可以向子組件傳遞style 和 class ,style 和 class將合並到子組件根元素上
父組件
子組件
最終渲染結果
父組件在使用子組件時,在子組件上定義一些屬性,這些屬性將作用於子組件的根元素上,但是不包括style和class
父組件
子組件
最終渲染結果
Tip:子組件可以通過定義 inheritAttrs:false 來緊張 attribute 附著在子組件根元素上 但不影響通過 $attrs 獲取數據
在注冊事件時,父組件可以通過 navite 修飾符,將事件注冊到子組件根元素上
父組件
子組件
子組件可以通過 $listeners 獲取父組件傳遞過來的所有處理函數
父組件在使用子組件時,可以在子組件上綁定v-model,子組件通過定義model的prop和event還獲取父組件定義的值
父組件
<compn v-model=" "datas" />
子組件
和 v-model類似,用於雙向數據綁定,不同點在於 v-model只能針對一個數據進行綁定,而 sync 修飾符沒有限制
子組件
父組件
在組件內部,可以通過$parent 和$children屬性,分別獲取當前組件的父組件和子組件實例
ref
在使用組件時,可以通過在組件上定義ref來獲取組件實例
provide和inject 可以實現深層組件通信,頂層組件只需定義provide,底層組件通過inject接受數據
頂層組件
如果一個組將改變了地址欄,所有監聽地址欄的組將都會做出相應的改變,
vuex 過於笨重,通常不建議在小型項目中使用,小型項目可以使用store 或 eventbus代替vuex,vuex本質上就是一個數據倉庫。在此不做過多贅述,先挖一個坑,下回再敘。
store模式其實就是一個普通的js模塊,各組件可以導入該模塊,將數據放到data裡面,此時store就具有響應式了。
tip: store模式的缺點是無法跟蹤數據的改變,因為所有組件都可以更改數據
③ vue腳手架如何實現將數據傳給下一個html
跟腳手架沒有關系。你可以用bus或者vuex傳遞數據。
④ Vuex的使用及組件通信方式
Vuex是通過全局注入store對象,來實現組件間的狀態共享。在大型復雜的項目中(多級組件嵌套),需要實現一個組件更改某個數據,多個組件自動獲取更改後的數據進行業務邏輯處理,這時候使用vuex比較合適。假如只是多個組件間傳遞數據,使用vuex未免有點大材小用,其實只用使用組件間常用的通信方法即可。
Vue組件簡單常用的通信方式有以下幾種:
1、父子通信:父向子傳值,通過props;子向父傳值通過events ($emit);父調用子方法通過ref;provide / inject。
2、兄弟通信:bus
3、跨級嵌套通信:bus;provide / inject等。
Vuex有以下幾個部分構成:
1)state
state是存儲的單一狀態,是存儲的基本數據。
2)Getters
getters是store的計算屬性,對state的加工,是派生出來的數據。就像computed計算屬性一樣,getter返回的值會根據它的依賴被緩存起來,且只有當它的依賴值發生改變才會被重新計算。
3)Mutations
mutations提交更改數據,使用store.commit方法更改state存儲的狀態。(mutations同步函數)
4)Actions
actions像一個裝飾器,提交mutation,而不是直接變更狀態。(actions可以包含任何非同步操作)
5)Mole
Mole是store分割的模塊,每個模塊擁有自己的state、getters、mutations、actions。
const moleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
moles: {
a: moleA,
b: moleB
}
})
store.state.a // -> moleA 的狀態
store.state.b // -> moleB 的狀態
觸發非同步請求操作:
this.$store.dispatch('reqHomeData')
actions中:
async reqHomeData({ commit }) {
const result = await server.getHomeData();
commit(GET_HOME_DATA, { homeList: result })
},
mutations中:
[GET_HOME_DATA](state, { homeList }) {
state.homeList = homeList
},
⑤ vue事件匯流排EventBus
vue組件有父子組件通信:props
兄弟組件通信:
可以使用vuex,還可以使用事件匯流排eventBus
使用方法:
1.初始化:
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
另外一種方式,可以直接在項目中的 main.js 初始化 EventBus :
// main.js
Vue.prototype.$EventBus = new Vue()
2.發送事件
import { EventBus } from "../event-bus.js";
export default {
methods: {
sendMsg() {
EventBus. on("aMsg", (msg) => {
// A發送來的消息
this.msg = msg;
});
EventBus如果使用不善,EventBus會是一種災難,到底是什麼樣的「災難」了?大家都知道vue是單頁應用,如果你在某一個頁面刷新了之後,與之相關的EventBus會被移除,這樣就導致業務走不下去。還要就是如果業務有反復操作的頁面,EventBus在監聽的時候就會觸發很多次,也是一個非常大的隱患。這時候我們就需要好好處理EventBus在項目中的關系。通常會用到,在vue頁面銷毀時,同時移除EventBus事件監聽。
4.移除監聽
import {
eventBus
} from './event-bus.js'
EventBus.$off('aMsg', {})
全局EventBus
var EventBus = new Vue();
Object.defineProperties(Vue.prototype, {
$bus: {
get: function () {
return EventBus
}
}
})
在這個特定的匯流排中使用兩個方法 emit。一個用於創建發出的事件,它就是 on:
var EventBus = new Vue();
this. emit('nameOfEvent', { ... pass some event data ...});
this. on('nameOfEvent',( bus.$emit("sendMsg", '我是web秀');,另一個Vue頁面使用
this. on('updateMessage', function(value) {
console.log(value); // 我是web秀
})
同時也可以使用this. off('sendMsg')來移除事件監聽。
⑥ 史上最全前端vue面試題!推薦收藏
1.為什麼會形成跨域?
不是一個源的文件操作另一個源的文件就會形成跨域。當請求端的協議、域名、埠號和伺服器的協議、域名、埠號有一個不一致就會發生跨域。
解決方法:安裝插件
Pip install django-cors-headers
2.vuex的工作流程?
① 在vue組件裡面,通過dispatch來出發actions提交修改數據的操作。
② 然後再通過actions的commit來出發mutations來修改數據。
③ mutations接收到commit的請求,就會自動通過Mutate來修改state(數據中心裏面的數據狀態)裡面的數據。
④ 最後由store觸發每一個調用它的組件更新。
3.vuex是什麼?怎麼使用?
vuex是一個專為vue.js應用程序開發的狀態管理模式。使用:store,getters,mutations,actions,moles詳細使用寫法請見:https://blog.csdn.net/qq_33226029/article/details/109628600?spm=1001.2014.3001.5502
4.vuex中的數據在頁面刷新後數據消失怎麼解決?
使用sessionStorage或localStorage存儲數據;也可以引入vuex-persist插件
5.在vue中,如何阻止事件冒泡和默認行為?
在綁定事件時,在指令後邊加上修飾符.stop來阻止冒泡,.prevent來阻止默認行為
6.深拷貝與淺拷貝?
假設B復制A,修改A的時候,看B是否變化:B變了是淺拷貝(修改堆內存中的同一個值),沒變是深拷貝(修改堆內存中不同的值)。淺拷貝只是增加了一個指針指向已存在的內存地址,深拷貝是增加了一個指針並申請了一個新的內存,使這個增加的指針指向這個新的內存。深拷貝和淺拷貝最根本的區別在於是否真正獲取一個對象的復制實體,而不是引用。
7.vue的生命周期?
beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyedactived deactived (keep-alive)組件是否激活調用
8. keep-alive: 組件緩存
https://juejin.cn/post/6844903624099758094
router.js中:
meta: {keepAlive:true} // 需要被緩存
鉤子執行順序:created -> mounted -> actived
include表示需要緩存的頁面;exclude表示不需要緩存的頁面。如果兩個同時設置,exclude優先順序更 改,則組件不會被緩存。
應用場景: 用戶在某個列表頁面選擇篩選條件過濾出一份數據列表,由列表頁面進入數據詳情頁面,再返回 該列表頁,我們希望列表頁可以保留用戶的篩選狀態。
9.vue傳值方式?
props $emit() $on() $parent $children $listener $attr
10. $on 兄弟組件傳值
$emit 分發
$on 監聽
$off 取消監聽
$once 一次性監聽一個事件
在js文件中定義一個中央事件匯流排Bus,並暴露出來
具體的實現方式:
使用Bus的時候在接收Bus的組件的beforeDestroy函數中銷毀Bus,否則會一直疊加調用這個方法。
應用場景:「退出登錄」 -> ①點擊退出登錄;②修改密碼後自動退出登錄
11.組件跨級傳值
$attrs a->b->c
$listeners 監聽
12.vue事件修飾符有哪些?
.stop .prevent .self .once .passive .sync
13.箭頭函數中的this?
不具有this綁定,但函數體可以使用this,這個this指向的是箭頭函數當前所處的詞法環境中的this對象。
15.為什麼vue組件中data必須是一個函數?
如果不是函數的話,每個組件的data都是內存的同一個地址,一個數據改變了其他也改變了,當他是一個函數時,每個組件實例都有自己的作用域,每個實例相互獨立,就不會互相影響。
16.v-if 和 v-show區別?
v-if 是對標簽的創建與銷毀, v-show 則僅在初始化時載入一次,v-if 開銷相對來說比v-show 大;
v-if 是惰性的;v-show 做的僅是簡單的css切換。
17.v-text 與 v-html區別?
v-text 用於普通文本,不能解析html;
v-html 反之。
18.v-for key的作用?
使用v-for更新渲染過的數據,它默認用「就地復用」策略。如果數據項的順序改變,vue將不是移動DOM元素來匹配數據項的改變,而是簡單地復用此處每個元素,並確保在特定索引下顯示已被渲染過的每個元素。key屬性類型只能是string或number。
key的特殊屬性主要用在虛擬DOM演算法,在新舊node對比時辨識VNods。如不使用key,vue會使用一種最大限度減少動態元素並且盡可能的嘗試修復/再利用相同類型元素的演算法,它會基於key的變化重新排列元素順序。
19.Scss是什麼?在vue-cli中安裝步驟?有哪幾大特性?
npm 下載loader (sass-loader,css-loader,node-sass),在webpack中配置extends屬性(加.scss拓展) Vscode中可在擴展中下載;
特性:可以用變數,可以用混合器,可以嵌套等。
20.vue獲取dom?
ref
21.vue初始化頁面閃動問題?
webpack、vue-router
v-cloak css:[v-cloak]:display:none
22.什麼是vue-router?
vue router 是官方路由管理器。
主要功能:路由嵌套,模塊化 基於組件路由配置,路由參數、查詢、通配符,細粒度導航控制,自定義的滾動條行為等。
23.vue路由傳參,接收?
傳: this.$router.push({path:'', query(params):{}})
接:this.$router.query.xxx
24.防抖和節流?
節流是一定時間內執行一次函數,多用在scroll事件上;
防抖是在一定時間內執行最後一次的函數,多用在input輸入操作,表單提交等。
25.如何讓scss只在當前組件中起作用?
⑦ Vue組件通信中eventBus的使用
原文鏈接: https://segmentfault.com/a/1190000013636153?utm_source=tag-newest
在vue1.0中,組件之間的通信主要通過vm.dispatch沿著父鏈向上傳播和用vm.dispatch沿著父鏈向上傳播和用vm.broadcast向下廣播來實現。然而在vue2.0中,已經廢除了這種用法。
vuex加入後,對組件之間的通信有了更加清晰的操作,對於中大型的項目來說,一開始就把vuex的使用計劃在內是明智的選擇。
然而在一些小型的項目,或者說像我這樣寫到一半才發現vue2.0用不了.broadcast和.broadcast和dispatch的人來說,就需要一個比較便捷的解決方法。那麼,eventBus的作用就體現出來了。
主要是現實途徑是在要相互通信的兄弟組件之中,都引入一個新的vue實例,然後通過分別調用這個實例的事件觸發和監聽來實現通信和參數傳遞。
這里來看一個簡單的例子:
比如,我們這里有三個組件,main.vue、click.vue、show.vue。click和show是父組件main下的兄弟組件,而且click是通過v-for在父組件中遍歷在了多個列表項中。這里要實現,click組件中觸發點擊事件後,由show組件將點擊的是哪個dom元素console出來。
首先,我們給click組件添加點擊事件
想要在doClick()方法中,實現對show組件的通信,我們需要新建一個js文件,來創建出我們的eventBus,我們把它命名為bus.js
importVuefrom'vue';exportdefaultnewVue();
這樣我們就創建了一個新的vue實例。接下來我們在click組件和show組件中import它。
importBusfrom'common/js/bus.js';
接下來,我們在doClick方法中,來觸發一個事件:
methods: { addCart(event){Bus.$emit('getTarget',event.target); } }
這里我們在click組件中每次點擊,都會在bus中觸發這個名為'getTarget'的事件,並將點擊事件的event.target順著事件傳遞出去。
接著,我們要在show組件中的created()鉤子中調用bus監聽這個事件,並接收參數:
created(){ Bus.$on('getTarget',target=>{console.log(target); }); }
這樣,在每次click組件的點擊事件中,就會把event.target傳遞到show中,並console出來。
所以eventBus的使用還是非常便捷的,但是如果是中大型項目,通信比較復雜,還是建議大家直接使用vuex。
來看一個實際例子:
我們創建了一個selection.vue的下拉框組件,在layout.vue組件中使用了selection.vue組件,我們要實現點擊layout.vue組件頁面的任意一處(除下拉框組件本身外),都可以將下拉框收起來。首先,新建了一個eventBus.js文件,在裡面新建了一個vue的實例賦值給const eventBus,在selection.vue和layout.vue中分別import eventBus from '../../eventBus'和import eventBus from '../eventBus',則eventBus對於selection.vue和layout.vue就是一個全局的vue實例對象,然後通過分別調用eventBus這個實例的事件觸發emit和事件監聽emit和事件監聽on來實現通信和參數傳遞。圖6,是為了在一個頁面中,把selection.vue使用了至少兩次,則我們點擊任意一個selection.vue的同時,要把其它的selection.vue給收起來,如圖7。
圖1:
圖2:
圖3:
圖4:
圖5:
圖6:
圖7:
⑧ vuex的五個屬性及使用方法
vuex的五個屬性及使用方法具體如下:
VueX是一個專門為Vue.js應用設計的狀態管理構架,統一管理和維護各個vue組件的可變化狀態(你可以理解成vue組件里的某些data)。
Vuex有五個核心概念:
state,getters,mutations,actions,moles。
1.state:vuex的基本數據,用來存儲變數
2.geeter:從基本數據(state)派生的數據,相當於state的計算屬性
3.mutation:提交更新數據的方法,必須是同步的(如果需要非同步使用action)。每個mutation都有一個字元串的事件類型(type)和一個回調函數(handler)。回調函數就是我們實際進行狀態更改的地方,並且它會接受state作為第一個參數,提交載荷作為第二個參數。
4.action:和mutation的功能大致相同,不同之處在於==》1.Action提交的是mutation,而不是直接變更狀態。2.Action可以包含任意非同步操作。
5.moles:模塊化vuex,可以讓每一個模塊擁有自己的state、mutation、action、getters,使得結構非常清晰,方便管理。