vue-element-admin的二次开发

柯升
2023-12-01

最近也是完成了公司招聘管理系统后台的前端开发,项目已经开始测试了近期估计就会交付使用。一直是一个人在做,配合两个后端,说实话这种从很多不会到一个个独立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的东西)

动态选择组件 <component :is="xxx " /> is确定组件名

表单要放在table里,我的解决方案是

 <el-form :model="form">
        <el-table border fit :data="form.info">
          <el-table-column label="职位" align="center">
            <template slot-scope="scope">
              <el-form-item class="form-item" style="margin-bottom:0;">
                <span>{{ scope.row.post }}</span>
              </el-form-item>
            </template>
          </el-table-column>

form和table嵌套,

关于element没有纵向表头的table,
我采用了el-row和el-col的方法手撸表格

<el-row class="table_row">
         <el-col class="table_label" :span="6">
           <div>总体评价</div>
           <div>候选人优势</div>
           <div>候选人不足</div>
           <div>沟通能力</div>
           <div>知识水平</div>
           <div>经验积累</div>
           <div>管理能力</div>
           <div>聪明程度</div>
           <div>候选人与应聘职位的契合度</div>
           <div>是否愿意与候选人一起工作</div>
           <div>是否建议增加面试</div>
           <div>如不建议录用是否推荐到其他部门和其他职位</div>
         </el-col>
         <el-col :span="18">
           <el-form-item class="table_rate">
             <div>
               <el-radio-group v-model="form.radio_total">
                 <el-radio :label="1">不录用</el-radio>
                 <el-radio :label="2">建议不录用</el-radio>
                 <el-radio :label="3">拿不准</el-radio>
                 <el-radio :label="3">建议录用</el-radio>
                 <el-radio :label="3">录用</el-radio>
               </el-radio-group>
             </div>

用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用于加载转圈的动画

更新状态后表格内容不变,估计是直接用了缓存数据,选择去除<keep-alive

created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
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: &#x27;Evaluate&#x27;, params: { id: this.id } }) this. router.push(name:Evaluate,params:id:this.id)this.route.params.id

没办法对评价获取当前行的信息,采用scope
与 “{row}” ,是scope.row的解构赋值

可以对data直接赋值即调用函数,目前不清楚data和created先后顺序

vscode正则表达式替换。 其中分组不是\2 而是$2
:label="(\d)">(.*)<
:label="$2">$2<

label改成中文以后,突然所有的单选框都被选中了
已知不是中文的问题,发现问题,label不应该加冒号绑定。

git revert 和 git reset的区别

  • git revert是用一次新的commit来回滚之前的commit,此次提交之前的commit都会被保留;
  • git reset是回到某次提交,提交及之前的commit都会被保留,但是此commit id之后的修改都会被删除

事件处理。
想获得当前点击的元素,handleCheck(event) ,event.target就是目标元素
还可以直接传参数进来,这样可能方便一些
或者传$event,个人理解是如果传了参数(也就是@click= 内联形式),就要写成这种形式,访问原始的 DOM 事件

// e.target 是你当前点击的元素
// e.currentTarget 是你绑定事件的元素
所以最好用currentTarget,,稳定

如果是要获取的数据,data里初始化的时候直接[]或者{},

get不用管content-type。亲测没区别,毕竟不传data

可以看到,Promise.prototype.done和Promise.prototype.finally存在两点不同:

done并不返回promise对象,也就是说,在done之后不能使用then,catch等方法组成方法链。
done中发送的异常会被直接抛给外部,也就是说,其不会进行Promise的错误处理(Error Handling)

用户设置: 这种方式进行的设置,会应用于该用户打开的所有工程;

  • 工作空间设置:工作空间是指使用VS Code打开的某个文件夹,在该文件夹下会创建一个名为.vscode的隐藏文件夹,里面包含着仅适用于当前目录的VS Code的设置。工作空间的设置会覆盖用户的设置。

Unknown configuration setting: 把eslint插件禁用了

找了半天,我说为啥不能保存后自动格式化了,原来这个/* eslint-disable /对后面的代码生效, 正确做法
/
eslint-disable /

/
eslint-enable */

针对某一行
// eslint-disable-line
// eslint-disable-next-line

可以跟规则
/* eslint-disable no-alert */
// eslint-disable-line no-alert, quotes, semi

在 Vue 中,父子组件的关系可以总结为 props down、events up。
父子组件通信:父组件通过 props 向下传递数据给子组件
子父组件通信:子组件通过 events 给父组件发送消息
使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件
非父子组件通信:使用一个空的 Vue 实例作为中央事件总线

.native也不是想加就加的,个人猜测可能参数不能是row这种原生js没有的东西

对象要forEach的话必须先用Object.keys()转化成数组

更改配置文件必须重新yarn run dev

