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 vuex@3.6.2 --save
//或
npm i vuex@3.6.2 --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