# vue基礎 - vue項目搭建 - vue單文件組件 - mustach表達式 - vue指令 - methods方法 - filters過濾器 - computed計算屬性 - watch監聽器 - vue組件 - vue-router 路由 - vue生命周期 - vue組件通信 - slo ...
vue基礎
-
vue項目搭建
-
vue單文件組件
-
mustach表達式
-
vue指令
-
methods方法
-
filters過濾器
-
computed計算屬性
-
watch監聽器
-
vue組件
-
vue-router 路由
-
vue生命周期
-
vue組件通信
-
slot插槽
-
vuex 狀態管理
前言
vuejs 是一個構建數據驅動的漸進式MVVM框架
數據驅動:不用操作dom(vue)
漸進式: 漸進式開發---模塊的使用(在項目開發的過程之中不斷的引入三方包完善項目的開發)
響應的數據綁定: 數據一旦發生改變,頁面自動重新渲染(替代了 dom操作)
MVVM : model(數據) view(視圖) ViewModel(數據和視圖進行綁定)===雙向綁定
優點
-
體積小(33k)
-
基於虛擬DOM 比較 不同的dom節點 直接更新的是 一部分不同的dom節點 性能高
-
雙向數據綁定 -節約渲染dom的代碼
-
生態豐富、學習成本低
vue全家桶技術棧
vue2.0 底層 vue-cli腳手架(vue+webpack) vue-router vuex狀態管理 axios介面對接
1.vue2 項目創建
1.1直接引入
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
1.2通過vue-cli腳手架創建
npm install -g @vue/cli #vue腳手架 全局安裝
或者
yarn global add @vue/cli
vue --version #檢查版本是否安裝成功
1.3 項目創建 vue create 項目名稱
vue create 項目名稱 #創建項目
手動選擇配置--vue version ----babel ----css 預處理
vue 版本 配置 babel 配置 css預處理配置
項目啟動
yarn serve
1.4.vue項目目錄結構
1.5.vue 代碼插件
- 代碼高亮 vetur
- 代碼補全 Vue VSCode Snippets
2.單文件組件 .vue SFC
一個 .vue 文件 就是一個 組件
一個頁面可以是 一個vue文件組成,也可以是多個vue文件共同組成
組件特點:帶有獨立功能 的小模塊 ,低耦合
組件的優點:可重用 可組合 易維護
<template>
<!-- template 節點 有且只有一個 節點 div -->
<div>
<div class="box">asdasdsad</div>
<div>aaaa</div>
asndjasbdjasbdjasda
</div>
</template>
<script>
// 導出對象
export default {};
</script>
<style lang="less">
.box {
color: #f60;
font-size: 50px;
}
</style>
3.data() 函數與mastach 語法
vue 中data函數 返回了一個數據對象給vue組件
在組件的html代碼部分 可以通過 mastach 語法 {{}} 獲得該數據
mastach 表達式語法:
{{ js表達式 }}
<template>
<div>
<!-- mustach 表達式 在vue文件中 html代碼裡面 獲取 data的數據 -->
<p > 姓名: {{ name }} </p>
<p>年齡: {{ age }}</p>
<p>愛好: {{ like[0] }} {{ like[1] }} {{ like[2] }}</p>
</div>
</template>
<script>
export default {
data() {
return {
name: "艾坤",
age: 40,
like: ["唱", "跳", "rap","籃球"],
};
},
};
</script>
4.vue 中的js代碼配置項
<script>
export defalut {
//數據
data(){
return {}
},
//組件
components:{
},
//方法
methods:{
},
//計算屬性
computed:{
},
//監聽
watch:{
},
//過濾器
filters:{
},
//組件生命周期鉤子函數-八個
}
</script>
5.組件的創建和註冊 components
- 創建組件 .vue文件
- 父組件導入子組件
- 註冊組件
- 使用組件
5.1.創建組件的要求
大駝峰
5.2.父組件導入子組件
import 子組件名 from '組件路徑'
5.3.父組件註冊子組件
components:{
子組件名,
},
5.4.組件的使用
<template>
<div>
<子組件名></子組件名>
</div>
</template>
6.vue指令 14個
6.1.v-text 和 v-html 節點渲染
v-text : 給當前的dom節點 渲染 一段 靜態文本 -----innerText
v-html:給當前的dom節點 渲染 一段 html代碼的文本 ----innerHTML
區別:
mustach 更適合 零散的變數的字元拼接輸出
v-text 更適合完整字元串的輸出
v-html 更適合 帶有html標簽的字元串的輸
<!-- mustach {{}} -->
<p>
{{ str }}
</p>
指令v-text
<p v-text="str"></p>
指令: v-html
<p v-html="str"></p>
6.2.v-show 和 v-if 顯隱切換
v-show:對dom節點 的顯示和隱藏
v-if:對節點增加和刪除
區別:
v-show:控制css屬性 display 對dom進行顯示和隱藏
v-if: 對DOM節點進行增加 刪除操作
<span v-show="flag"> 女</span>
<span v-show="flag">男</span>
<hr>
<span v-if="flag"> 女</span>
<span v-if="flag">男</span>
<script>
export defalut{
data(){
flag:true
}
}
</script>
6.3.v-if 和 v-else 和 v-else-if 判斷
v-if 滿足條件 新增 dom
v-else-if 不滿足 v-if的條件 但是 滿足了 v-else-if ="條件" 新增dom
v-else 前面的條件都不滿足 新增 dom
區別:效果等同於 js 的 if else 分支語法特點
<p v-if="flag === 0">女</p>
<p v-else-if="flag === 1">男</p>
<p v-else-if="flag === 2">公公</p>
<p v-else>其他</p>
<script>
data() {
return {
flag: 4, //0:女 1 :男 2:公公 3:其他
};
},
</script>
6.4.v-for 迴圈
v-for:迴圈數據 並渲染頁面 v-for 迴圈必須搭配 :key="表達式"
動態屬性進行使用
註意:如果同一個組件中存在多個 v-for 迴圈 需要特別註意 key的值
整個組件中 key 都必須保持唯一性,目的: 虛擬DOM發生更新的時候 所有的dom節點可以快速比較
<p v-for="(item, index) in arr" :key="index">
我是艾坤叫來的兄弟:我的名字:{{ item }}
</p>
<script>
export default {
data() {
return {
arr: ["王子", "小鬼", "大鬼"],
};
},
};
</script>
6.5.v-on 事件綁定 與methods 對象
給dom綁定事件
v-on:` 可以簡寫為 `@
函數的調用可以 傳遞自定義參數 與 $event 事件對象
<div v-on:事件類型="事件處理函數()"> 點擊我 </div>
<div @事件類型="事件處理函數()"> 點擊我 </div>
export defalut{
methods:{
事件執行函數(){
console.log('點你了...')
}toe
}
}
6.6.v-model 輸入框數據綁定
實現頁面的輸入框(input select check radio )與 data中的數據 進行雙向綁定
雙向綁定:一旦頁面中的輸入框發生數據的變化,會導致 data中的數據 跟著變化
<input v-model="表達式" >
<input v-model="number+1" >
data(){
return{
number:100,
str:'你好啊'
}
}
6.7.v-bind 屬性綁定
綁定、操作dom 屬性 綁定動態值 布爾值 或者數字類型時使用
v-bind:` 可簡寫為 `:
<標簽 v-bind:屬性名="表達式">
<標簽 :屬性名="表達式">
7.methods 方法
- 事件處理函數
- 頁面當中的表達式 都可以使用 函數
- 函數與函數之間 調用 this.函數名()
- vue 聲明周期 鉤子函數 中調用 this.函數名()
<標簽 @事件類型="事件執行函數()">
<p>
{{ 函數名() }} //表達式 可以寫成函數的調用
<p>
<script>
export default{
methods:{
事件執行函數(){
},
}
}
</script>
8.filters 過濾器
將原來的數據 進行處理並返回一個新數據
語法和 methods中方法 一樣,filters中的函數 必須要有返回值
filters中 獲取不到data() 中的數據
<div> {{ 參數|過濾器名 }} </div>
filters:{
過濾器名(data){
//處理數據
return 新數據
}
}
9.computed 計算屬性
作用: 將比較複雜的計算交給計算屬性處理 ,而不是交給 methods處理
語法規則 和methods 一模一樣 ,必須要有返回數據
調用時不能加小括弧
依賴緩存:如果參與計算的基礎數據 沒有發生變化,不會進行再次調用,
第一次 計算完成之後,只要參與計算的數據沒有發生變化,後面的反覆調用,不會執行函數體,直接用之前的數據輸出
使用場景:需要反覆輸出的 複雜的運算
<p v-for="item in 100" :key="item">
{{ resData }}
</p>
data(){
return {
num:100,
}
}
computed: {
resData() {
//根據依賴緩存特點 只執行了一次函數體
console.log('執行代碼一次....');
return this.num % 21;
},
},
10.watch 偵聽器 監聽器 常用
監聽數據的變化,如果數據發生改變 觸發對應的方法
export defalut {
data(){
return{
}
},
watch:{
需要監聽變數(newVal,oldVal){
//newVal: 改變之後的數據 新數據
//oldVal:改變之前的數據 老數據
}
}
}
watch:{
需要監聽變數:{
handler(newVal,oldVal){ },
deep:true //是否開啟深度監聽
immediate:true //立即執行一次
}
}
11.vue組件
11.1組件分類
- 頁面級組件
實現頁面與頁面之間的跳轉
- 公共組件
多個頁面 組件都可使用的通用組件 放在src/components 中
- 業務組件
在某個頁面 中進行使用 的組件,更多體現為 頁面的某一模塊或部分
11.2頁面級組件的創建步驟
創 配 占位 測 四個步驟
-
創建.vue 文件
-
配置路由 一 一對應 router/index.js
//導入頁面級組件
import Mine from '../views/my/Mine.vue'
const routes = [
{
path: "/mine", //跳轉的路由
component: Mine //對應的組件
},
]
- 父組件中需要 給子組件占位 app.vue
<router-view></router-view>
- 測試 是否可以訪問 手動切換路由地址
http://localhost:8080/#/mine
12路由的使用 vue-router
vue-router 通過a標簽 封裝了一個組件 :router-link
<router-link to="頁面的路徑 path"> </router-link>
12.1 vue-router的配置
12.2 兩個路由對象
- this.$route
this.$route.path #當前頁面的路由
this.$route.query #獲取頁面的search參數 location.search 獲取的值是一個對象
this.$route.params #獲取頁面參數
this.$route.matched #當前頁面匹配的所有
- this.$router
this.$router.push('路由的地址 path ') #在js中進行頁面的跳轉
this.$router.back() #返回上一頁 history.back()
this.$router.forward() #前進一頁
this.$router.go(數字) #前進後退任意頁面
13 vue的生命周期
生命周期 就是 vue組件 從誕生到消亡整個過程
vue組件生命周期分為 四大階段 8個鉤子函數
鉤子函數:當達到這個階段 自動觸發的某個函數
可以在生命周期的鉤子函數中處理一些業務邏輯
所有的鉤子函數 都是和data() 平級
#第一大階段 create 創建階段
beforeCreate() #vue組件創建之前 組件中的任何資源都獲取不到 可以獲取到 Vue 頂級實例
created() #vue組件創建完成 可以獲取到 data()裡面的數據
#第二大階段 mount 掛載階段
beforeMount() # 掛載之前 可以獲取data() 獲取不到頁面的dom
mounted() # 掛載之後 可以獲取所有的 dom 節點
#第三大階段 update 更新階段
beforeUpdate() #更新之前
updated() #更新之後
#第四大階段 destroy 銷毀階段
beforeDestroy(){
#銷毀之前觸發
destroyed() #銷毀之後觸發
14 vue組件通信
組件與組件之間的數據傳遞
-
父傳 子
-
子傳 父
-
狀態管理vuex
-
中央事件匯流排 $bus (不使用)
-
相關 本地存儲 和頁面帶參傳值
14.1 組件 父傳子 動態屬性+props
在父組件中將數據傳遞給子組件
子組件需要父組件的數據 做頁面的渲染
子組件props 接收到的數據 用法和 data中的數據用法完全一致
父組件
<子組件名 title="你好啊" :age="20"></子組件名>
子組件
通過props 接收後, 直接用 this.變數
使用
props:{
title:{
type:String,
default:'標題'
},
age:{
type:Number,
default:0
},
}
14.2組件 子傳父 $emit+自定義事件
父組件
<子組件 @自定義的事件類型名="執行函數名" > </子組件>
export default{
methods:{
執行函數名(獲取到的子組件的回傳參數){
//業務邏輯
}
}
}
子組件
methods:{
自定義的事件類型名(){
this.$emit("自定義的事件類型名",需要傳遞的數據)
}
}
14.3 中央事件匯流排 $bus
所有組件需要傳遞數據 都直接存到 $bus
其他的所有的組件 都可以直接找 $bus 獲取 數據
優點:無視層級傳數據
缺點:必須在同一個 頁面組件中,切換頁面後 $bus 就無法觸發事件
//main.js 整個程式的入口
Vue.prototype.$bus = new Vue() ; //中介 新的vue實例對象,專門存取數據 $emit
//向$bus寫入數據--存數據的組件
this.$bus.$emit('自定義的事件類型',數據)
//在組件中獲取值 --取數據的組件
//找到當前組件的 created()
created(){
this.$bus.$on('自定義的事件類型',data=>{
console.log(data) //獲取的數據
})
}
14.4 祖宗孫子傳值: provide+ inject
優:祖宗節點定義好數據,所有的孫子組件 都可以使用該數據 非常方便
缺:只能傳遞一個 固定值下去,沒有響應式(子組件修改了該數據,祖宗節點的數據並不會發生變化)
祖宗組件
// 祖宗註入依賴
provide: {
name: '你好呀',
},
// 祖宗註入依賴
provide() {
return {
name: "你好呀",
};
},
孫子組件
export default {
inject:['name'],
mounted(){
//可以獲取和使用
console.log(this.name);
//不能修改---報錯
this.name = '我是孫子組件'
}
}
14.5 中間商:父親組件帶動態屬性 $attrs $listeners
通過屬性傳值:可以快速實現 祖宗>孫子 孫子>祖宗【父親組件只是一個中間商 負責 轉發數據和轉發事件】
爺爺組件
<template>
<div>
我是爺爺組件
<button @click="title='我是爺爺組件的新數據'">點擊修改數據</button>
<hr />
<father :title="title" @change="getData"></father>
</div>
</template>
<script>
import Father from './components/AppFather.vue'
export default {
data() {
return {
title: "我是爺爺組件的數據",
};
},
methods:{
//根據自定義數據 獲取孫子組件的傳遞數據
getData(data){
console.log(data);
}
},
components: {
Father,
},
};
</script>
父親組件
父親組件 通過$attrs 將獲取到的上一層的數據 傳遞給 下一級
父親組件 通過 $listeners 將獲取到的自定義事件 傳遞給上一級 觸發
<template>
<div>
父親組件:
<hr>
<grand-son v-bind="$attrs" v-on="$listeners" ></grand-son>
</div>
</template>
<script>
import GrandSon from './GrandSon.vue'
export default {
components:{
GrandSon
}
}
</script>
孫子組件
<template>
<div>
我是孫子組件:
<p>{{ title }}</p>
<button @click="changeData">回傳數據給祖宗</button>
</div>
</template>
<script>
export default {
props: {
// 在爺爺組件中傳遞過來的屬性
title: {
type:String,
default:'標題'
},
},
methods:{
changeData(){
let data ={msg:"我是孫子組件回傳的數據"}
this.$emit('change',data)
}
},
15 vue插槽使用 slot
父組件把 html 代碼 傳給子組件
子組件預留 html代碼的位置 給父組件
15.1匿名插槽
子組件的slot標簽就是 預留給 父組件 傳html代碼的位置
#父組件
<子組件>
#寫入替換 slot插槽的html代碼
<html代碼>
</子組件>
#子組件
</div>
#子組件提前給父組件預留的位置 插槽
<slot></slot>
</div>
15.2具名插槽
如果同一個子組件中出現多個 插槽 必須使用具名插槽
如果是同一個子組件中出現兩個 插槽 可以一個匿名 一個具名
#父組件
<子組件>
<div slot="插槽名1">
</div>
<div slot="插槽名2">
</子組件>
#子組件
<div>
<slot name="插槽名1"></slot> 、
<slot name="插槽名2"> </slot>
<div>
15.3 作用域插槽
將子組件的數據 回傳給 父組件的插槽 部分的代碼進行使用
一般情況下:作用域插槽 都是基於 具名插槽進行操作
#父組件
<子組件>
<div slot="插槽名1" slot-socpe="scope">
{{scope.變數}}
</div>
<div slot="插槽名2">
</div>
</子組件>
#子組件
<div>
<slot name="插槽名1" :變數=“str”></slot> 、
<slot name="插槽名2"> </slot>
<div>
data(){
return {
str:'啦啦啦'
}
}
15.4 簡化語法 vue3 適用
#父組件
<子組件>
<div v-slot="插槽名1">
</div>
<div v-slot="插槽名2">
</div>
</子組件>
#父組件
<子組件>
<template #插槽名1>
<div> </div>
</template>
<div v-slot="插槽名2">
</div>
</子組件>
#父組件
<子組件>
<template #插槽名1="scope">
<div >
{{scope.變數}}
</div>
</template>
<div slot="插槽名2">
</div>
</子組件>
16 vuex狀態管理
vuex是一個程式裡面的狀態管理模式,它是集中式存儲所有組件的狀態的小倉庫,並且保持我們存儲的狀態以一種可以預測的方式發生變化
官網地址:https://vuex.vuejs.org/zh/
vuex周期圖
16.1 安裝 vuex
- 安裝vuex
進入項目,在命令行中輸入安裝指令,回車
yarn add [email protected] --save
//或
npm i [email protected] --save
- 創建vuex 的倉庫文件
src/store/index.js
在src路徑下創建store文件夾,然後創建index.js文件,文件內容如下:
import Vue from 'vue'
import Vuex from 'vuex'
//註冊插件
Vue.use(Vuex);
//根據vuex的store 生成實例對象
const store = new Vuex.Store({
//存數據的倉庫
state:{
name:'comentang'
},
//修改倉庫中數據的同步方法
mutations:{
},
//調用 同步方法 實現非同步修改倉庫中的數據
actions:{
}
})
//暴露生成的vuex實例
export default store;
- main.js 進行導入和掛載
import store from './store' //引入前面導出的store對象
Vue.config.productionTip = false;
new Vue({
router,
store, //將store 實例掛載到vue頂級實例對象上
render: h => h(App)
}).$mount('#app')
16.2 獲取 state 中的數據
state:{
name:"babybearcq"
}
- 直接通過實例對象層級查找
缺點:每次改變都需要使用該語句進行重新獲取,代碼太冗長
this.name = this.$store.state.name // babybearcq
- 通過 計算屬性 獲取值
優點:如果倉庫中的數據發生了變化,computed 會自動觸發,重新更新值
computed:{
nameData(){
return this.$store.state.name;
}
}
- 通過計算屬性 + 對象解構獲取
將mapState 對象解構出來直接放到 computed中
優點:使用簡便,推薦此方法
import {mapState} from 'vuex'
computed:{
...mapState(['name'])
}
16.3 mutations 修改數據的方法
- 在組件中直接修改
直接通過實例對象層級賦值
缺點:任何組件任何時候都可以修改這個數據,給數據維護帶來了不穩定性。
vuex官網頁非常明確的指出,修改vuex倉庫中的數據必須使用 vuex中定義的方法。
低版本的vuex 數據會修改成功 但是控制台會有報錯提示
this.$store.state.name = '新數據'
- 定義mutations的方法 修改數據
const store = new Vuex.Store({
//存數據的倉庫
state:{
name:'babybearcq'
},
//修改倉庫中數據的同步方法
mutations:{
changeName(state,newData){
state.name = newData
}
},
})
在組件中 調用該方法 實現修改數據
this.$store.commit('changeName',新數據)
methods+解構的方式 【推薦】
import { mapMutations } from 'vuex';
methods:{
// 註意,mapMutations是解構到methods裡面的,而不是計算屬性了
...mapMutations(['changeName']),
//使用方法和methods中的函數 一致。
// this.changeName(新數據) 修改數據
}
16.4 actions 非同步修改數據
定義actions 非同步操作中 通過上下文 調用同步方法 修改數據
//調用 同步方法 實現非同步修改倉庫中的數據
actions:{
//1s之後 通過上下文 調用同步方法修改數據
setAsyncData(context,newData){
return new Promise(resolve=>{
setTimeout(()=>{
context.commit('changeName',newData);
resolve();
},1000)
})
}
}
- 在組件中 調用該方法 實現修改數據
let res = await this.$store.dispatch('setAsyncData',this.title)
- methods+解構的方式 【推薦】
import { mapActions } from 'vuex';
methods:{
// 註意,mapActions是解構到methods裡面的,而不是計算屬性了
...mapActions(['setAsyncData']),
let res= await this.setAsyncData(this.title)
}
16.5 修飾器:Getters
獲取數據時 統一對該數據進行處理之後 再返回新數據
特點:必須要有return 返回新數據 ,調用時不需要傳參數
定義修飾器
getters:{
updateName(state){
return '你好呀'+state.name;
}
}
- 組件中直接使用 獲取數據
this.$store.getters.updateName
- 通過computed 解構函數使用
import {mapGetters} from 'vuex'
computed:{
...mapGetters(['updateName'])
},
created() {
//取值
this.updateName1 = this.updateName
}
16.6 模塊 Module
假設一個項目功能比較複雜,在vuex中存儲的數據非常多,設置出現了同名的情況,這種時候就不能直接寫到一個store 文件中了,應該根據不同的功能模塊 對 該store文件進行拆分。
思路:寫獨立的js文件 將 5個核心配置寫入一個對象 並 暴露出去,導入到總的store裡面的modules裡面
現有模塊: 用戶模塊users 商品模塊
src/store/index.js #總的vuex主模塊
src/store/users.js #用戶模塊
src/store/goods.js #商品模塊
主模塊 index
//index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 導入子模塊
import users from './users'
import goods from './goods'
//註冊插件
Vue.use(Vuex);
//根據vue的store 生成實例對象
const store = new Vuex.Store({
state: {
name: '我是主模塊的cometang'
},
mutations: {
},
actions: {
},
getters: {
},
//模塊
modules: {
users, goods
}
})
//暴露生成的vuex實例
export default store;
用戶模塊
const users = {
namespaced: true,
state: {
userName: '我是userjs的name'
},
mutations: {
},
actions: {
},
getters: {
}
}
export default users
商品模塊
const goods = {
namespaced: true,
state:{
goodsName:'我是goods的name'
},
mutations:{
},
actions:{
},
getters:{
}
}
export default goods
註意:使用了模塊化和命名空間之後對於子模塊中的數據,方法
的調用 不再建議使用 解構賦值快速複製的方式進行.
原因:本來命名空間打開就是為了區分各個不同的模塊,如果用解構的方式,可能會造成數據變數名 方法名重名使用的風險。
- 使用方式
//獲取數據
this.$store.state.users.userName;
//獲取Getters 修飾器的數據
this.$store.getters.users.userName;
//調用同步方法
this.$store.commit('模塊名/mutations的方法名',傳遞的數據)
// 調用非同步方法
this.$store.dispatch('模塊名/actions的方法名',傳遞的數據)
- 解構使用
特點:一個組件中 只能解構一個模塊的數據 和方法
import { mapState,mapMutations,mapActions,mapGetters } from 'vuex';
computed:{
...mapState('users',['userName']), //this.userName
...mapGetters('users',['newUserName']) //this.newUserName
},
methods:{
...mapMutations('users',['updateName']), //this.updateName(數據)
...mapActions('users',['asyncUpdateName'])//this.asyncUpdateName(數據)
},
16.7 vuex 持久化
- **插件 ** 數據持久化的插件
npm install vuex-persistedstate
或
yarn add vuex-persistedstate
//數據持久化插件導入
import persistedState from 'vuex-persistedstate'
//根據vue的store 生成實例對象
const store = new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
getters: {
},
//模塊
modules: {
},
plugins: [persistedState()] //添加插件
})
//暴露生成的vuex實例
export default store;
-
本地存儲
-
創建公共函數
utils/store.js
import { validatenull } from 'utils/validate';
import website from '@/config/website'; //
/**
* 存儲localStorage
*/
export const setStore = (params = {}) => {
let { name, content, type } = params;
name = keyName + name;
let obj = {
dataType: typeof content,
content: content,
type: type,
datetime: new Date().getTime(),
};
if (type) window.sessionStorage.setItem(name, JSON.stringify(obj));
else window.localStorage.setItem(name, JSON.stringify(obj));
};
/**
* 獲取localStorage
*/
export const getStore = (params = {}) => {
let { name, debug } = params;
name = keyName + name;
let obj = {},
content;
obj = window.sessionStorage.getItem(name);
if (validatenull(obj)) obj = window.localStorage.getItem(name);
if (validatenull(obj)) return;
try {
obj = JSON.parse(obj);
} catch {
return obj;
}
if (debug) {
return obj;
}
if (obj.dataType == 'string') {
content = obj.content;
} else if (obj.dataType == 'number') {
content = Number(obj.content);
} else if (obj.dataType == 'boolean') {
content = eval(obj.content);
} else if (obj.dataType == 'object') {
content = obj.content;
}
return content;
};
/**
* 刪除localStorage
*/
export const removeStore = (params = {}) => {
let { name, type } = params;
name = keyName + name;
if (type) {
window.sessionStorage.removeItem(name);
} else {
window.localStorage.removeItem(name);
}
};
/**
* 獲取全部localStorage
*/
export const getAllStore = (params = {}) => {
let list = [];
let { type } = params;
if (type) {
for (let i = 0; i <= window.sessionStorage.length; i++) {
list.push({
name: window.sessionStorage.key(i),
content: getStore({
name: window.sessionStorage.key(i),
type: 'session',
}),
});
}
} else {
for (let i = 0; i <= window.localStorage.length; i++) {
list.push({
name: window.localStorage.key(i),
content: getStore({
name: window.localStorage.key(i),
}),
});
}
}
return list;
};
/**
* 清空全部localStorage
*/
export const clearStore = (params = {}) => {
let { type } = params;
if (type) {
window.sessionStorage.clear();
} else {
window.localStorage.clear();
}
};
vuex 文件 store/index.js
import { setStore, getStore, removeStore } from 'utils/store';
const store = createStore({
state: {
//從本地獲取數據
language: getStore({ name: 'language' }) || 'zh-cn',
isLock: getStore({ name: 'isLock' }),
lockPasswd: getStore({ name: 'lockPasswd' }) || '',
},
mutations: {
setLanguage: (state, language) => {
state.language = language;
//改變後將數據存儲到本地
setStore({
name: 'language',
content: state.language,
});
},
setLockPasswd: (state, lockPasswd) => {
state.lockPasswd = lockPasswd;
setStore({
name: 'lockPasswd',
content: state.lockPasswd,
type: 'session',
});
},
clearLock: (state, data) => {
state.isLock = false;
state.lockPasswd = '';
//將使用過的數據 從本地清除
removeStore({
name: 'lockPasswd',
type: 'session',
});
},
},
});
export default store;
參考:https://www.gotang.cn/pages/658702/#%E5%89%8D%E8%A8%80