vue2基础 入门vue2
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 中间商:父亲组件带动态属性 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;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】