Vue 組件通信這塊,其實在先前的文章《vue 組件傳值》中就已經提過,總結了常用的五種方法:props、ref、emit、路由、vuex。
這裏,考慮到實際項目中的開發需要,略加補充,一起探討學習下!
provide + inject (官檔)
provide / inject 是Vue.js 2.2.0 新增的 API,一種無依賴的組件通信方法。
官檔說明:這對選項需要一起使用,以允許一個祖先組件向其所有子孫後代注入一個依賴,不論組件層次有多深,並在起上下游關係成立的時間裏始終生效。如果你熟悉 React,這與 React 的上下文特性很相似。
A.vue
<template>
<div class="grand">
<Father></Father>
</div>
</template>
<script>
export default {
provide: {
name:"Hello"
}
}
</script>
B.vue
<template>
<div class="father">
<div>name:{{name}}</div>
<Sub></Sub>
</div>
</template>
<script>
export default {
inject: ['name'],
}
</script>
C.vue
<template>
<div class="sub">
<div>sub:{{name}}</div>
</div>
</template>
<script>
export default {
inject: ['name'],
}
</script>
*提示:provide 和 inject 綁定並不是可響應的。這是刻意爲之的。然而,如果你傳入了一個可監聽的對象,那麼其對象的屬性還是可響應的。
## $attrs 和 $listeners([官檔](https://cn.vuejs.org/v2/api/#vm-attrs))
$attrs 和 $listeners 都是Vue.js 2.4.0 版本新增的,實現父、子、孫組件的通信。
A.vue
<template>
<div class="grand">
<Father :num="active"></Father>
</div>
</template>
<script>
export default {
data() {
return {
active:0
};
},
}
</script>
B.vue
<template>
<div class="father">
<div>son:{{$attrs.num}}</div>
<Sub v-bind="$attrs" v-on="$listeners"></Sub>
</div>
</template>
C.vue
<template>
<div class="sub">
<p>sub: {{$attrs.num}}</p>
</div>
</template>
*提示:$attrs 和 $listeners 的數據會動態響應的
插槽 slot
<template>
<div class="index">
<Tab :tabData="tabData" @tabHandle="tabHandle">
<template slot="tabContent" slot-scope="props">
<div>{{props.active}}</div>
</template>
</Tab>
</div>
</template>
<template>
<div class="tab">
<div class="hd">
<div v-for="(item,index) in tabData" :key="index" @click="tabCard(index)">{{item}}</div>
</div>
<div class="bd">
<slot name="tabContent" :active="active"></slot>
</div>
</div>
</template>
cookie、localStrage、sessionStorage
Vuex 刷新頁面 state 數據丟失問題
比如,當你成功登陸一個後臺系統後,接口會返回一個 Token 用來作身份驗證。
前端儲存這個token,如果用 vuex 設置 state,刷新頁面,數據會丟失,這裏就會用到這三者: cookie、localStrage、sessionStorage
先來對比看下這三者:
圖片引用自網絡,侵刪!
所以,這裏用到的是 localStrage
login(shareKey) {
let { username, password } = this.loginData;
let params = { username, password };
params.shareKey = shareKey;
this.$fetch.login.toLogin(params).then((res) => {
localStorage.setItem('user_info', JSON.stringify(res.data));
this.$router.push('/cusService');
}).catch((err) => {
})
},
增刪改查:
//cookie
function setCookie(key,value,t){ //設置
var oDate = new Date();
oDate.setDate(oDate.getDate()+t);//某天
document.cookie = key + '='+value+';expries ='+oDate.toUTCString();
}
setCookie("name","hayden",365);
function getItem(key){ //獲取
let cookiesArr = document.cookie.split("; "); //留意 ;帶空格
for(let i of cookiesArr){
let item = i.split("=");
if(item[0]==key){
return item[1]
}
}
}
getItem("name")
function removeCookie(key){ //刪除key
setCookie(key,'',-1);
}
removeCookie("name")
//localStorage
localStorage["a"]=1; //設置
localStorage.a=1; l
localStorage.setItem("a",1);
localStorage['a']; //獲取
localStorage.a;
localStorage.getItem("a")
localStorage.removeItem("key") //刪除key
localStorage.clear() //清空所有
//sessionStorage
sessionStorage.setItem('a','1'); //設置
sessionStorage.a = '1';
sessionStorage['a'] = '1';
sessionStorage.getItem('a'); //獲取
sessionStorage.a
sessionStorage['a'];
sessionStorage.removeItem("a"); //刪除key
sessionStorage.clear(); //清空所有