首页
壁纸
友链
留言
统计
个人导航
Search
1
一款超炫酷超好看的个人主页
890 阅读
2
网站顶部添加滚动文字
784 阅读
3
博客底部添加炫酷菜单栏
569 阅读
4
海南特产-鹧鸪茶
505 阅读
5
QQ和微信内置浏览器缓存清理
490 阅读
编程技术
Vue
JavaSe
Java
数据库
网站部署优化
typecho
超炫源码
超炫软件
实用技能
好东西
登录
Search
标签搜索
JavaSe
Vue
typecho
HTML标签
滚动文字
域名
申诉
表单校验
Nginx
java
HTML
flex布局
图片
服务器
登录框
组件传值
路由
缓存清理
鹧鸪茶
JavaScript
罗小黑
累计撰写
43
篇文章
累计收到
112
条评论
今日撰写
0
篇文章
首页
栏目
编程技术
Vue
JavaSe
Java
数据库
网站部署优化
typecho
超炫源码
超炫软件
实用技能
好东西
页面
壁纸
友链
留言
统计
个人导航
用户登录
登录
:欢迎您的到来! 如果您遇到任何问题,请联系博主qq:
180181332
搜索到
16
篇与
Vue
的结果
2022-04-25
http常见的返回状态码
http状态码分类:100-199 提示信息 – 表示请求正在处理200-299 成功 – 表示请求正常处理完毕300-399 重定向 – 要完成请求必须进行更进一步的处理400-499 客户端错误 – 请求有语法错误或请求无法实现500-599 服务器端错误 – 服务器处理请求出错常见的状态码有哪些?200:请求成功,浏览器会把响应体内容(通常是html)显示在浏览器中;404:(客户端问题)请求的资源没有找到 400: 语义有误,当前请求无法被服务器理解。401: 当前请求需要用户验证403: 服务器已经理解请求,但是拒绝执行它。500:(服务端问题)请求资源找到了,但服务器内部发生了不可预期的错误;301/302/303:(网站搬家了,跳转)重定向304: Not Modified,代表上次的文档已经被缓存了,还可以继续使用。如果你不想使用本地缓存可以用Ctrl+F5 强制刷新页面注意:状态码与实际情况不一致的情形不少返回的状态码都是错误的,但是用户可能察觉不到这点,比如web应用程序发送内部错误,状态码依然返回200 OK ,这种请求也会发生的。
2022年04月25日
16 阅读
0 评论
1 点赞
2022-03-25
uniapp开发微信小程序的坑
一、前言由于PC端的网站功能已经写的差不多了,一直想写个微信小程序和App将数据整合到一起。发现uniapp可以一套代码搞定微信小程序和App,于是我利用空闲时间边看文档边搞、搞了一个礼拜初步完成了第一版。由于微信小程序和App进行微信授权的流程是不一样的,我分开进行了区分,全部搞好。正想申请App微信授权认证的时候,微信认证居然要营业执照和300块钱。没钱、免费办理的营业执照也注销了、所以目前只上线了微信小程序(免费上线)。 PC端请点击此处访问 在线预览:二、开发遇到的问题1、首页首页没什么大问题,很简单的布局。使用组件和卡片式直接布局简单明了。2、文章详情使用mp-html组件解析md文档。这里图标的选择以及左右布局的大小对于强迫症的我纠结的比较久!3、聊天室这里最坑的就是scroll-view组件,将聊天记录渲染完后,要跳到底部。因此我给每个item加一个id值,用scroll-view来识别每次进入聊天室直接获取列表长度的值-1来跳到底部。想法虽然没问题,但是最终老是离底部有那么一点距离。折腾半天,一开始是以为高度不能设置成百分比,我直接改成具体高度。好家伙,布局直接乱了。经过多次反复测试,发现有那么一个高度,恰好能滑到最低部。心想每个手机的尺寸和高度肯定不一样,于是想着动态获取手机的可视高度减去底部tabbar的高度不就行了?问题直接解决。输入框问题,一开始想着设置textarea自适应高度,根据输入的字数自动调节高度,在自己手机上调试的没问题,但是在不同手机上的初始高度不一样,很不美观,其次是发送按钮没有给固定高度,父元素也没有高度,导致垂直居中不了(有会的吗?)。于是算了,我直接给输入框固定高度把。至少美观一点。突然想到,用户进入聊天室的时候,只需要返回最新的十条记录就行,用户上拉再继续请求数据。4、我的这里最纠结的就是背景颜色和图标的选择。选哪个都觉得不对劲。最后还有一个坑就是设置背景颜色的时候,高度设置100%不会生效,设置100vh才会生效。麻了。5、微信授权问题这里分为两种:微信小程序和App两种使用的是不同的微信授权流程微信小程序(这是我将微信授权存入后端数据库的流程,可能每个人的写法流程不一样):第一步:使用wx.getUserProfile获取微信的用户信息保存起来第二步:使用uni.login获取微信code,获取成功之后,将code和微信用户信息传入后端第三步:在后端接收到code和用户信息,将code和appid、secret拼接起来请求获取sessionkey和openid第四步,判断数据库中是否存在该用户,存在(从数据库中取),不存在(将获取的信息存入数据库)App:(要花钱)第一步:使用uni.login获取unionid和openid第二步:使用uni.getUserInfo获取用户昵称和头像信息,将这些数据发送到后端第三步:后端接收到数据,先进行判断是否存在用户,存在(从数据库中取),不存在(将获取的信息存入数据库)三、页面展示
2022年03月25日
319 阅读
2 评论
0 点赞
2021-11-30
vue-router 报错:Navigation cancelled from“/xxx“ to “/xxx“ with a new navigation
卸载3.0版本npm uninstall vue-router --save安装2.8版本npm install vue-router@2.8.0 -S
2021年11月30日
139 阅读
0 评论
0 点赞
2021-11-15
Vue权限控制管理
一、权限相关概念1.1 权限的分类后端权限 从根不上讲前端仅仅只是视图层的展示, 权限的核心是在于服务器中的数据变化,所以后端才是权限的关键,后端权限可以控制某个用户是否能够查询数据, 是否能够修改数据等操作。1.后端如何知道该请求是哪个用户发过来的 cookie session token2.后端的权限设计RBAC(后面再了解) 用户 角色 权限前端权限前端权限的控制本质上来说,就是控制端的视图层的展示和前端所发送的请求。但是只有前端权限控制没有后端权限控制是万万不可的。前端权限控制只可以说是达到锦上添花的效果。##### 1.2 前端权限的意义 如果仅从能够修改服务器中数据库中的数据层面上讲, 确实只在后端做控制就足够了, 那为什么越来越多的项目也进行了前端权限的控制, 主要有这几方面的好处。降低非法操作的可能性 不怕赃偷就怕贼惦记, 在页面中展示出一个就算点击了也最终会失败的按钮,势必会增加有心者非法操作的可能性。尽可能排除不必要清求, 减轻服务器压力 没必要的请求, 操作失败的清求, 不具备权限的清求, 应该压根就不需要发送, 请求少了, 自然也会减轻服务器的 压力。提高用户体验 根据用户具备的权限为该用户展现自己权限范围内的内容, 避免在界面上给用户带来困扰, 让用户专注于分内之事。### 二、前端权限的控制思路##### 2.1菜单(侧边栏)的控制在登录请求中,会得到权限数据,当然,这个需要后端返回数据的支持(我们也可以自己模拟数据),前端根据权限数据,展示对应的菜单,点击菜单,才能查看到相关的界面。##### 2.2界面的控制如果用户没有登录,手动在地址栏敲入管理界面的地址,则需要跳转到登录界面。如果用户已经登录,如果手动敲入非权限内的地址,则跳转不过去或者需要跳转到404界面。##### 2.3按钮的控制在某个菜单的界面中,还得根据权限数据,展示出可进行操作的按钮,比如删除,修改,增加。##### 2.4请求和响应的控制如果用户通过非常规操作,比如通过浏览器调试工具将某些禁用的按钮变成启用状态,此时发的请求,也应该被前端所拦截。### 三、实现步骤##### 3.1权限菜单栏控制在src文件夹下新建一个mock文件夹,在mock文件夹下面新建一个js文件,然后在控制台输入npm install mockjs安装mockjs模块,之后在main.js中导入mock文件。在mock文件下写一个模拟数据,分配两个账户,分别有各自的菜单列表和token。代码如下://使用Mock const Mock = require('mockjs') Mock.setup({ timeout: '500-1000' }) // 用户信息 const users = [ { id: 1, username: 'user', password: '123456', photo: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2667925509,1048662418&fm=11&gp=0.jpg', token: 'user-token', role: 'user', rights: [] }, { id: 2, username: 'admin', password: '123456', photo: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2364244149,3298797080&fm=26&gp=0.jpg', token: 'admin-token', role: 'admin', rights: [] } ] // 权限信息 将权限信息从用户信息中抽离出来 不同身份对应不同的路由信息 // 这样方便了后期的维护 否则以后每加一个页面就需要在每个用户信息中做更改 十分的不方便 如果用户多了更是增添了不必要的麻烦 // 将用户直接分为不同身份 然后对不同身份做处理 这样比较合理 const roles = { user: [ { id: 1, authName: '评估管理', icon: 'el-icon-connection', children: [ { id: 11, authName: '估价师', icon: 'el-icon-s-grid', path: 'appraiser', rights: ['view'] }, { id: 12, authName: '估价师库', icon: 'el-icon-s-marketing', path: 'appraiserLibrary', rights: ['view'] } ] } ], admin: [ { id: 1, authName: '评估管理', icon: 'el-icon-connection', children: [ { id: 11, authName: '估价师', icon: 'el-icon-s-grid', path: 'appraiser', rights: ['view', 'edit', 'add', 'delete'] }, { id: 12, authName: '估价师库', icon: 'el-icon-s-marketing', path: 'appraiserLibrary', rights: ['view', 'edit', 'add', 'delete'] } ] }, { id: 2, authName: '项目管理', icon: 'el-icon-set-up', children: [ { id: 21, authName: '项目登记', icon: 'el-icon-s-custom', path: 'ProjectRegistration', rights: ['view', 'edit', 'add', 'delete'] }, { id: 22, authName: '项目查询', icon: 'el-icon-s-custom', path: 'ProjectQuery', rights: ['view', 'edit', 'add', 'delete'] } ] } ] } // 用户登录 Mock.mock('/login', 'post', option => { const { username, password } = JSON.parse(option.body) const user = users.find(item => { return item.username === username && item.password === password }) return user }) // 用户权限信息 Mock.mock('/roles', 'post', option => { return roles[option.body] })然后我们把这个数据存放在vuex中,然后主页根据vuex中的数据进行菜单列表的渲染。问题:刷新界面vuex数据消失,菜单栏消失。解决:将数据存储在sessionStorage中,并让其和vuex中的数据保持同步。vuex的代码如下:import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { role: sessionStorage.getItem('role'), rightList: JSON.parse(sessionStorage.getItem('rightList') || '[]'),//防止刷新侧边栏数据消失 username: sessionStorage.getItem('username'), photo: sessionStorage.getItem('photo') }, mutations: { setRole (state, data) { state.role = data sessionStorage.setItem('role', data) }, setRightList (state, data) { state.rightList = data sessionStorage.setItem('rightList', JSON.stringify(data)) }, setUsername (state, data) { state.username = data sessionStorage.setItem('username', data) }, setPhoto (state, data) { state.photo = data sessionStorage.setItem('photo', data) } }, actions: {}, getters: {} })将mock里面的数据存入vuex后,我们需要在Login.vue的登录按钮事件中设置点击登录后将数据传入我们登录后的页面中。此时我们在登录按钮的事件中这样写:submitForm(form) { this.$refs[form].validate((valid) => { if (valid) { this.loading = true login(this.form).then(res => { // console.log(res, 'login=>res') // 将用户身份存入vuex 普通用户身份: user 管理员用户身份: admin this.$store.commit('setRole', res.data.role) this.$store.commit('setUsername', res.data.username) this.$store.commit('setPhoto', res.data.photo) sessionStorage.setItem('token', res.data.token) getRoles(res.data.role).then(ret => { // console.log(ret.data, 'getRoles=>ret.data') // 将对应身份下的路由存储到vuex this.$store.commit('setRightList', ret.data) this.loading = false this.$message.success('登陆成功') // 根据用户所具备的权限 动态添加路由规则 initDynamicRoutes() this.$router.push('/frame') }) }) } else { this.$message.error('用户名或密码错误'); return false; } }); },传入框架页面之后,我们需要在frame(框架页面遍历侧边栏的菜单数据数组,使其显示对应用户的菜单列表),先导入相应的数据,<script> import { mapState } from 'vuex' import {initDynamicRoutes} from "@/router"; export default {computed: { ...mapState(['rightList']),//侧边栏数据 ...mapState(['username']), // 用户名 ...mapState(['photo']) // 用户头像 //三个可以写在一起! }, created () { // 初始化menulist菜单栏的数据 // this.menulist = this.rightList initDynamicRoutes() this.menuList = this.rightList },这样的话rightList数组数据就传给menuList,此时我们只需要将menuList遍历出来到侧边栏中就可以了。<!-- 动态路由 --> <!-- 一级菜单 --> <el-submenu :index="item.id+''" v-for="item in menuList" :key="item.index" > <template slot="title"> <span>{{item.authName}}</span> </template> <!--二级菜单--> <el-menu-item :index="'/'+subItem.path" v-for="subItem in item.children" :key="subItem.index" > <template > <i :class="subItem.icon"></i> <span>{{subItem.authName}}</span> </template> </el-menu-item> </el-submenu>3.2 界面的控制登录成功后,将token数据存储在sessionStorage中,判断是否登录。1.路由导航守卫// 路由导航守卫 router.beforeEach((to, from, next) => { if (to.path === '/Login') { next() } else { const token = sessionStorage.getItem('token') if (!token) { next('/Login') } else { next() } } })问题:这样用户在登录之后就可以访问其他界面了,但如果用户A登录之后他只能访问a页面,他不能访问b页面,但是这时候他还是可以通过地址栏输入进入到b页面。解决:当然我们也可以设置路由导航守卫,但是如果有多个页面,设置会非常不方便,并且对于用户A来说,她是不用访问b页面的,这时候我们干嘛不设置登录A用户时只显示A用户所要显示的路由呢,这时候我们用到动态路由。2.动态路由根据当前用户所拥有的权限数据动态添加所需要的路由。1.先定义好所有的路由规则//动态路由 const ProjectQueryRule={ path: '/ProjectQuery', name:'ProjectQuery', component:()=>import('@/views/projectManagement/ProjectQuery'), } const ProjectRegistrationRule={ path: '/ProjectRegistration', name:'ProjectRegistration', component:()=>import('@/views/projectManagement/ProjectRegistration'), } const appraiserRule={ path: '/appraiser', name:'appraiser', component:()=>import('@/views/evaluateManagement/appraiser'), } const appraiserLibraryRule={ path: '/appraiserLibrary', name:'appraiserLibrary', component:()=>import('@/views/evaluateManagement/appraiserLibrary'), } /** * eslint报错 * error Unnecessarily quoted property 'xxx' found quote-props * 表示 key没必要加引号 'table': tableRule => table: tableRule */ // 路由规则和字符串的映射关系 const ruleMapping = { ProjectQuery: ProjectQueryRule, ProjectRegistration: ProjectRegistrationRule, appraiser: appraiserRule, appraiserLibrary:appraiserLibraryRule }2.登录之后动态添加路由,注意这个initDynamicsRoutes的方法需要暴露出去在登录页面调用。export function initDynamicRoutes () { // console.log(router) // 根据二级权限 对路由规则进行动态的添加 const currentRoutes = router.options.routes //console.log(currentRoutes) // currentRoutes[2].children.push() const rightList = store.state.rightList // console.log(rightList) rightList.forEach(item => { // 如果是没有子路由的话 就直接添加进去 如果有子路由的话就进入二级权限遍历 // console.log(item, 'item-1') if (item.path) { const temp = ruleMapping[item.path] // 路由规则中添加元数据meta temp.meta = item.rights currentRoutes[1].children.push(temp) } item.children.forEach(item => { // item 二级权限 // console.log(item, 'item-2') const temp = ruleMapping[item.path] // 路由规则中添加元数据meta temp.meta = item.rights //console.log(temp.meta) currentRoutes[2].children.push(temp) }) }) console.log(currentRoutes) router.addRoutes(currentRoutes) }这样当用户A在地址栏输入自己不能访问的路由时,则不会跳转到该页面,跳转到空白页面或者404页面。问题:如果我们重新刷新的话动态路由就会消失,动态路由是在登录成功后才会调用的,刷新的时候并没有调用,所以动态路由没有添加上。解决:可以在app.vue(框架页面)中created中调用添加动态路由的方法created(){ initDynamicRoutes() }3.3按钮的控制虽然用户可以看到对应的界面了,但是这个界面的一些按钮该用户可能没有权限。因此,我们需要对组件中的一些按钮进行控制,用户不具备权限的按钮就隐藏或者禁用,而在这块的实现中,可以把该逻辑放到自定义指令中。这时我们需要根据我们mock设置的right属性来判断用户有什么权限。添加自定义指令控制按钮<!--如果添加估价师这个按钮有添加的权限,那就显示这个按钮,如果没有添加的权限,那就隐藏这个按钮。--> <el-button type="primary" @click="addAppraiser()" v-permission="{action:'add'}">添加估价师</el-button> <!--如果编辑这个按钮有添加的权限,那就显示这个按钮并且能点击,如果没有添加的权限,那就禁用这个按钮。--> <el-button type="primary" size="mini" @click="handleEditBtn(row)" v-permission="{action:'add',effect:'disabled'}">编辑</el-button> 这样设置之后还不能实现效果,我们需要给这个设置对应的指令。在util文件夹下新建permission.js文件,在里面设置我们这个自定义指令// 自定义指令的注册 import Vue from 'vue' import router from '@/router' Vue.directive('permission', { inserted (el, binding) { // console.log(el) // console.log(binding) const action = binding.value.action const effect = binding.value.effect // 判断 当前的路由所对应的组件中 如何判断用户是否具备action的权限 console.log(router.currentRoute.meta, '按钮权限') if (router.currentRoute.meta.indexOf(action) === -1) { // 等于-1说明没找到 不具备权限 if (effect === 'disabled') { el.disabled = true el.classList.add('is-disabled') } else { el.parentNode.removeChild(el) } } } })这个按钮权限是通过meta属性传入的。item.children.forEach(item => { // item 二级权限 // console.log(item, 'item-2') const temp = ruleMapping[item.path] // 路由规则中添加元数据meta temp.meta = item.rights //console.log(temp.meta) currentRoutes[2].children.push(temp) })设置完之后我们需要在main.js中导入import './utils/permission.js'3.4 请求和响应的控制请求控制除了登录请求都要带上token,这样服务器才可以鉴别我们的身份。此时我们需要用到axios的请求拦截设置在util文件夹上新建request.js文件,加入以下代码// 请求拦截器 request.interceptors.request.use(req => { // console.log(req.url) // console.log(req.method) if (req.url !== '/login' && req.url !== '/roles') { // 不是登录的请求 也不是获取权限的请求 则在请求头中加入token 不知道如何使用Mock来验证请求头中的token 故此处注释 // req.headers.Authorization = sessionStorage.getItem('token') const action = actionMapping[req.method] // 判断非权限范围内的请求 // console.log(router) const currentRight = router.currentRoute.meta // console.log(currentRight) if (currentRight && currentRight.indexOf(action) === -1) { // 没有权限 alert('没有权限') return Promise.reject(new Error('没有权限')) } } return req })如果发出了非权限内的请求,应该直接在前端范围内阻止,虽然这个请求发到服务器也会被拒绝。非权限内的请求:比如A用户是不能够操作该页面的按钮的,但是他通过f12调试把按钮改为可点击,如果我们不对这个请求进行处理,那么这个请求就会发送出去。如果我们得到了服务器返回的状态码为401,代表token超时或者被篡改了,此时应该强制跳转到登录界面。request.js的完整代码如下。import axios from 'axios' import router from '@/router' const request = axios.create() // 映射 const actionMapping = { get: 'view', post: 'add', put: 'edit', delete: 'delete' } // request.defaults.baseURL = 'http://127.0.0.1:7001' // 注释掉之后调的接口将是Mock数据 // 请求拦截器 request.interceptors.request.use(req => { // console.log(req.url) // console.log(req.method) if (req.url !== '/login' && req.url !== '/roles') { // 不是登录的请求 也不是获取权限的请求 则在请求头中加入token 不知道如何使用Mock来验证请求头中的token 故此处注释 // req.headers.Authorization = sessionStorage.getItem('token') const action = actionMapping[req.method] // 判断非权限范围内的请求 // console.log(router) const currentRight = router.currentRoute.meta // console.log(currentRight) if (currentRight && currentRight.indexOf(action) === -1) { // 没有权限 alert('没有权限') return Promise.reject(new Error('没有权限')) } } return req }) // 响应拦截器 request.interceptors.response.use(res => { // console.log(res) if (res.data.status === 401) { router.push('/login') sessionStorage.clear() window.location.reload() } return res }) export default request同时也别忘了在main.js中导入。四、小结前端权限的实现之后需要后端提供数据支持,否则无法实现。返回的权限数据的结构,前后端需要沟通协商怎样的数据用起来才最方便。4.1 菜单的控制权限的数据需要在多组件之间共享,因此采用Vuex防止刷新界面,权限数据丢失,所以需要存在sessionStorage中,并且要保证两者的同步。4.2 界面的控制路由的导航守卫可以防止跳过登录界面动态路由可以让不具备权限的路由规则压根就不存在4.3 按钮控制路由规则中可以增加路由元数据meta通过路由对象可以得到当前的路由规则以及存在此规则中的meta数据自定义指令可以很方便的实现按钮控制4.4 请求和响应的控制请求拦截器和响应拦截器的使用
2021年11月15日
184 阅读
0 评论
1 点赞
2021-11-09
Vue开发环境和生产环境的配置
配置文件.env.development:开发环境下的配置文件,执行npm run serve命令,会自动加载.env.development文件. .env.production:生产环境下的配置文件,执行npm run build命令,会自动加载.env.production文件 命名规则属性名必须以VUE_APP_开头 比如VUE_APP_BASE_API_D.env.development文件配置ENV = 'development' VUE_APP_BASE_API_D = 'http://134.111.111.111'.env.productio文件配置ENV = 'production' VUE_APP_BASE_API_D = 'http://112.5.112.112'使用axios封装创建第一步封装Apiimport axios from "axios"; const serveBaseApi=axios.create({ baseURL:process.env.VUE_APP_BASE_API_D,//process.env代表引用我们之前的文件配置。 timeout:3000 }) export default serveBaseApi;第二部封装Apiimport serveBaseApi from "@/api/serveApi/serveBaseApi"; export function development(query) { return serveBaseApi({ url:'shixishen/git-bash.png',//这里后缀都一样,则只需要封装一个。 methods:'get', params:query, }) }最后使用按钮请求数据<el-button @click="TestBtn">测试</el-button> import {development} from "@/api/serveApi/development"; TestBtn(){ console.log('不同环境',process.env.VUE_APP_BASE_API_D) development({ },).then(res=>{ console.log(res) }) } //这里导入封装的Api,我们运行开发环境和生产环境分别给的Api前缀不同,就是我们配置的env.development和env.production由于我们请求不到数据,所以报错,但是生产环境配置的Api和开发环境配的Api分别在两个运行环境下都成功实现。具体效果请实测!
2021年11月09日
160 阅读
1 评论
3 点赞
2021-11-08
JavaScript数据类型Null和Undefined的区别与联系
JavaScript数据类型Null和Undefined的区别与联系一、Undefined类型使用var关键字声明了变量、但还未对其初始化 (即未赋值)。可以理解为变量声明了之后,默认就会取得undefined值。Undefined类型只有一个值,即特殊的undefined。var solar ; // 这个变量声明之后默认取得了undefined值 // age 变量并没有声明 // var age; alert (solar); // "undefined" alert (age); // 会报错注意:对未初始化的变量执行 typeof 操作符会返回 undefined 值,对于未声明的变量执行 typeof 操作符同样也会同样返回 undefined 值。二、Null类型是一个只有一个值的数据类型,该值为null。null 类型表示的是一个空的对象( object ),也正是使用 typeof 操作符检测 null 值时,返回 “object” 的原因。如果定义的变量是准备在将来用于保存对象,那么最好将该变量初始化为 null,而不是其他值。主动释放一个变量引用的对象,表示一个变量不再指向任何对象地址var solar = null ; alert ( typeof solar ); // "object" if ( solar != null ){ alert ( null == undefined ); // true }注意:对于任何变量都没有必要对其初始化为 undefined,但 null 就可以,比如空指针,就可以初始化为 null,也就是说当一个变量准备用来保存对象时,就可以将其值初始化为 null。
2021年11月08日
121 阅读
0 评论
2 点赞
2021-10-21
Vuex(Store仓库)
Vuex(Store仓库)state:是一个全局的状态存储,数据会存储在其中,vue组件可以直接访问其中的值,但是只可以读,不可以进行写操作。getters:有些时候我们需要对获取的数据进行加工,获取数据的一部分或者某些属性,而不是直接获取state中的数据,这时候可以通过getter定义函数,返回对应数据。mutations:Vuex中唯一一个可以修改数据的地方,mutations可以定义事件函数,在Vue组件中可以通过commit发射事件,调用函数,需要注意的是,mutations中的操作必须是同步的,不存在异步操作的情况。actions:他和mutations比较相似,不同的是actions中不直接修改state,而是通过commit调用mutations修改数据,而且actions中可以存在异步处理逻辑。store/index.js中import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) //三目表达式,先判断有没有值,有值就转成对象,没值就创建一个。 const Store=new Vuex.Store({ //全局state对象,用于保存所有组件的公共数据。 state:sessionStorage.getItem('state')?JSON.parse(sessionStorage.getItem('state')):{ user:{ name:'', } }, //监听state对象的值的最新状态(计算属性) getters:{ getUser(state){ return state.user; } }, //唯一可以修改state值的方法(同步执行) mutations:{ updateUser(state,user){ state.user=user; } }, //异步执行mutations方法。 actions:{ asyncUpdateUser(conText,user){ conText.commit("updateUser",user); } } }) export default Store vuex在这里通过$store.getters.getUser.name输出内容到各个组件中getters:{ getUser(state){ return state.user; } }, 这里的state.user就是用getters指代了vuex中 this.$store.dispatch() 与 this.$store.commit()方法的区别 this.$store.dispatch()` 与 `this.$store.commit()`方法的区别总的来说他们只是存取方式的不同,两个方法都是传值给vuex的mutation改变state `this.$store.dispatch()` :含有异步操作,例如向后台提交数据,写法:`this.$store.dispatch(‘action方法名’,值)` `this.$store.commit()`:同步操作,,写法:`this.$store.commit(‘mutations方法名’,值)#### commit: 同步操作存储 this.$store.commit('changeValue',name)取值 this.$store.state.changeValue#### dispatch: 异步操作存储 this.$store.dispatch('getlists',name)取值 this.$store.getters.getlists
2021年10月21日
58 阅读
0 评论
1 点赞
1
2
3