upload上传文件失败,原因是文件并未保存在fileList中,里面只是个索引。应该重写方法http-request(param),覆盖默认上传行为,data中保存param.file。文件类型(binary)

将/重定向到/login,发现栈溢出,原因是在permission.js中
设计了如果要访问/login就会跳到/,然后就一直在跳

通过在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应该是 routethis.redirect(===route.query.redirectrouteroute的新值)

全局搜索有点问题,并不是只要有就能搜到,亲测我的user.js中的log的内容就没搜到

7.8
登录进行校验,锁定用户名为chuangxin.com
无法获取用户名,input::placeholder的颜色
尝试使用sass变量获取值,似乎只能赋一个确定的值

.set-min-width .el-dialog {
min-width: 400px;
}

@chuangxin.com 本来想写在input里面,但是看编译后的html是封闭结构,所以除非直接造一个新的

@import ‘@/styles/mycss.css’;无法引入
选择在main.js的入口文件,引入样式

取字符串的三个函数:slice(start,[end]),substring(start,[end])和substr(start,[length])
相关属性:
slice()
第一个参数代表开始位置,第二个参数代表结束位置的下一个位置,截取出来的字符串的长度为第二个参数与第一个参数之间的差;若参数值为负数,则将该值加上字符串长度后转为正值;若第一个参数等于大于第二个参数,则返回空字符串.
substring()
第一个参数代表开始位置,第二个参数代表结束位置的下一个位置;若参数值为负数,则将该值转为0;两个参数中,取较小值作为开始位置,截取出来的字符串的长度为较大值与较小值之间的差.
substr()
第一个参数代表开始位置,第二个参数代表截取的长度
PS:字符串都从0开始计起
字符串的不可变性,只能赋值不能直接裁剪

写了一个bug,由于直接复用了添加和更新,导致更新完以后添加,this.temp已经有值了,所以应该在每次添加之前都先this.temp = {}

好像不能直接在vue的模板里调用引入的函数,决定采用computed,【未解决】

裁剪出现问题,由于使用的是splice,每次弹框都会裁剪一次,导致userName越来越小,解决方案为indexOf(’@’)找不到的时候返回-1改成当前字符串长度

把另一个对象的部分属性赋值给另一个对象

校验错误依旧提交,因为没有调用方法

确定了,axios方法中,data本应该给的是对象,但是实测json字符串好像也没事

transformRequest: [function (data) {
    // 对 data 进行任意转换处
    return data;
  }],

  // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
  transformResponse: [function (data) {
    // 对 data 进行任意转换处理

    return data;
  }],

以后可以直接使用transformResponse先把response.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) {
// 对原生进度事件的处理
},
猜测这个可用于进度条的显示

// ‘proxy’ 定义代理服务器的主机名称和端口
// auth 表示 HTTP 基础验证应当用于连接代理,并提供凭据
// 这将会设置一个 Proxy-Authorization 头,覆写掉已有的通过使用 header 设置的自定义 Proxy-Authorization 头。
proxy: {
host: ‘127.0.0.1’,
port: 9000,
auth: : {
username: ‘mikeymike’,
password: ‘rapunz3l’
}
},
这个是否可用于跨域? 是否可以不需要再vue.config.js中定义代理?

他对element的分页进行了二次封装,个人觉得没必要

this. r e f s r e f 引 用 的 是 元 素 和 子 组 件 。 全 局 注 册 , 所 以 不 要 重 名 t h i s . refs ref 引用的是元素和子组件。全局注册,所以不要重名 this. refsrefthis.refs为空???
猜测是刚触发事件函数已经执行完了,但是dom节点还没生成,解决方法是提前生成dom节点(v-show)
不过查阅element文档找到了更好的解决方案

Value below was evaluated just now.

Dialog 的内容是懒渲染的,即在第一次被打开之前,传入的默认 slot 不会被渲染到 DOM 上。因此,如果需要执行 DOM 操作,或通过 ref 获取相应组件,请在 open 事件回调中进行。
@open=”“
发现open的时候无效,改为opened成功

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个人感觉无所谓,于是发生了大问题
我一修改值,结果重新渲染了,直接回到了之前的rules,
可能还是得data或者computed中弄这个rules
所以选择了两套rules,然后分开create_rules和update_rules,在methods中对rules赋值。
出现问题,dialog似乎复用了之前的,在update中,不需要校验的部分也弹出红字
需要调用reset’F’i

1,在生命周期 mounted 之前的钩子函数中去调用会获取不到,原因是DOM节点都没有生成。
2 ,this.refs的组件在v-if为false的父节点下,导致这个子组件未渲染,所以获取不到。
总结:一定是组件已经渲染成功才能调用组件的数据。而不是页面加载完成后就一定能获取到

