最近也是完成了公司招聘管理系统后台的前端开发,项目已经开始测试了近期估计就会交付使用。一直是一个人在做,配合两个后端,说实话这种从很多不会到一个个独立debug解决问题到最后终于完成项目的感觉真的太有成就感了,看了一下项目开发日志写了一万多字了,现在回过头看之前踩过的坑其实都是一些很简单的错误,也是好笑当初怎么那么笨(准确来说其实是没怎么用过),特此记录一下,完成了第一个成熟的作品。
---------------------------------------------- 1.项目开始没多久的记录-----------------------------------------------
首先,我只能说这个真的不适合做二次开发,冗余的东西太多了。这里其作者推荐vue-element-template来做二次开发。暂且记录一下,以后也许会用。
介绍一下它的大致结构。
views里是视图上直接出现的组件
components大多是被views复用的子组件
store对应着vuex,
router对应vue-router
api对应vue-axios
layout是每个页面都存在的一些东西,比如侧边栏导航栏之类的。
permission.js做的权限路由,里面主要是两个导航守卫
style存全局css样式的地方。(这里要改一个element的table的bug,也就是windows上表头对不齐(mac没这个问题,,好像是因为饿了么团队用的都是mac。。。),百度查一下,添加进去就行了
utils里我写的是一些自己可能复用到的方法。用于其他地方调用
其中的auth.js,这个得自己改一改。这是认证用的,也就是读写删token的地方,原本是用了vue-cookies,感觉cookie不稳定,换成了localStorage,这个写法上其实区别不大。
于我司来说,token是用户登录时后端返回的,可以存在localstorage中,而role是必须要时刻请求的,不能缓存,毕竟如果一个普通用户也有token,它要是自己把localstorage里的role从普通用户改成了admin,这就会引起大麻烦。
所有的请求,请求头必须都带上token字段。
request.js, 这个其实是对axios请求的封装,配置一些相同的东西,比如
baseURL: '/api',
headers: {
'Content-Type': 'application/json'
}
说到api,就不得不说到跨域问题,我一直觉得跨域可能会很复杂,直到后来发现,也就是在webpack的config(如果是vue-cli3,那就是vue-config.js)里把代理配一下
proxy: {
'/api': {
target: 'http://10.18.92.121:8080',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
target是服务器的地址。
前端不能直接去对其他ip发起请求,但是如果你先发给本机的服务器(代理),再由本机的服务器去向后端请求,那就不存在跨域问题了。
经过我对开发者工具中network的查看,请求的ip依旧是本机的ip,这就代表这个代理,对于浏览器来说,其实是不可见的过程。
接下来是项目开发过程中随便记录的一些东西
在element的很多地方都可以用插槽slot,比如把原本只能是文字的地方加个图片啥的啦,不得不说,很神奇,(这个好像是vue的东西)
动态选择组件
is确定组件名
表单要放在table里,我的解决方案是
{{ scope.row.post }}
form和table嵌套,
关于element没有纵向表头的table,
我采用了el-row和el-col的方法手撸表格
总体评价
候选人优势
候选人不足
沟通能力
知识水平
经验积累
管理能力
聪明程度
候选人与应聘职位的契合度
是否愿意与候选人一起工作
是否建议增加面试
如不建议录用是否推荐到其他部门和其他职位
不录用
建议不录用
拿不准
建议录用
录用
用css通过加边框的形式解决。这里要注意边框重叠的部分颜色会加深,所以css要分开写。确保每条边只有一条线
接下来就是逻辑层,痛苦的debug过程。
组里的大哥教我怎么搞编译后的东西。
如果是css,就给element的标签加class,即使element的东西编译了,你还是能找到自己定义的类的位置。
如果是js,就给vue里的文件加debugger
据说webpack有source-map,源代码映射,以后看看怎么用。
在.vue文件里mapgetters,然后在create()钩子中查看这个值。后来console发现permission_routes没东西,也就是空数组
如果我没记错的话,vuex的this大概率会是store,而不是vue,这个看具体情况,很多时候,你会因为this指向问题出错。
然后就到了提交环节,大佬设置了eslint如果有warning不让我commit,,只好老老实实地把import后但是没用的函数给它去了。不过后面我学会了eslint-disable嘿嘿
再后来。我只要一登录就给我报了一连串的错误,比如data function没有return啦,
Property “type” must be accessed with "$data.type"
$或者_的变量不能怎样怎样啦。当时我以为真的是我的data()没写return,全局搜索了所有的data,发现都写了,,简直是蠢透了。
这个问题的根源我后来找到了(现在忘了当时怎么出错的了),但是那个根源为什么会导致这种错误,没想通。
再后来。又出现了重名路由的bug,也就是路由的name有一样的。呵,亏我找了半天name,也是发现,重名的那部分路由恰好全是管理员才有的路由。问题的根源是基础路由在添加管理员路由的时候,分别在vuex的user.js和permission各添加了一次,导致我的路由表数组里有两份一样管理员路由。这才导致了重名。
再往后,关于导航守卫,permission.js里设置了每次切换路由,都要执行这个函数,而我当时释放钩子的时候用的是next(’/’),原来这并不能释放钩子,真正只能是用next(),这直接造成了我一直循环报错,一直再login页面跳不出去。循环报错真的很可怕,,我的浏览器这个页面崩了又崩。还好chrome每个页面都是独立进程,,起码浏览器还活着。
< transition > 标签用于跟踪过渡。可以定义相关的css样式。
未出现在侧边栏的,在vue devtool中看都是没有meta(icon,title)的,不想出现在侧边栏的路由都定义了hidden属性,如404。
展开运算符也能用于对象。
左侧少了view的module中只有一个index.vue的,通过对不同嵌套层中添加111,能查出v-if哪里没放进去。出现在页面上,又看不见,可能是宽度为0;
最后找到了问题,< app-link >要加插槽slot,不然里面放不了子组件
发请求遇到converting circularstructure to JSON的报错,是参数错误。
get请求的参数会直接在url里显示。
axios,我传对象或者json,都能正确运行,但是原意是想让我传对象
user module里的state,要访问时应用 state.user.xx
namespaced:true,命名空间打开的话,dispatch时要用 ‘post/getList’,跟上模块名。
对于undefined的属性,get请求的参数不会它放进去。
没有执行回调then,一开始以为时自己写的alert打断了异步操作,后来发现是忘了加resolve,reject传出去。
覆盖element的类,css必须要去掉scope,才能作用到外面的,要注意不要污染全局css,如果只是想修改某个el-input,可以在其外层加一个div class=“xx“, 然后用子代选择器选出来。 .xx > .el_input
或者 .xx .el_input
微信小程序,看似用的是wxml之类的,但是底层和html并无关系,是原生的东西。
pc端可以是px,而移动端一定是rem。
min-width大法好,配合百分比挺好的。
document.querySelector
用css选择器来选择,不支持伪类,只匹配第一个
document.querySelectorAll()匹配全部
关于跨域问题
axios请求不携带cookie
this.axios.defaults.withCredentials = true;// 跨域携带cookie
在跨域的情况下不仅前端要设置withCredentials,后端也是要设置Access-Control-Allow-Credentials的。
无法在一个请求中同时发 文件加json数据 ,最后改成发formData。
无法阻止element文件默认上传行为,auto-upload改为false即可
TypeError: Failed to execute ‘append’ on ‘FormData’: parameter 2 is not of type ‘Blob’.
formData在append时出现问题
单独报错null,一脸懵逼,发现是catch到错误,自己console.error出来的
转时间格式 把获取到的date直接作为参数放到new Date(),能自己识别。
date.toLocaleDateString()
“2019/7/30”
replace(’/’, ‘-’)失败,只替换了一个,应该是replace(///g, ‘-’),不要偷懒。。
element上传的属性multiply啥意思???
tinymce.min.js去不掉,发现是项目之前引入的文件,全局搜索这个文件名然后删除
流程中返回了面试信息intervInfos,但是一个格子没办法显示这么多东西。解决方案两种
一:采用展开行
二:先缓存下来,到时候要查看面试信息的时候,展示出来
子组件和父组件不要用一样的函数名之类的,会冲突
methods和computed的方法不能互相调用eg:methods只能调methods的方法
所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算
更新状态的接口只设计了单个id,而多选的话会是一个数组,解决方案是多次调用接口,一次更新一个id
下拉框内选项点击事件,需要加native,否则无法触发,(写自己原生的事件)
不同于组件和 prop,事件名不存在任何自动化的大小写转换。
不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或属性名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。
因此,我们推荐你始终使用 kebab-case 的事件名。
.syn 用于子组件传递里面值的改动到父组件,
当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bind 配合使用:
git commit提交被eslint检测出双等,故意为之,不想改。
解决方法:
1、git commit --no-verify -m “commit” 就可以跳过代码检查
2、注释eslint-disable
3、.eslintignore文件添加
4、直接取消eslint关于严格等于的检查
内容分发网络(Content delivery network或Content distribution network,缩写:CDN)是指一种通过互联网互相连接的电脑网络系统,利用最靠近每位用户的服务器,更快、更可靠地将音乐、图片、视频、应用程序及其他文件发送给用户,来提供高性能、可扩展性及低成本的网络内容传递给用户。
为什么需要CDN
根本上的原因是,访问速度对互联网应用的用户体验、口碑、甚至说直接的营收都有巨大的影响,任何的企业都渴望自己站点有更快的访问速度。而HTTP传输时延对web的访问速度的影响很大,在绝大多数情况下是起决定性作用的,这是由TCP/IP协议的一些特点决定的。物理层上的原因是光速有限、信道有限,协议上的原因有丢包、慢启动、拥塞控制等。
要提高访问速度,最简单的做法当然就是多设置几个服务器,让终端用户离服务器“更近”。典型的例子是各类下载网站在不同地域不同运营商设置镜像站,或者是像Google那样设置多个数据中心。但是多设几个服务器的问题也不少,一是多地部署时的困难,二是一致性没法保障,三则是管理困难、成本很高。实际上,在排除多地容灾等特殊需求的情况下,对大多数公司这种做法是不太可取的。当然,这种方案真正做好了,甚至是比后续所说的使用CDN要好的。
CDN是一种公共服务,他本身有很多台位于不同地域、接入不同运营商的服务器,而所谓的使用CDN实质上就是让CDN作为网站的门面,用户访问到的是CDN服务器,而不是直接访问到网站。由于CDN内部对TCP的优化、对静态资源的缓存、预取,加上用户访问CDN时,会被智能地分配到最近的节点,降低大量延迟,让访问速度可以得到很大提升。
cdn import注释掉还是报错,原因是webpack打包的时候似乎注释会被理解成别的含义,所以这里直接删除这几段话
父组件直接访问子组件 用ref。由于我这里是for,
第一次尝试ref="‘tabPane-’ + item.label"失败
看文档后发现直接用ref="tabPane"就好,会是一个数组,结果好像和预期的不太一样
因为v-if过了,所以只会有一个,这样解释就通了。
发现ch_tabPane.multipleSelection为undefined。其实还是一个数组,只是只有一个元素。要用[0]
规避错误方法,如果不存vuex并不是一定要dispatch action,可以在vue中直接调用api。
v-loading用于加载转圈的动画
更新状态后表格内容不变,估计是直接用了缓存数据,选择去除 created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。 路由传参 没办法对评价获取当前行的信息,采用scope 可以对data直接赋值即调用函数,目前不清楚data和created先后顺序 vscode正则表达式替换。 其中分组不是\2 而是$2 label改成中文以后,突然所有的单选框都被选中了 git revert 和 git reset的区别 事件处理。 // e.target 是你当前点击的元素 如果是要获取的数据,data里初始化的时候直接[]或者{}, get不用管content-type。亲测没区别,毕竟不传data 可以看到,Promise.prototype.done和Promise.prototype.finally存在两点不同: done并不返回promise对象,也就是说,在done之后不能使用then,catch等方法组成方法链。 用户设置: 这种方式进行的设置,会应用于该用户打开的所有工程; Unknown configuration setting: 把eslint插件禁用了 找了半天,我说为啥不能保存后自动格式化了,原来这个/* eslint-disable /对后面的代码生效, 正确做法 针对某一行 可以跟规则 在 Vue 中,父子组件的关系可以总结为 props down、events up。 .native也不是想加就加的,个人猜测可能参数不能是row这种原生js没有的东西 对象要forEach的话必须先用Object.keys()转化成数组 更改配置文件必须重新yarn run dev upload上传文件失败,原因是文件并未保存在fileList中,里面只是个索引。应该重写方法http-request(param),覆盖默认上传行为,data中保存param.file。文件类型(binary) 将/重定向到/login,发现栈溢出,原因是在permission.js中 通过在login.vue中设置watch r o u t e 来 监 听 路 由 变 化 , 然 后 登 录 直 接 跳 到 t h i s . r e d i r e c t ( = = = r o u t e . q u e r y . r e d i r e c t , 这 个 r o u t e 应 该 是 route来监听路由变化,然后登录直接跳到this.redirect( === route.query.redirect,这个route应该是 route来监听路由变化,然后登录直接跳到this.redirect(===route.query.redirect,这个route应该是route的新值) 全局搜索有点问题,并不是只要有就能搜到,亲测我的user.js中的log的内容就没搜到 7.8 .set-min-width .el-dialog { @chuangxin.com 本来想写在input里面,但是看编译后的html是封闭结构,所以除非直接造一个新的 @import ‘@/styles/mycss.css’;无法引入 取字符串的三个函数:slice(start,[end]),substring(start,[end])和substr(start,[length]) 写了一个bug,由于直接复用了添加和更新,导致更新完以后添加,this.temp已经有值了,所以应该在每次添加之前都先this.temp = {} 好像不能直接在vue的模板里调用引入的函数,决定采用computed,【未解决】 裁剪出现问题,由于使用的是splice,每次弹框都会裁剪一次,导致userName越来越小,解决方案为indexOf(’@’)找不到的时候返回-1改成当前字符串长度 把另一个对象的部分属性赋值给另一个对象 校验错误依旧提交,因为没有调用方法 确定了,axios方法中,data本应该给的是对象,但是实测json字符串好像也没事 以后可以直接使用transformResponse先把response.data返回出来 // // // // ‘proxy’ 定义代理服务器的主机名称和端口 他对element的分页进行了二次封装,个人觉得没必要 this. r e f s r e f 引 用 的 是 元 素 和 子 组 件 。 全 局 注 册 , 所 以 不 要 重 名 t h i s . refs ref 引用的是元素和子组件。全局注册,所以不要重名 this. refsref引用的是元素和子组件。全局注册,所以不要重名this.refs为空??? Value below was evaluated just now. Dialog 的内容是懒渲染的,即在第一次被打开之前,传入的默认 slot 不会被渲染到 DOM 上。因此,如果需要执行 DOM 操作,或通过 ref 获取相应组件,请在 open 事件回调中进行。 Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “rules” (出现新的问题),mutate改变。这个warning个人感觉无所谓,于是发生了大问题 1,在生命周期 mounted 之前的钩子函数中去调用会获取不到,原因是DOM节点都没有生成。 resetFields 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 — 在opened中调clearValidate,会在动画加载完才消除校验结果 新增用户的时候,关闭窗口之前突然给我的userName增加了@chuangxin.com,忘了data一旦变动就会触发重新渲染 post模块出现问题,修改了以后即使不提交,也因为更改了data而产生了假的数据变动。 职位创建时如果先点过更新,需要resetFields W3C 标准中有如下规定: When there is only one single-line text input field in a form, the user agent should accept Enter in that field as a request to submit the form. 即:当一个 form 元素中只有一个输入框时,在该输入框中按下回车应提交该表单。如果希望阻止这一默认行为,可以在 标签上添加 @submit.native.prevent。 this.$nextTick啦,这个回调函数的意思呢,其实简单理解就是等所有的DOM元素节点都渲染完成以后才执行其里面的方法。 resetFields出现问题,会把值置为初始值,而这个初始值却是第一次打开的时候赋予的值,不解决这个bug,甚至会影响update时reset的值 个人最简单的解决方案,每次打开对话框的时候直接先赋值一次,这样也就解决了表单的数据修改以后temp存了值的问题。而校验还是在open里做就行 Duplicate keys detected: ‘后端-AI工程院-北京’. 把tabPane子组件的total传出来,我用的是emit/on机制 window.alert(‘尚未开发’)。这条语句无法直接作为表达式执行,因为及不认识window,也不认识alert 前端该如何对文件做必选校验? blob binary large object),二进制大对象 下载简历 管理员权限的路由user出了bug,发现会自动再permission.js中通过if(to.path === ‘/login’)的判断,很迷,于是才next(’/profileStep’) 终于找到了跳转不来user页面的原因,路由的index.js是export了路由表,而之前的路由表没有asyncRoutes。所以造成无法跳转的情况 logout从profileStep登出没反应,从别的登出会跳到profileStep,大概知道为什么了。其实不是没反应而是跳到login。如果令牌还在的话,其实是会跳回profileStep的。这个应该和异步操作有关,dispatch应该是异步的,先把后面的路由push执行了,导致token还没移除 本模块的commit只能调自己的,不能调别人的mutation user.js中关于commit兄弟模块的mutation。 在带命名空间的模块内访问全局内容(Global Assets) 若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。 模板渲染, h()函数第二个参数,不知道怎么加element组件的属性。。。 出bug了,一旦刷新,admin路由也会变成common,原因是存在store的role被刷新没了 x=document.forms[“myForm”][“email”].value;要用[email]的方式,前提是input外层是表单,而且name=email, this.$store.state.user.userName,模块化的话要加模块名的 加解密 加密btoa解密atob,密码之类的放在前端是不安全的 match返回的其实是数组,第一项是匹配的字串 怎么在别的vue文件调用该vue文件的methods if (response.data.statusCode === 1) {失败
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作
this. r o u t e r . p u s h ( n a m e : ′ E v a l u a t e ′ , p a r a m s : i d : t h i s . i d ) t h i s . router.push({ name: 'Evaluate', params: { id: this.id } }) this. router.push(name:′Evaluate′,params:id:this.id)this.route.params.id
与 “{row}” ,是scope.row的解构赋值
:label="(\d)">(.*)<
:label="$2">$2<
已知不是中文的问题,发现问题,label不应该加冒号绑定。
想获得当前点击的元素,handleCheck(event) ,event.target就是目标元素
还可以直接传参数进来,这样可能方便一些
或者传$event,个人理解是如果传了参数(也就是@click= 内联形式),就要写成这种形式,访问原始的 DOM 事件
// e.currentTarget 是你绑定事件的元素
所以最好用currentTarget,,稳定
done中发送的异常会被直接抛给外部,也就是说,其不会进行Promise的错误处理(Error Handling)
/ eslint-disable /
…
/ eslint-enable */
// eslint-disable-line
// eslint-disable-next-line
/* eslint-disable no-alert */
// eslint-disable-line no-alert, quotes, semi
父子组件通信:父组件通过 props 向下传递数据给子组件
子父组件通信:子组件通过 events 给父组件发送消息
使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件
非父子组件通信:使用一个空的 Vue 实例作为中央事件总线
设计了如果要访问/login就会跳到/,然后就一直在跳
登录进行校验,锁定用户名为chuangxin.com
无法获取用户名,input::placeholder的颜色
尝试使用sass变量获取值,似乎只能赋一个确定的值
min-width: 400px;
}
选择在main.js的入口文件,引入样式
相关属性:
slice()
第一个参数代表开始位置,第二个参数代表结束位置的下一个位置,截取出来的字符串的长度为第二个参数与第一个参数之间的差;若参数值为负数,则将该值加上字符串长度后转为正值;若第一个参数等于大于第二个参数,则返回空字符串.
substring()
第一个参数代表开始位置,第二个参数代表结束位置的下一个位置;若参数值为负数,则将该值转为0;两个参数中,取较小值作为开始位置,截取出来的字符串的长度为较大值与较小值之间的差.
substr()
第一个参数代表开始位置,第二个参数代表截取的长度
PS:字符串都从0开始计起
字符串的不可变性,只能赋值不能直接裁剪transformRequest: [function (data) {
// 对 data 进行任意转换处
return data;
}],
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
data
是作为请求主体被发送的数据
// 只适用于这些请求方法 ‘PUT’, ‘POST’, 和 ‘PATCH’
// 在没有设置 transformRequest
时,必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属:FormData, File, Blob
// - Node 专属: Stream
也许是因为这里可以是string的原因onUploadProgress
允许为上传处理进度事件
onUploadProgress: function (progressEvent) {
// 对原生进度事件的处理
},onDownloadProgress
允许为下载处理进度事件
onDownloadProgress: function (progressEvent) {
// 对原生进度事件的处理
},
猜测这个可用于进度条的显示
// auth
表示 HTTP 基础验证应当用于连接代理,并提供凭据
// 这将会设置一个 Proxy-Authorization
头,覆写掉已有的通过使用 header
设置的自定义 Proxy-Authorization
头。
proxy: {
host: ‘127.0.0.1’,
port: 9000,
auth: : {
username: ‘mikeymike’,
password: ‘rapunz3l’
}
},
这个是否可用于跨域? 是否可以不需要再vue.config.js中定义代理?
猜测是刚触发事件函数已经执行完了,但是dom节点还没生成,解决方法是提前生成dom节点(v-show)
不过查阅element文档找到了更好的解决方案
@open=”“
发现open的时候无效,改为opened成功
我一修改值,结果重新渲染了,直接回到了之前的rules,
可能还是得data或者computed中弄这个rules
所以选择了两套rules,然后分开create_rules和update_rules,在methods中对rules赋值。
出现问题,dialog似乎复用了之前的,在update中,不需要校验的部分也弹出红字
需要调用reset’F’i
2 ,this.refs的组件在v-if为false的父节点下,导致这个子组件未渲染,所以获取不到。
总结:一定是组件已经渲染成功才能调用组件的数据。而不是页面加载完成后就一定能获取到
clearValidate 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果 Function(props: array | string)
这里用clearValidate就行了,毕竟每次都会先赋值
不应该对data修改也就是this.temp,而是先let temp = this.temp,然后去修改其中的属性。
发现他会把我的let变为const,记起了即使是const,也是可以修改对象里的某个属性的,只要不对他重新赋值
又犯了一个错误,这个temp和this.temp其实还是引用,,,指向同一个对象
两种方法
JSON转两次,
Object.assign(target, source)将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
应该多写逻辑,若取消则数据不变
或者更好的做法是,temp先把row中的数据取出来,不要直接this.temp = row,一定要深拷贝!!!
在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
给下一个遇到这个问题的人,这个问题的本质是因为你编辑时,第一次打开dialog的时候给表单绑定的model赋值了,这时候这个model的初始值就变成了你所赋值的值,所以resetFields的时候,会将model对应的每个值重置到初始值,这时候的初始值就是你编辑时赋值的那个值,而不是在data里声明的初始值,解决方式是,等dialog已经初始化mounted之后再给model赋值,也就是
this.$nextTick(() => { // 这里开始赋值 this.model.xxx = xxx; })
v-if直接销毁这种也可以
解决方案v-for="(item, index) in items"用index当key
当将responseType设置为一个特定的类型时,你需要确保服务器所返回的类型和你所设置的返回值类型是兼容的。那么如果两者类型不兼容呢?恭喜你,你会发现服务器返回的数据变成了null,即使服务器返回了数据。
发现是redirectfrom中有user,说明是从user跳到/的,估计是*通配符在前面先匹配了这项
【理解错误】其实是因为忘了移除token,事实证明不用async和await也一样
使用第三参数{root: true}
报错unknown mutation type
识别不来?
如果你希望使用全局 state 和 getter,rootState 和 rootGetter 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。
问题解决了,要先加上模块名 commit(‘permission/REMOVE_ROUTES’, null, { root: true })
事实证明如果我不用form的话,我可以不要name,直接getElementById().value也是可以的
获取文件名
const fileName = headers[‘content-disposition’].match(/(?<=fileName=.*___).+(?=;filename)/)[0]
response与实际返回的不同,断点执行完才会到statusCode=1
修改判断方法data.type === ‘application/json’ 如果有文件会是"text/xml"