1.通过 extendRoutes 配置项来扩展 Nuxt.js 生成的路由配置
2.JavaScript-阻止浏览器下载拖放的Excel文件
1.IOS问题汇总
3.使用 husky、commitlint 和 lint-staged 来规范git提交
2.JWT
4.CSS黑科技
前端小白蔡 [BLOG]
html
<div
:class="['drag-area', fileOver ? 'over' : '']"
@drop="hleDrop"
@dragover="hleDragOver"
@click="$refs.fileInput.click()"
>
<div>将Excel文件拖到此处,或点击上传</div>
<input ref="fileInput" type="file" hidden @input="hleInput" />
</div>
js
hleInput(e) {
const file = e.target.files[0]
this.fileName = file.name
let fielParam = new FormData() //创建form对象
fielParam.append('file', file) //通过append向form对象添加数据
this.$emit('input', fielParam)
},
hleDrop(e) {
e.preventDefault()
const data = e.dataTransfer.items[0] || {}
if (data.kind === 'file') {
const file = data.getAsFile()
this.fileName = file.name
let fielParam = new FormData() //创建form对象
fielParam.append('file', file) //通过append向form对象添加数据
this.$emit('input', fielParam)
}
},
请求方式为 GET:
1、可利用a标签的href、img的src实现后端接口下载文件或直接展示(验证码图片)
请求方式为POST 或者GET方式(需要带token验证的)
exportMenu(this.appId, this.importExport.groupId).then(res => {
const blob = new Blob([res], {
type: 'application/vnd.ms-excel;charset=utf-8',
})
let fileName = `文件名_${new Date().getTime()}.xlsx`
const elink = document.createElement('a')
elink.download = fileName
elink.style.display = 'none'
elink.href = URL.createObjectURL(blob)
document.body.appendChild(elink)
elink.click()
URL.revokeObjectURL(elink.href) // 释放URL 对象
document.body.removeChild(elink)
})
// 注意: 接口请求头信息需要再自定义 如:
export const downloadTemplate = ()=> axios.$get(`url`,{
responseType: 'blob',
headers: {'Content-Type': 'application/x-download;charset=utf-8'},
})
huskey相关新版-->语雀文章
yarn add -D eslint babel-eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y
npm install --save-dev prettier eslint-plugin-prettier eslint-config-prettier
yarn add husky@next # 安装最新版,就不用配置 scripts 脚本了
yarn add -D lint-staged@beta
yarn add --dev @commitlint/cli @commitlint/config-conventional
module.exports = {
extends: ['@commitlint/config-conventional']
};
说明:
commitlint.config.js 配置文件可以添加自己的规则,这里 @commitlint/config-conventional 提供了官方的规则扩展:
build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交
ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle等)的提交
docs:文档更新
feat:新增功能
merge:分支合并 Merge branch ? of ?
fix:bug 修复
perf:性能, 体验优化
refactor:重构代码(既没有新增功能,也没有修复 bug)
style:不影响程序逻辑的代码修改(修改空白字符,格式缩进,补全缺失的分号等,没有改变代码逻辑)
test:新增测试用例或是更新现有测试
revert:回滚某个更早之前的提交
chore:不属于以上类型的其他类型
// 添加husky
"husky": {
"hooks": {
"commit-msg": "commitlint -e $HUSKY_GIT_PARAMS"
}
},
新增.prettierrrc
文件
{
"printWidth": 120, // 一行最大多少字符
"tabWidth": 2, // tab占用的字符数
"useTabs": false, // 是否使用tab代替空格
"semi": true, // 是否每句后都加分号
"singleQuote": true, // 是否使用单引号
"jsxSingleQuote": false, // jsx是否使用单引号
"trailingComma": "all", // 数组尾逗号。
"bracketSpacing": false, // {foo: xx}还是{ foo: xx }
"arrowParens": "always" //剪头函数参数是否使用()
}
*vue开启eslint基本上不用配置 ( 如果需要请参考底部链接进行配置 )
package.json文件 :
"gitHooks": {
"commit-msg": "commitlint -e $HUSKY_GIT_PARAMS",
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.js": [
"vue-cli-service lint",
"git add"
],
"*.vue": [
"vue-cli-service lint",
"git add"
]
}
husky
会在你提交前,调用 pre-commit
钩子,执行 lint-staged
,如果代码不符合 prettier
配置的规则,会进行格式化;然后再用 eslint
的规则进行检查,如果有不符合规则且无法自动修复的,就会停止此次提交。如果都通过了就会讲代码添加到 stage
,然后 commit
。
参考
- 实现前端代码模块化-可移植性更高
- 不基于nuxt中pages目录自动生成路由的功能-更加方便移植代码
- require('path').resolve()
- fast-glob
- extendRoutes属性
在模块中新建路一个路由文件:
// 注意:在配置路由信息的时候 当配置到children(子路由)时
// 请保证父页面有用到<nuxt-child>
在nuxt.config.js文件中引入并扩展理由
这个需求可能不是很常见,但当好几个项目需要使用相同的几个模块,或者项目构建只需要某一些模块而不需要的模块代码不想引入,就会产生这种需求。(应该有其他好的方法-期待交流)
注意路由匹配顺序: 如routes数组中正常路由必须要在404页面(*任意匹配)路由之前,否则404会优先匹配。
分别style-resources-loader 和 vue-cli-plugin-style-resources-loader (前提是已经安装过 sass sass-loader)
vue add style-resources-loader
或
yarn add style-resources-loader vue-cli-plugin-style-resources-loader -D
// vue.config.js
const path = require("path");
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = {
pluginOptions: {
"style-resources-loader": {
preProcessor: "scss",
patterns: [
resolve('./src/styles/global.scss') // 声明scss全局变量的文件
]
}
}
};
按以上两个步骤,可以在任何.vue文件的style标签中正常使用全局变量,但如果.vue文件中的scss是用@import url('')这种方式导入就例外
.vue文件中:
<style lang="scss">
// @import url('./index.scss'); 这种方式导入-index.scss中全局变量无法被解析
@import "./index.scss";
</style>
// 在safari中, Js代码不兼容YYYY-MM-DD这种时间格式,只支持YYYY/MM/DD
new Date('2018-09-02') // Invalid Date
new Date('2018/09/02') // Sun Sep 02 2018 00:00:00 GMT+0800 (**标准时间)
<!-- 在html头部加这一行可以解决 -- 个人觉得比较暴力,应该有更好的方案待发现 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
// width - viewport的宽度
// height - viewport的高度
// initial-scale - 初始的缩放比例
// minimum-scale - 允许用户缩放到的最小比例
// maximum-scale - 允许用户缩放到的最大比例
// user-scalable - 用户是否可以手动缩放
// 在内容溢出滚动的元素添加如下样式:
-webkit-overflow-scrolling : touch;
1、安装下载并启动UTools ( 下载地址 :https://yuanliao.info/d/1020 )
2、在utools插件中心中搜索 <内网穿透> 进行安装使用
它的本质是一个对JSON对象加密后的字符串,服务器认证以后,生成一个 JSON 对象,发回给用户。
典型的JWT由三个部分组成,每一个部分由 . 分隔,然后构成JWT: header(头部).payload(载荷).signature(签名)
例子: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
{
"alg": "HS256",
"typ": "JWT"
}
头部包含alg(签名算法)和令牌(token)的类型,这部分会被编码为Base64URL格式:结果大致如:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据
/* 官方提供七个字段供选用 */
{
iss (issuer):'', // 签发人
exp (expiration time):'', // 过期时间
sub (subject):'', // 主题
aud (audience):'', // 受众
nbf (Not Before):'', // 生效时间
iat (Issued At):'', // 签发时间
jti (JWT ID):'' // 编号
}
/* 除了以上字段,你还可以自定义 */
{
name: "Stephen",
phone: ""
}
载荷也会使用 Base64URL 算法转成字符串, 如 :eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
对它进行解析得到前端想要的数据:
const token = 'header.payload.signature' // 参考上面第一个例子,数据太长简化
const payloadInfo = JSON.parse( decodeURIComponent(escape(window.atob(token.split('.')[1]))) )
const {name} = payloadInfo // 得到我们想要的信息 name===Stepehn
Signature部分是对前两部分的防篡改签名。将Header和Payload用Base64URL编码后,用点(.)连接起来组成新字符串。然后使用签名算法和密钥对这个字符串进行签名:
signature = hmac_sha256(base64encode(header) + '.' + base64encode(payload), 'MY_SUPER_SECRET_KEY')
// 这个密钥(MY_SUPER_SECRET_KEY)只有服务器才知道,不能泄露给用户
// 输出结果如: TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
const encode = (str) => btoa(encodeURI(str))
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
if(!pre.includes(cur)){
return pre.concat(cur)
}else{
return pre
}
},[])
console.log(newArr);// [1, 2, 3, 4]
const unique = (arr) => Array.from(new Set(arr))
let arr = [1,1,'true','true',true,true,false,false, undefined,undefined, null,null,
NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log( unique(arr) )
// [ 1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {} ]
// 简写成一句去重:
[...new Set(arr)]
const unique = function(arr = []) {
let newArr = [];
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i])
}
}
return newArr;
}
windows环境下
默认生成的文件名是 id_rsa/id_rsa.pub
,由于这里需要两套密钥,需为它们分别命名,防止被覆盖 -- 默认路径在用户根目录下的.ssh
文件夹中
执行下面命令生成密钥:
ssh-keygen -t rsa -C "注册 gitlab 账户的邮箱"
提示输入名称时输入: id_rsa_gitlab
ssh-keygen -t rsa -C "注册 github 账户的邮箱"
提示输入名称时输入: id_rsa_github
打开
~/.ssh/config
文件(没有就新建一个),并在文件中加入以下内容
# default
Host github.com
HostName github.com
User [email protected](GitHub邮箱)
IdentityFile ~/.ssh/id_rsa_github
# two
Host gitlab.com(这里注意填写自己公司对于的gitlab host)
HostName gitlab.com
User [email protected](Gitlab邮箱)
IdentityFile ~/.ssh/id_rsa_gitlab
把常用的账户设为全局(默认上面配置的第一个),不常用的进入项目文件夹单独设置
用户名/邮箱
# 单独设置每个repo 用户名/邮箱
git config user.name “xxxx”
git config user.email “[email protected]”
# 设置全局 用户名/邮箱 配置
git config –-global user.name “xxxx”
git config –-global user.email “[email protected]”
1、复制 ~/.ssh/id_rsa_gitlab.pub
文件内容,进入gitlab / profile / SSH Keys,将公钥内容添加至 gitlab
2、复制 ~/.ssh/id_rsa_github.pub
文件内容,进入github / setting / SSH and GPG keys / New SSH key 将公钥内容添加至 github
1、前端通过JS,动态创建一个script标签
2、前端设置script的src,实现不同域数据的申请
3、前端将需要给后台传递的数据放置在URL串中,还需要将“申请到数据后”想要运行的功能函数“作为参数”传递给后台
4、后台接收到前端传递的数据,并根据需求,从数据库中获取数据
5、后台把从数据库中得到的数据以JSON格式存储
6、后台将JSON格式的数据作为“参数”放置在函数中
7、后台将JS代码返回前端并运行JS函数
8、在前端中定义的函数被运行,后台传递的数据存在于参数当中(此时我们可以再书写要执行的DOM操作等功能)
1、后台需要的参数名,可以随便定义吗?
答案:不可以,后台是需要根据字段在数据库中进行数据查找的,需要前后端协定不能随便定义。
为何要动态设置JavaScript?
答案:用动态的方式进行创建,可以满足“参数值不确定”的功能需求
实例需求:希望在A域中访问 http://localhost/interface 这个接口,并且获取接口返回的内容。A域与 http://localhost/interface 处于不同域。
前端代码
var newScript = document.createElement('script');
newScript.src = 'http://localhost/interface?name=stephen&callback=callFn';
document.body.appendChild(newScript);
function callFn(data) {
console.log(data);
}
后端代码 (以php语言为例)
<?php
$id = $_GET['name'];
$callback = $_GET['callback'];
$json = '';
if ($id === 'stephen') {
$json = '{
"name": "Hi, stephen"
}';
} else {
$json = '{
"name": "iOS"
}';
};
if ($callback) {
$result = $callback . '(' . $json . ')';
}
echo $result;
?>
一、优点:
二、缺点:
我要将一个Excel文件拖放上传,当文件被放入上传区域时,没有问题
但当文件上传区域禁止上传 或者 将文件放在上传区域外,浏览器就会下载该Excel
将事件侦听器添加到对所有拖放事件调用preventDefault()的窗口
window.addEventListener("dragover",function(e){
e = e || event;
e.preventDefault();
},false);
window.addEventListener("drop",function(e){
e = e || event;
e.preventDefault();
},false);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.