resetFields 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 —
clearValidate 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果 Function(props: array | string)
这里用clearValidate就行了,毕竟每次都会先赋值

在opened中调clearValidate,会在动画加载完才消除校验结果

新增用户的时候,关闭窗口之前突然给我的userName增加了@chuangxin.com,忘了data一旦变动就会触发重新渲染
不应该对data修改也就是this.temp,而是先let temp = this.temp,然后去修改其中的属性。
发现他会把我的let变为const,记起了即使是const,也是可以修改对象里的某个属性的,只要不对他重新赋值
又犯了一个错误,这个temp和this.temp其实还是引用,,,指向同一个对象
两种方法
JSON转两次,
Object.assign(target, source)将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

post模块出现问题,修改了以后即使不提交,也因为更改了data而产生了假的数据变动。
应该多写逻辑,若取消则数据不变
或者更好的做法是,temp先把row中的数据取出来,不要直接this.temp = row,一定要深拷贝!!!

职位创建时如果先点过更新,需要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元素节点都渲染完成以后才执行其里面的方法。
在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM

resetFields出现问题,会把值置为初始值,而这个初始值却是第一次打开的时候赋予的值,不解决这个bug,甚至会影响update时reset的值
给下一个遇到这个问题的人,这个问题的本质是因为你编辑时,第一次打开dialog的时候给表单绑定的model赋值了,这时候这个model的初始值就变成了你所赋值的值,所以resetFields的时候,会将model对应的每个值重置到初始值,这时候的初始值就是你编辑时赋值的那个值,而不是在data里声明的初始值,解决方式是,等dialog已经初始化mounted之后再给model赋值,也就是
this.$nextTick(() => { // 这里开始赋值 this.model.xxx = xxx; })

个人最简单的解决方案,每次打开对话框的时候直接先赋值一次,这样也就解决了表单的数据修改以后temp存了值的问题。而校验还是在open里做就行
v-if直接销毁这种也可以

Duplicate keys detected: ‘后端-AI工程院-北京’.
解决方案v-for="(item, index) in items"用index当key

把tabPane子组件的total传出来,我用的是emit/on机制

window.alert(‘尚未开发’)。这条语句无法直接作为表达式执行,因为及不认识window,也不认识alert

前端该如何对文件做必选校验?

blob binary large object),二进制大对象

下载简历
当将responseType设置为一个特定的类型时,你需要确保服务器所返回的类型和你所设置的返回值类型是兼容的。那么如果两者类型不兼容呢?恭喜你,你会发现服务器返回的数据变成了null,即使服务器返回了数据。

管理员权限的路由user出了bug,发现会自动再permission.js中通过if(to.path === ‘/login’)的判断,很迷,于是才next(’/profileStep’)
发现是redirectfrom中有user,说明是从user跳到/的,估计是*通配符在前面先匹配了这项

终于找到了跳转不来user页面的原因,路由的index.js是export了路由表,而之前的路由表没有asyncRoutes。所以造成无法跳转的情况

logout从profileStep登出没反应,从别的登出会跳到profileStep,大概知道为什么了。其实不是没反应而是跳到login。如果令牌还在的话,其实是会跳回profileStep的。这个应该和异步操作有关,dispatch应该是异步的,先把后面的路由push执行了,导致token还没移除
【理解错误】其实是因为忘了移除token,事实证明不用async和await也一样

本模块的commit只能调自己的,不能调别人的mutation
使用第三参数{root: true}
报错unknown mutation type
识别不来?

user.js中关于commit兄弟模块的mutation。

在带命名空间的模块内访问全局内容(Global Assets)
如果你希望使用全局 state 和 getter,rootState 和 rootGetter 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。

若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。
问题解决了,要先加上模块名 commit(‘permission/REMOVE_ROUTES’, null, { root: true })

模板渲染, h()函数第二个参数,不知道怎么加element组件的属性。。。

出bug了,一旦刷新,admin路由也会变成common,原因是存在store的role被刷新没了

/ autocomplete 属性 自动补全是根据之前的输入

x=document.forms[“myForm”][“email”].value;要用[email]的方式,前提是input外层是表单,而且name=email,
事实证明如果我不用form的话,我可以不要name,直接getElementById().value也是可以的

this.$store.state.user.userName,模块化的话要加模块名的

加解密 加密btoa解密atob,密码之类的放在前端是不安全的

match返回的其实是数组,第一项是匹配的字串
获取文件名
const fileName = headers[‘content-disposition’].match(/(?<=fileName=.*___).+(?=;filename)/)[0]

怎么在别的vue文件调用该vue文件的methods

if (response.data.statusCode === 1) {失败
response与实际返回的不同,断点执行完才会到statusCode=1
修改判断方法data.type === ‘application/json’ 如果有文件会是"text/xml"

 类似资料: