-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontent.json
1 lines (1 loc) · 66.6 KB
/
content.json
1
{"meta":{"title":"Bran's Blog","subtitle":"布兰的网络日志","description":"Bran的个人博客,一个前端程序员的成长","author":"Bran","url":"http://wywppkd.github.io","root":"/"},"pages":[{"title":"分类","date":"2020-08-11T01:13:15.979Z","updated":"2020-08-11T01:13:15.979Z","comments":false,"path":"categories/index.html","permalink":"http://wywppkd.github.io/categories/index.html","excerpt":"","text":""},{"title":"Repositories","date":"2020-08-11T01:13:15.980Z","updated":"2020-08-11T01:13:15.980Z","comments":false,"path":"repository/index.html","permalink":"http://wywppkd.github.io/repository/index.html","excerpt":"","text":"Githubgithub: username: wywppkd"},{"title":"关于","date":"2020-08-11T01:13:15.978Z","updated":"2020-08-11T01:13:15.978Z","comments":false,"path":"about/index.html","permalink":"http://wywppkd.github.io/about/index.html","excerpt":"","text":"{ name: 'Bran' age: 29, gender: '男', profession: 'Web Developer & Explorer', experience: '5年', address: '北京市', education: '本科', github: 'https://github.com/wywppkd', blog: 'http://wywppkd.github.io', email: '[email protected]', description: '致力于网站建设与前端用户体验设计', skills: [ ['Html', 'Javascript', 'jQuery', 'CSS', 'ES6', 'Node'], ['Webpack', 'Gulp'], ['Less','Sass'], ['Git', 'SVN'], ['Vue','React'], ['Bootstrap', 'Vant', 'iView'], ], devTools: [ ['Sublime Text', 'Visual Studio Code'], ['Chrome DevTools'], ['SourceTree', 'TortoiseSVN'], ['iSparta'], ['Navicat'], ] }"},{"title":"404 Not Found:该页无法显示","date":"2020-08-11T01:13:15.963Z","updated":"2020-08-11T01:13:15.963Z","comments":false,"path":"/404.html","permalink":"http://wywppkd.github.io/404.html","excerpt":"","text":""},{"title":"标签","date":"2020-08-11T01:13:15.980Z","updated":"2020-08-11T01:13:15.980Z","comments":false,"path":"tags/index.html","permalink":"http://wywppkd.github.io/tags/index.html","excerpt":"","text":""}],"posts":[{"title":"Taro开发注意事项","slug":"Taro开发注意事项","date":"2020-08-24T10:03:42.000Z","updated":"2020-08-24T10:04:38.474Z","comments":true,"path":"2020/08/24/Taro开发注意事项/","link":"","permalink":"http://wywppkd.github.io/2020/08/24/Taro%E5%BC%80%E5%8F%91%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/","excerpt":"","text":"推荐命名 普通js/ts文件, 命名: util.js, util_helper.js 组件文件(大驼峰+jsx后缀): PayResult.jsx, CouponCenter.jsx CSS标签选择器(View,Text)不生效 支付宝小程序不生效, 推荐用类名 // 支付宝端无效 View{ color:#000 } // ok .box{ color:#000 } 轮播组件绑定事件无效 支付宝端: SwiperItem标签绑定onClick事件无效, 必须绑在内部的View或Image标签上 // 绑定事件无效 <Swiper> {swiperList.map((item) => { return ( <SwiperItem key={item.cardPackagePartnerId} onClick={tapBanner.bind( this, item.cardPackagePartnerId )}> <Image src={item.cardPackageImage} /> </SwiperItem> ); })} </Swiper> // ok <Swiper> {swiperList.map((item) => { return ( <SwiperItem key={item.cardPackagePartnerId} > <Image onClick={tapBanner.bind( this, item.cardPackagePartnerId )} src={item.cardPackageImage} /> </SwiperItem> ); })} </Swiper> build打包后背景图错乱 问题: build打包会进行代码压缩合并, 将不同选择器相同的属性background-size: contain;提取合并到一起, 但是合并后的代码确放在background之前, 导致background复合属性覆盖掉了background-size属性 推荐: 联调测试阶段采用build打包, 避免使用dev打包 /* 推荐 */ .box{ background-image: url("https://19ego.cn/home/home-default.png"); background-repeat: no-repeat; background-size: contain; } /* 不推荐 */ .box{ background: url("https://19ego.cn/home/home-default.png") no-repeat; background-size: contain; } JSX遍历 JSX中遍历数组只能使用map JSX遍历时: 事件传参不支持对象字面量 react-hooks组件中没有复现 const article = [{id:1, title:"标题1"}, {id:2, title:"标题2"}] // 报错 render(){ return ( <View> article.map((item,index) => { // 报错: 不允许传字面量对象 return <View onClick={this.doPay.bind(this, {title:item.title})}>{item.name}</View> }) ) </View> } /// 解决 render(){ return ( <View> article.map((item,index) => { // 变量 const obj = { title:item.title } return <View onClick={this.doPay.bind(this, obj)}>{item.name}</View> }) ) </View> } taro打包出错 问题: 命令行工具@tarojs/cli与项目依赖的版本不一致 解决: 升级@tarojs/cli时注意升级项目依赖, 保持taro工具与项目依赖的版本一致","categories":[{"name":"Taro","slug":"Taro","permalink":"http://wywppkd.github.io/categories/Taro/"}],"tags":[{"name":"React","slug":"React","permalink":"http://wywppkd.github.io/tags/React/"},{"name":"Taro","slug":"Taro","permalink":"http://wywppkd.github.io/tags/Taro/"},{"name":"小程序","slug":"小程序","permalink":"http://wywppkd.github.io/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"}]},{"title":"Docker部署React项目","slug":"Docker部署React项目","date":"2020-08-24T10:02:48.000Z","updated":"2020-08-24T10:02:53.426Z","comments":true,"path":"2020/08/24/Docker部署React项目/","link":"","permalink":"http://wywppkd.github.io/2020/08/24/Docker%E9%83%A8%E7%BD%B2React%E9%A1%B9%E7%9B%AE/","excerpt":"","text":"1. 创建配置文件1.1 创建Dockerfile(项目根目录)# Dockerfile # 第一阶段: 构建node容器镜像 FROM node:12.18 # 基础镜像node COPY ./ /app-source # 复制项目文件到镜像内的目标位置/app-source WORKDIR /app-source # 指定工作目录 RUN npm install && npm run build:test # 安装依赖 && 打包 # 第二阶段: 构建nginx容器镜像 FROM nginx:1.18 # 设置基础镜像nginx RUN mkdir /app # 创建目录 COPY --from=0 /app/build /app # 将第一阶段镜像打包后的文件复制到nginx镜像的指定目录 # --from=0 引用第一阶段镜像 COPY nginx.conf /etc/nginx/nginx.conf # 复制配置文件到nginx镜像的指定目录 1.2 创建.dockerignore(项目根目录) 防止 node_modules 和其他中间构建产物被复制到镜像中导致构建问题 **/node_modules **/build 1.3 创建nginx.conf(项目根目录)user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; server { listen 80; # 端口号 location / { root /app; # 站点目录 index index.html; # 默认首页 try_files $uri $uri/ /index.html; # 兼容history路由 } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } } 2. 构建Docker镜像# 进入主机 $ git clone ${项目地址} # 克隆工程目录 $ cd /app # 进入项目目录 $ docker build . -t app-image # 构建Docker镜像 3. 运行Docker镜像$ docker run -d -p 8080:80 app-image # 通过镜像启动容器: 映射本机端口号8080-容器内端口90 $ curl localhost:8080 # 测试是否部署成功 # 通过8080端口访问当前主机","categories":[{"name":"React","slug":"React","permalink":"http://wywppkd.github.io/categories/React/"}],"tags":[{"name":"React","slug":"React","permalink":"http://wywppkd.github.io/tags/React/"},{"name":"Docker","slug":"Docker","permalink":"http://wywppkd.github.io/tags/Docker/"},{"name":"Nginx","slug":"Nginx","permalink":"http://wywppkd.github.io/tags/Nginx/"},{"name":"自动化打包部署","slug":"自动化打包部署","permalink":"http://wywppkd.github.io/tags/%E8%87%AA%E5%8A%A8%E5%8C%96%E6%89%93%E5%8C%85%E9%83%A8%E7%BD%B2/"}]},{"title":"使用env-cmd设置React项目环境变量","slug":"使用env-cmd设置React项目环境变量","date":"2020-08-12T08:56:50.000Z","updated":"2020-08-12T08:57:30.233Z","comments":true,"path":"2020/08/12/使用env-cmd设置React项目环境变量/","link":"","permalink":"http://wywppkd.github.io/2020/08/12/%E4%BD%BF%E7%94%A8env-cmd%E8%AE%BE%E7%BD%AEReact%E9%A1%B9%E7%9B%AE%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F/","excerpt":"","text":"借助env-cmd设置环境变量, 避免每次手动修改代码 $ npm install env-cmd -D # 打包时将自定义变量注入到环境变量process.env中 创建.env文件 注意: 变量名一定要用REACT_APP_开头, 其他变量名(除NODE_ENV)会被忽略 注意: 修改变量后必须重新打包 // .env.dev REACT_APP_API_URL=http://api-dev.example.com 配置scripts命令// package.json { "scripts": { "start": "react-scripts start",// development模式 "build": "react-scripts build",// production模式 // 使用development模式打包: 将.env.dev内的变量注入到环境变量中 "start:dev": "env-cmd -f .env.dev npm run start", // 使用production模式打包: 将.env.dev内的变量注入到环境变量中 "build:dev": "env-cmd -f .env.dev npm run build" } } 读取变量process.env.REACT_APP_API_URL // 读取变量","categories":[{"name":"React","slug":"React","permalink":"http://wywppkd.github.io/categories/React/"}],"tags":[{"name":"React项目环境变量","slug":"React项目环境变量","permalink":"http://wywppkd.github.io/tags/React%E9%A1%B9%E7%9B%AE%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F/"},{"name":"env-cmd","slug":"env-cmd","permalink":"http://wywppkd.github.io/tags/env-cmd/"}]},{"title":"React-Typescript配置ESLint-Prettier","slug":"React-Typescript配置ESLint-Prettier","date":"2020-08-11T01:16:45.000Z","updated":"2020-08-12T08:56:50.539Z","comments":true,"path":"2020/08/11/React-Typescript配置ESLint-Prettier/","link":"","permalink":"http://wywppkd.github.io/2020/08/11/React-Typescript%E9%85%8D%E7%BD%AEESLint-Prettier/","excerpt":"","text":"创建项目$ npx create-react-app app-react-ts --typescript 安装 ESLint 解析 TypeScript 的依赖$ npm i eslint -D # eslint包 $ npm i @typescript-eslint/parser -D # 将 TypeScript 转换为 ESTree,使 eslint 可以识别 ts $ npm i @typescript-eslint/eslint-plugin -D # 定义好的检测Typescript代码的规范 安装Prettier依赖$ npm i prettier -D # prettier包 $ npm i eslint-config-prettier -D # 禁用任何可能干扰现有 prettier 规则的 linting 规则, 一定要把它放在 extends 中最后的位置, 避免再次被打开 $ npm i eslint-plugin-prettier -D # 将 Prettier 问题作为ESLint规则提示出来 配置ESLint// .eslintrc.js module.exports = { // 解析器 parser: "@typescript-eslint/parser",// 使eslint识别ts // 现有规则的一系列预设 extends: [ "plugin:@typescript-eslint/recommended",// 启用@typescript-eslint/eslint-plugin建议规则 "react-app",// CRA推荐规则 "plugin:prettier/recommended",// 简化配置: eslint-config-prettier + eslint-plugin-prettier ], // 规则 rules: {} }; 安装VSCode插件 ESLint插件 注意: 不需要安装Prettier插件, 安装了也无妨 配置settings// workspace settings.json { // 老版只支持js文件校验, 所以需要配置"eslint.validate" // 新版不需要配置"eslint.validate", 增加ts, vue等支持 // "eslint.validate": [ // "javascript", // "javascriptreact", // "typescript", // "typescriptreact" // ], "editor.formatOnSave": false,// 保存时, 禁止触发其他扩展格式化代码, 如Prettier "editor.codeActionsOnSave": { "source.fixAll.eslint": true// 保存时, 运行ESLint检测并格式化代码 } }","categories":[{"name":"React","slug":"React","permalink":"http://wywppkd.github.io/categories/React/"}],"tags":[{"name":"React","slug":"React","permalink":"http://wywppkd.github.io/tags/React/"},{"name":"TypeScript","slug":"TypeScript","permalink":"http://wywppkd.github.io/tags/TypeScript/"},{"name":"ESLint","slug":"ESLint","permalink":"http://wywppkd.github.io/tags/ESLint/"},{"name":"Prettier","slug":"Prettier","permalink":"http://wywppkd.github.io/tags/Prettier/"}]},{"title":"用TS写React","slug":"用TS写React","date":"2020-07-17T01:27:07.000Z","updated":"2020-08-11T01:13:15.976Z","comments":true,"path":"2020/07/17/用TS写React/","link":"","permalink":"http://wywppkd.github.io/2020/07/17/%E7%94%A8TS%E5%86%99React/","excerpt":"","text":"1. TS重构项目三种方案 共存策略: TS和JS共存 宽松策略: 将现有JS改成TS, 代码检测规则按照宽松的规则执行 严格策略: 开启最严格的检测规则, 一个一个排除报错 2. TS写函数组件2.1 函数声明式// React.ReactNode: 表示返回的内容 function Heading(): React.ReactNode { return <h1>My Website Heading</h1> } 2.2 函数表达式// React.FC: 因为函数表达式返回一个函数 const OtherHeading: React.FC = () => <h1>My Website Heading</h1> 3. TS 写 useStateconst [count, setCount] = useState<number>(0);// 不推荐, 类型注解: number类型 const [count, setCount] = useState(0);// ok, 推荐用类型推导 const [state, setState] = useState<number | null>(null);// 类型注解: 联合类型 type ArticleInfo = { title: string; content: string; }; const [articles, setArticles] = useState<ArticleInfo[]>([]);// 类型注解: 数组 4. ES6参数默认值代替React的defaultProps 原因: React.FC不能完美支持defaultProps import React from 'react' type Props = { color?: string; children: React.ReactNode; onClick: () => void; } // color设置了默认值, 代替defaultProps const Button: React.FC<Props> = ({ children, color = 'tomato', onClick }) => { return <button style={{ backgroundColor: color }} onClick={onClick}>{children}</button> } 5. TS对Redux所有state进行类型约束// 类型约束: store/index.ts // 将RootState暴露出去: store中所有state状态进行类型约束 export type RootState = ReturnType<typeof rootReducer>; // 使用 import { RootState } from '../../store/index' // 使用RootState约束所有state const { userReducer, tokenReducer } = useSelector((state: RootState) => state)","categories":[{"name":"TypeScript","slug":"TypeScript","permalink":"http://wywppkd.github.io/categories/TypeScript/"}],"tags":[{"name":"React","slug":"React","permalink":"http://wywppkd.github.io/tags/React/"},{"name":"TypeScript","slug":"TypeScript","permalink":"http://wywppkd.github.io/tags/TypeScript/"}]},{"title":"express-session使用介绍","slug":"express-session使用介绍","date":"2019-10-08T11:53:20.000Z","updated":"2020-08-11T01:13:15.968Z","comments":true,"path":"2019/10/08/express-session使用介绍/","link":"","permalink":"http://wywppkd.github.io/2019/10/08/express-session%E4%BD%BF%E7%94%A8%E4%BB%8B%E7%BB%8D/","excerpt":"","text":"express-session使用介绍 session 存储位置: 默认是内存中, 推荐 redis 1.5.0 版本之后: 不需要借用cookie-parser, 可以直接读取 req.cookies, res.cookies 生成 session 会话$ npm i express-session -S var express = require("express"); var session = require("express-session"); var app = express(); var sess = session({ name: "sessionId", // 默认为connect.sid, 推荐使用自定义名称, 更安全 secret: "my_session_secret", // 建议使用 128 个字符的随机字符串 resave: false, // 即使session会话未更改, 也保存到store中 rolling: true, // 默认false, 是否每次请求都刷新会话有效期 saveUninitialized: true, // store, // 默认存储在内存中(不推荐,容易内存泄漏), 可以改存放redis中 cookie: { maxAge: 10 * 60 * 60 * 1000, // 过期时间(毫秒) // expires, // 过期日期, 不推荐直接设置, 推荐使用maxAge httpOnly: true // 禁止js操作cookie } }); app.use(sess); // 使用中间件 saveUninitialized 属性 false:只有用户登录(req.session 对象被修改)才会生成 session 会话 true:只要用户访问就会生成 session 会话 登录的时候修改session信息// 登录接口 app.post("/user/login", function(req, res, next) { if (req.body.user === "admin" && req.body.password === "123456") { // 验证账号密码成功后, 将用户user写入session信息中 req.session.user = req.body.user; res.redirect("/"); } else { let error = req.body.user !== "admin" ? "账号错误" : "密码错误"; res.render("login", { error: error }); } }); // 过滤登录状态中间件 app.use(function(req,res,next){ // session中有user属性说明是已登录状态 if (req.session.user || req.path=="/user/login") { next(); } else { res.redirect("/user/login"); } }) req.session对象常用属性和方法1. 访问 session 信息req.session; // 访问session数据 req.session.views = 1; // 给session中添加一个views属性, 值为1 2. 获取 cookie 信息req.session.cookie; // 每个session都有唯一的cookie与之伴随, 允许你更改每个访问者的session cookie 3. 获取 sessionId 每个 session 都有一个与之关联的唯一 ID req.session.id; // 属性是`req.sessionID`的别名且无法改变 4. 销毁 session// 用户退出登录时调用 req.session.destroy(function(err) { // cannot access session here }); 5. 重新生成 sessionreq.session.regenerate(function(err) { // will have a new session here }); 6. 重载 session 数据 从 store 重载 session 数据, 填充 req.session 对象 req.session.reload(function(err) { // session updated });","categories":[{"name":"Express","slug":"Express","permalink":"http://wywppkd.github.io/categories/Express/"}],"tags":[{"name":"Node","slug":"Node","permalink":"http://wywppkd.github.io/tags/Node/"},{"name":"express-session","slug":"express-session","permalink":"http://wywppkd.github.io/tags/express-session/"}]},{"title":"morgan日志中间件","slug":"morgan日志中间件","date":"2019-09-08T12:34:12.000Z","updated":"2020-08-11T01:13:15.969Z","comments":true,"path":"2019/09/08/morgan日志中间件/","link":"","permalink":"http://wywppkd.github.io/2019/09/08/morgan%E6%97%A5%E5%BF%97%E4%B8%AD%E9%97%B4%E4%BB%B6/","excerpt":"","text":"morgan日志中间件 只能记录 http 请求日志 $ npm install morgan -S # 下载 基本使用var logger = require("morgan"); app.use(logger("dev")); // 将日志输出到控制台 // 方法 路径 状态码 时间 GET /users 200 53.454 ms - 23 将日志按照日期保存到日志文件中var logger = require("morgan"); var rfs = require("rotating-file-stream"); // 将日志写入log目录文件中 // 解决:时区不一致的问题 logger.token("date", function() { var p = new Date() .toString() .replace(/[A-Z]{3}\\+/, "+") .split(/ /); return p[2] + "/" + p[1] + "/" + p[3] + ":" + p[4] + " " + p[5]; }); var accessLogStream = rfs.createStream("access.log", { size: "10M", // 每10M大小轮换 interval: "1d", // 每天轮换 path: path.join(__dirname, "log") // 手动创建日志目录"/log" }); app.use(logger("combined", { stream: accessLogStream })); 预定义日志格式 format 即是日志格式, 支持自定义日志格式, 同时 morgan 提供了几个预定义选项: // combined ip, 时间, 请求方法, 请求url, HTTP版本, 状态码, 响应内容长度, referrer, user-agent // common ip, 时间, 请求方法, 请求url, HTTP版本, 状态码, 响应内容长度 // dev 请求方法, 请求url, 状态码, 响应时间, 响应内容长度 // short ip, 请求方法, 请求url, HTTP版本, 状态码, 响应内容长度, 响应时间 // tiny 请求方法, 请求url, 状态码, 响应内容长度, 响应时间","categories":[{"name":"Express","slug":"Express","permalink":"http://wywppkd.github.io/categories/Express/"}],"tags":[{"name":"Node","slug":"Node","permalink":"http://wywppkd.github.io/tags/Node/"},{"name":"morgan日志","slug":"morgan日志","permalink":"http://wywppkd.github.io/tags/morgan%E6%97%A5%E5%BF%97/"}]},{"title":"切换npm源的几种方式","slug":"切换npm源的几种方式","date":"2019-09-06T07:42:33.000Z","updated":"2020-08-11T01:13:15.971Z","comments":true,"path":"2019/09/06/切换npm源的几种方式/","link":"","permalink":"http://wywppkd.github.io/2019/09/06/%E5%88%87%E6%8D%A2npm%E6%BA%90%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/","excerpt":"","text":"切换npm源的几种方式手动切换$ npm --registry https://registry.npm.taobao.org # 切换到taobao源, 临时使用 $ npm config set registry=https://registry.npm.taobao.org # 切换到taobao源, 长期使用 # 删除taobao源 $ npm config delete registry $ npm config delete disturl 通过nrm工具管理(推荐)$ npm install -g nrm # 安装nrm工具 $ nrm ls # 查看仓库地址列表(默认有:taobao,yarn,cnpm等源) $ npm use taobao # 切换到taobao的仓库地址 $ npm add taobao2 https://registry.npm.taobao.org/ # 添加一个名叫taobao的仓库地址 $ npm del taobao2 # 删除一个叫taobao2的仓库地址","categories":[{"name":"npm","slug":"npm","permalink":"http://wywppkd.github.io/categories/npm/"}],"tags":[{"name":"npm","slug":"npm","permalink":"http://wywppkd.github.io/tags/npm/"},{"name":"nrm","slug":"nrm","permalink":"http://wywppkd.github.io/tags/nrm/"},{"name":"npm源","slug":"npm源","permalink":"http://wywppkd.github.io/tags/npm%E6%BA%90/"}]},{"title":"虚拟主机种类","slug":"虚拟主机种类","date":"2019-05-07T12:54:33.000Z","updated":"2020-08-11T01:13:15.977Z","comments":true,"path":"2019/05/07/虚拟主机种类/","link":"","permalink":"http://wywppkd.github.io/2019/05/07/%E8%99%9A%E6%8B%9F%E4%B8%BB%E6%9C%BA%E7%A7%8D%E7%B1%BB/","excerpt":"","text":"虚拟主机种类(以nginx为例)1. 设置基于域名的虚拟主机 设置阿里云域名解析 www.aaa.com nginx所在主机的公网IP www.bbb.com nginx所在主机的公网IP 这里设置两个虚拟主机: # /etc/nginx/conf.d/aaa.conf server{ listen 80; server_name www.aaa.com; root /usr/share/nginx/html/aaa; # 网站根目录 index index.html; # 网站主页 } # /etc/nginx/conf.d/bbb.conf server{ listen 80; server_name www.bbb.com; root /usr/share/nginx/html/bbb; # 网站根目录 index index.html; # 网站主页 } www.aaa.com 返回的是aaa目录下的index.html www.bbb.com 返回的是bbb目录下的index.html 但是如果直接访问IP: 返回的是nginx设置的默认网站目录 2. 虚拟主机(基于端口)# /etc/nginx/conf.d/80.conf server{ listen 80; server_name localhost; root /usr/share/nginx/html/dir80; # 网站根目录 index index.html; # 网站主页 } # /etc/nginx/conf.d/8080.conf server{ listen 8080; server_name localhost; root /usr/share/nginx/html/dir8080; # 网站根目录 index index.html; # 网站主页 } 3. 基于IP的虚拟主机 很少用 需要一台服务器有多个IP地址, 不同IP地址对应不同虚拟主机 nginx虚拟主机配置文件1. 方式1: 修改主配置文件/nginx/conf/nginx.conf# nginx.conf http{ server{...} # 每一个server就是一个虚拟主机 server{...} server{...} } 2. 方式2(推荐): 增加单独的子配置文件/nginx/conf/conf.d/*.conf# /nginx/conf/nginx.conf 主配置文件 include /etc/nginx/conf.d/*.conf; # 设置子配置文件的目录/conf.d/ # /etc/nginx/conf.d/abc.conf 虚拟主机1 该目录下每个.conf文件都是一个虚拟主机 server{...} # /etc/nginx/conf.d/def.conf 虚拟主机2 server{...}","categories":[{"name":"nginx","slug":"nginx","permalink":"http://wywppkd.github.io/categories/nginx/"}],"tags":[{"name":"虚拟主机","slug":"虚拟主机","permalink":"http://wywppkd.github.io/tags/%E8%99%9A%E6%8B%9F%E4%B8%BB%E6%9C%BA/"},{"name":"nginx","slug":"nginx","permalink":"http://wywppkd.github.io/tags/nginx/"}]},{"title":"前端定位方法","slug":"前端定位方法","date":"2019-01-07T05:31:49.000Z","updated":"2020-08-11T01:13:15.971Z","comments":true,"path":"2019/01/07/前端定位方法/","link":"","permalink":"http://wywppkd.github.io/2019/01/07/%E5%89%8D%E7%AB%AF%E5%AE%9A%E4%BD%8D%E6%96%B9%E6%B3%95/","excerpt":"","text":"前端定位方法1. H5 定位window.navigator.geolocation.getCurrentPosition( function(position) { console.log(position.coords); // 坐标 console.log("经度", position.coords.longitude); // 经度 console.log("纬度", position.coords.latitude); // 纬度 }, function() { console.log("定位失败"); }, { timeout: 5000 } ); 2. 微信 SDK 定位 仅适用: 微信客户端 H5 <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> wx.config({ debug: false, // 开启调试模式 appId: data.appId, // 必填,企业号的唯一标识,此处填写企业号corpid timestamp: data.timestamp, // 必填,生成签名的时间戳 nonceStr: data.nonceStr, // 必填,生成签名的随机串 signature: data.signature, // 必填,签名,见附录1 jsApiList: ["getLocation"] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function() { // 获取经纬度 wx.getLocation({ type: "wgs84", // 坐标系 success: function(res) { console.log(res.latitude); // 纬度 console.log(res.longitude); // 经度 }, cancel: function(res) { alert( "定位授权失败,请进入【设置】中打开定位服务,并允许微信使用定位服务" ); }, fail: function(error) { alert("定位失败!" + error.errMsg); } }); }); 3. 支付宝 SDK 仅适用: 支付宝客户端 H5 function ready(callback) { // 如果jsbridge已经注入则直接调用 if (window.AlipayJSBridge) { callback && callback(); } else { // 如果没有注入则监听注入的事件 document.addEventListener("AlipayJSBridgeReady", callback, false); } } ready(function() { AlipayJSBridge.call("getCurrentLocation", { bizType: "didi" }, function( result ) { if (result.error) { console.log("获取定位失败"); return; } console.log("latitude", result.latitude); // 纬度 console.log("longitude", result.longitude); // 经度 }); }); 4. 高德定位<script type="text/javascript" src="http:// webapi.amap.com/maps?v=1.4.1&key=你的key"></script> var map = new AMap.Map("iCenter"); map.plugin("AMap.Geolocation", function() { geolocation = new AMap.Geolocation({ enableHighAccuracy: true, // 是否使用高精度定位,默认:true timeout: 10000, // 超过10秒后停止定位,默认:无穷大 maximumAge: 0, // 定位结果缓存0毫秒,默认:0 convert: true // 自动偏移坐标,偏移后的坐标为高德坐标,默认:true }); geolocation.getCurrentPosition(); AMap.event.addListener(geolocation, "complete", onComplete); // 返回定位信息 AMap.event.addListener(geolocation, "error", onError); // 返回定位出错信息 }); function onComplete(data) { console.log("经度" + data.position.getLng()); console.log("纬度" + data.position.getLat()); } function onError(err) { console.log("err", err); }","categories":[{"name":"定位","slug":"定位","permalink":"http://wywppkd.github.io/categories/%E5%AE%9A%E4%BD%8D/"}],"tags":[{"name":"定位","slug":"定位","permalink":"http://wywppkd.github.io/tags/%E5%AE%9A%E4%BD%8D/"},{"name":"H5","slug":"H5","permalink":"http://wywppkd.github.io/tags/H5/"},{"name":"微信","slug":"微信","permalink":"http://wywppkd.github.io/tags/%E5%BE%AE%E4%BF%A1/"},{"name":"支付宝","slug":"支付宝","permalink":"http://wywppkd.github.io/tags/%E6%94%AF%E4%BB%98%E5%AE%9D/"},{"name":"高德","slug":"高德","permalink":"http://wywppkd.github.io/tags/%E9%AB%98%E5%BE%B7/"}]},{"title":"定位技术","slug":"定位技术","date":"2019-01-07T05:29:17.000Z","updated":"2020-08-11T01:13:15.974Z","comments":true,"path":"2019/01/07/定位技术/","link":"","permalink":"http://wywppkd.github.io/2019/01/07/%E5%AE%9A%E4%BD%8D%E6%8A%80%E6%9C%AF/","excerpt":"","text":"定位技术1. 基站定位 根据手机接受不同基站的信号强弱判断两者距离, 基站密度越大越精准 优点: 定位快, 耗能小 缺点: 受基站密度影响, 受信号强弱影响 2. Wifi 定位 WiFi 信号被设备检测到, 数据库记录这个 WiFi 信号和设备对应的位置 优点: 解决室内定位问题 缺点: Wifi 数据库更新不及时 3. IP 定位 根据设备的 IP, 查询数据库, 可以粗略地知道这个 ip 所在的地理位置 缺点: 依赖数据库 4. GPS 定位(全球定位系统) 天上有 24 颗卫星, 通过 4 颗卫星位置以及卫星与设备之间的距离计算出该设备的位置 优点: 精度高 缺点: 费电, 不适合室内定位, 首次定位慢 5. AGPS 定位(辅助 GPS, 属于基站定位) GPS 定位最初使用有冷启动时间(2-3 分钟), 在此之前借助其他的定位方式(一般是基站定位)进行粗略地定位 前端常用定位方式 HTML5 定位 微信 JSSDK 定位 支付宝 JSSDK 定位 高德 JS API 定位","categories":[{"name":"定位","slug":"定位","permalink":"http://wywppkd.github.io/categories/%E5%AE%9A%E4%BD%8D/"}],"tags":[{"name":"定位","slug":"定位","permalink":"http://wywppkd.github.io/tags/%E5%AE%9A%E4%BD%8D/"}]},{"title":"地图坐标系","slug":"地图坐标系","date":"2019-01-07T05:27:55.000Z","updated":"2020-08-11T01:13:15.972Z","comments":true,"path":"2019/01/07/地图坐标系/","link":"","permalink":"http://wywppkd.github.io/2019/01/07/%E5%9C%B0%E5%9B%BE%E5%9D%90%E6%A0%87%E7%B3%BB/","excerpt":"","text":"地图坐标系地图坐标系有哪些 wgs284(地球坐标) 国际标准 gcj-02(火星坐标) 中国标准 国内出版各种地图系统, 必须至少采用 gcj-02 对地理位置进行首次加密 bg-09(百度坐标) 百度标准 百度: 在火星坐标上二次加密 开发中注意1. 目前各种 sdk 使用的坐标系 如果是百度 SDK, 默认 bd-09,或 gcj-02 如果是 iOS 原生定位, 默认 wgs284 如果是高德 sdk, 默认 gcj02 2. 目前各大地图商使用的坐标系 iOS 地图(高德) : gcj-02 国内 google 地图 : gcj-02 搜搜,阿里云,高德地图 : gcj-02 百度地图 : bd-09 国外 google 地图, 以及国外其他地图 : wgs84","categories":[{"name":"定位","slug":"定位","permalink":"http://wywppkd.github.io/categories/%E5%AE%9A%E4%BD%8D/"}],"tags":[{"name":"定位","slug":"定位","permalink":"http://wywppkd.github.io/tags/%E5%AE%9A%E4%BD%8D/"},{"name":"坐标系","slug":"坐标系","permalink":"http://wywppkd.github.io/tags/%E5%9D%90%E6%A0%87%E7%B3%BB/"}]},{"title":"开发npm包简单流程","slug":"开发npm包简单流程","date":"2018-12-04T10:40:52.000Z","updated":"2020-08-11T01:13:15.976Z","comments":true,"path":"2018/12/04/开发npm包简单流程/","link":"","permalink":"http://wywppkd.github.io/2018/12/04/%E5%BC%80%E5%8F%91npm%E5%8C%85%E7%AE%80%E5%8D%95%E6%B5%81%E7%A8%8B/","excerpt":"","text":"开发一个npm包1. 注册npm账号 https://www.npmjs.com/ 2. 配置package.json$ mkdir modal-helper $ cd modal-helper $ npm init --y # 初始化 // package.json { "name": "modal-helper", "version": "1.0.0", // 大迭代.功能叠加.修复bug "description": "防止弹框滚动穿透的一种解决方式", // 描述信息 "main": "index.js", // 入口文件名 "scripts": { "test": "echo \\"Error: no test specified\\" && exit 1" // 测试命令(可以不写) }, "repository": { "type": "git", "url": "git+https://github.com/wywppkd/modal-helper.git" // github仓库地址 }, "keywords": [ // 关键词 "关键词1", "关键词2", "关键词3" ], "author": "wywppkd", // 作者 "license": "MIT", // 开源协议 "bugs": { "url": "https://github.com/wywppkd/modal-helper/issues" }, "homepage": "https://github.com/wywppkd/modal-helper#readme" } name包命名规范 不能以点或下划线开头 不能包含大写字母 不能包含任何非URL安全字符(因为包名最终会成为URL的一部分) 小于或等于214个字符 不可以与现有包名类似: 与react-native包冲突的命名 reactnative react_native eact.native 推荐命名: 普通命名: modal-helper 作用域命名: @wywppkd/modal-helper 4. 开发你的包…5. 将开发的代码上传到npm官方服务器 注意需要保证npm源为官方地址 $ npm login # 登录npm账户 # 输入账户密码邮箱 $ npm publish # 上传代码(普通包名) $ npm publish --access=public # 上传代码(如果是作用域命名的包@wywppkd/modal-helper) 尝试下载$ npm install modal-helper --save # 下载 # 整个目录下文件都会下载至node_modules/modal-helper 迭代npm包 每次迭代后必须修改package.json的version(版本号)属性","categories":[{"name":"npm","slug":"npm","permalink":"http://wywppkd.github.io/categories/npm/"}],"tags":[{"name":"npm","slug":"npm","permalink":"http://wywppkd.github.io/tags/npm/"},{"name":"开发npm包","slug":"开发npm包","permalink":"http://wywppkd.github.io/tags/%E5%BC%80%E5%8F%91npm%E5%8C%85/"}]},{"title":"AMD规范-require.js使用","slug":"AMD规范-require-js使用","date":"2018-06-23T07:45:24.000Z","updated":"2020-08-11T01:13:15.964Z","comments":true,"path":"2018/06/23/AMD规范-require-js使用/","link":"","permalink":"http://wywppkd.github.io/2018/06/23/AMD%E8%A7%84%E8%8C%83-require-js%E4%BD%BF%E7%94%A8/","excerpt":"","text":"AMD规范 主要实践者: require.js require.config()指定引用路径等 define()定义模块 require()加载模块 define()定义一个普通AMD模块// math.js define(function(){ var add = function(x,y){ return x+y; } return { add: add } }) require()加载模块 在html页面中加载主模块 <script src="js/require.js" data-main="js/main"></script> <!-- data-main属性: 指定主模块, js/main.js 这个文件会被require.js第一个加载 --> 在主模块/js/main.js中配置依赖模块 // /js/main.js // 配置项: 可以指定模块文件的路径 require.config({ baseUrl: "js/lib",// 所有模块都从该路径下加载 paths: { "jquery": "jquery.min", "underscore": "underscore.min", "backbone": "backbone.min" } }); // AMD规范的require()函数 // 第一个参数: 数组(表示依赖的模块) // 第二个参数: 回调函数(当前面指定的模块加载成功后调用) require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){ // require.js会先加载jQuery、underscore和backbone,然后再运行回调函数 // 主模块代码就写在这个回调函数中 });","categories":[{"name":"js模块化","slug":"js模块化","permalink":"http://wywppkd.github.io/categories/js%E6%A8%A1%E5%9D%97%E5%8C%96/"}],"tags":[{"name":"js模块化","slug":"js模块化","permalink":"http://wywppkd.github.io/tags/js%E6%A8%A1%E5%9D%97%E5%8C%96/"},{"name":"AMD","slug":"AMD","permalink":"http://wywppkd.github.io/tags/AMD/"},{"name":"require.js","slug":"require-js","permalink":"http://wywppkd.github.io/tags/require-js/"}]},{"title":"ES6模块化","slug":"ES6模块化","date":"2018-06-17T06:34:12.000Z","updated":"2020-08-11T01:13:15.967Z","comments":true,"path":"2018/06/17/ES6模块化/","link":"","permalink":"http://wywppkd.github.io/2018/06/17/ES6%E6%A8%A1%E5%9D%97%E5%8C%96/","excerpt":"","text":"ES6 Module 主要由两个命令构成: export import 编译时就引入模块代码, 而不是运行时加载 无法实现条件加载, 可以实现静态分析 export导出(推荐)// 导出写法一 export var name = "Tom"; // 导出变量 export function say() { // 导出函数 console.log("say something") }; // 导出写法二(推荐) var name = "Tom"; var say = function(){ console.log("say something") } export { name, say } // 导入写法一(选择性导入) import {name,say} from "./app.js" console.log(name) console.log(say()) // 导入写法二(一次加载所有方法) import * as app from "./app.js" console.log(app.name) console.log(app.say()) export default导出 一个模块只能使用一个export default// 导出一个变量 export default function say(){ console.log("say something") } // 导出多个变量 var name = “Tom” var say = function(){ console.log(“say something”) } export default { name, say }; // 导入import app from ‘./app.js’ #### export和export default区别 1. 一个模块中, export可以有多个, export default只能有一个 2. export可以导出变量表达式, 而export default不行 ```js export const a = '100'; // 正确 export defult const a = '100'; // 错误, 将变量a赋值给变量default // export default其实是输出了一个叫default的变量, 所以后面不能跟变量声明语句 export不能直接输出变量, export default可以 export和export default对应的导入方式不同 import详解 import在编译阶段会提升到模块顶部 import导入的模块是只读的, 不允许改写// import可以省略文件后缀 import math from 'math.js' // ==> import math from 'math' // 导入math.js文件时, 可以省略文件后缀 // import可以省略index.js文件名 import math from ‘mathDir/index.js’ // ==> import math from ‘mathDir’ // 导入mathDir/index.js文件时, 可以省略文件名 // import支持起别名 import {math as myMath} from ‘./math’ // 必须是export导出的方式 --- ### 扩展: export和import同时使用实现转发 - 同时导入并导出一个模块 ```js // 从my_module中导入foo和bar, 同时导出这两个方法 // 实现了转发的效果, 注意当前模块不能使用foo和bar export { foo, bar } from 'my_module'; // 可以简单理解为 import { foo, bar } from 'my_module'; // 导入 export { foo, bar }; // 导出应用: 在框架中常见用法: 跨模块常量 项目中使用的常量可以统一在constants目录下管理. ├── constants // 该目录下放置了一些模块 | ├── db.js // 数据库账户信息 | ├── user.js // 用户信息 | └── index.js // 合并当目录constants下所有模块, 并导出所有 └── xxx.js // 在其他文件中使用这些常量 // constants/db.js 数据库账户信息 export const db = { url: ‘http://my.couchdbserver.local:5984', admin_username: ‘admin’, admin_password: ‘admin password’ }; // constants/user.js 用户信息 export const users = [‘root’, ‘admin’, ‘staff’, ‘ceo’, ‘chief’, ‘moderator’]; // constants/index.js 导入db,users模块, 并一次性导出 export {db} from ‘./db’; export {users} from ‘./users’; // xxx.js import {db, users} from ‘./constants/index’;","categories":[{"name":"js模块化","slug":"js模块化","permalink":"http://wywppkd.github.io/categories/js%E6%A8%A1%E5%9D%97%E5%8C%96/"}],"tags":[{"name":"js模块化","slug":"js模块化","permalink":"http://wywppkd.github.io/tags/js%E6%A8%A1%E5%9D%97%E5%8C%96/"},{"name":"ES6","slug":"ES6","permalink":"http://wywppkd.github.io/tags/ES6/"},{"name":"export","slug":"export","permalink":"http://wywppkd.github.io/tags/export/"},{"name":"import","slug":"import","permalink":"http://wywppkd.github.io/tags/import/"}]},{"title":"CommonJS模块化规范","slug":"CommonJS模块化规范","date":"2018-06-13T11:43:27.000Z","updated":"2020-08-11T01:13:15.965Z","comments":true,"path":"2018/06/13/CommonJS模块化规范/","link":"","permalink":"http://wywppkd.github.io/2018/06/13/CommonJS%E6%A8%A1%E5%9D%97%E5%8C%96%E8%A7%84%E8%8C%83/","excerpt":"","text":"CommonJS 主要实践者: Node 包含四个环境变量: module exports require global CommonJS是同步加载模块 适合场景: 服务端读取本地磁盘非常快, 所以很适合该规范 而浏览器端受限网络, 更适合异步加载 CommonJS模块导出// app.js // 一个一个导出 module.exports.name = "Tom"; module.exports.say = function(){ console.log("say something") } // 整体导出 var name = "Tom"; function say(){ console.log("say something") } module.exports = { name: name, say: say } CommonJS模块导入// main.js // 导入 const app = require('./app'); // 可以省略文件后缀 console.log(app.name) console.log(app.say()) exports 和 module.exports的区别 node执行一个文件时, 会生成一个exports和module对象 而module又有一个exports属性, 他们都指向一块内存区域 exports === module.exports 当添加exports.a=200, module.exports同时享有属性a 最终require()导入的是module.exports 可以看出exports是辅助module.exports操作内存中的数据用的; 建议: 为了防止混乱, 不推荐使用exports, 建议只使用module.exports require详解当Node执行遇到require(x) 如果x是核心模块: 如require(‘fs’) 返回该模块 如果x以”./“,”/“,”../“开头 根据x所在父模块, 确定x的绝对路径 将x当成文件, 依次查找下面文件 x x.js x.json x.node 如果没找到, 则把x当成目录, 依次查找下面的文件 x/package.json(main字段) x/index.js x/index.json x/index.node 如果x不带路径, 并且也不是核心模块 根据x所在父模块(也就是使用require(x)的模块), 确认x可能的安装目录 依次在每个目录下, 将x当前文件名和目录名从node_modules目录下加载 // require常见用法 const fs = require('fs'); // 核心模块 const math = require('./math'); // 自定义模块, 当前目录下的math.js文件 const vue = require('vue'); // node_modules目录下的第三方包","categories":[{"name":"js模块化","slug":"js模块化","permalink":"http://wywppkd.github.io/categories/js%E6%A8%A1%E5%9D%97%E5%8C%96/"}],"tags":[{"name":"js模块化","slug":"js模块化","permalink":"http://wywppkd.github.io/tags/js%E6%A8%A1%E5%9D%97%E5%8C%96/"},{"name":"CommonJS","slug":"CommonJS","permalink":"http://wywppkd.github.io/tags/CommonJS/"},{"name":"Node","slug":"Node","permalink":"http://wywppkd.github.io/tags/Node/"},{"name":"module.exports","slug":"module-exports","permalink":"http://wywppkd.github.io/tags/module-exports/"},{"name":"require","slug":"require","permalink":"http://wywppkd.github.io/tags/require/"}]},{"title":"js模块化介绍","slug":"js模块化介绍","date":"2018-06-05T08:37:56.000Z","updated":"2020-08-11T01:13:15.969Z","comments":true,"path":"2018/06/05/js模块化介绍/","link":"","permalink":"http://wywppkd.github.io/2018/06/05/js%E6%A8%A1%E5%9D%97%E5%8C%96%E4%BB%8B%E7%BB%8D/","excerpt":"","text":"什么是模块化 通常一个文件是一个模块,有自己的作用域,只对外暴露特定变量和函数 为什么使用模块化 代码复用 解决依赖关系, 利于维护 避免全局变量污染 JS模块化规范有哪些: IIFE(早期): 立即执行的匿名函数, 就是一个模块, 匿名函数内部变量不会污染全局对象 CommonJS ES6 Module AMD CMD CommonJS 主要实践者: Node 包含四个环境变量: module exports require global CommonJS是同步加载模块 适合场景: 服务端读取本地磁盘非常快, 所以很适合该规范 而浏览器端受限网络, 更适合异步加载 ES6 Module 主要由两个命令构成: export import 编译时就引入模块代码, 而不是运行时加载 无法实现条件加载, 可以实现静态分析 ES6 Module与CommonJS的差异 CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用。 CommonJS模块是运行时加载,ES6模块是编译时加载(所以import存在变量提升) 运行时加载: CommonJS模块就是对象(即module.exports属性) 编译时加载: ES6模块不是对象,而是通过export命令显式指定输出的代码,import时采用静态命令的形式。即在import时可以指定加载某个输出 值,而不是加载整个模块,这种加载称为“编译时加载” require支持动态加载, 而import不支持 AMD规范 主要实践者: require.js require.config()指定引用路径等 define()定义模块 require()加载模块 CMD规范 主要实践者: sea.js define()定义模块 use()加载模块 require.js和sea.js异同 相同点:requirejs 和 seajs 都是异步加载模块的 不同: requirejs 特点是依赖前置,指的是所有依赖提前加载完成 seajs 特点是就近依赖,指的就是:什么时候用某个模块,那么就什么时候去加载这个模块 但是实际使用中,sea.js也是提前加载完依赖模块, 才执行function,也就跟require.js没什么区别了","categories":[{"name":"js模块化","slug":"js模块化","permalink":"http://wywppkd.github.io/categories/js%E6%A8%A1%E5%9D%97%E5%8C%96/"}],"tags":[{"name":"js模块化","slug":"js模块化","permalink":"http://wywppkd.github.io/tags/js%E6%A8%A1%E5%9D%97%E5%8C%96/"},{"name":"AMD","slug":"AMD","permalink":"http://wywppkd.github.io/tags/AMD/"},{"name":"CommonJS","slug":"CommonJS","permalink":"http://wywppkd.github.io/tags/CommonJS/"},{"name":"ES6 Module","slug":"ES6-Module","permalink":"http://wywppkd.github.io/tags/ES6-Module/"},{"name":"CMD","slug":"CMD","permalink":"http://wywppkd.github.io/tags/CMD/"}]},{"title":"npm常用操作","slug":"npm常用操作","date":"2018-05-04T07:06:15.000Z","updated":"2020-08-11T01:13:15.970Z","comments":true,"path":"2018/05/04/npm常用操作/","link":"","permalink":"http://wywppkd.github.io/2018/05/04/npm%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/","excerpt":"","text":"npm更新$ npm install npm@latest -g # 更新npm到稳定版 $ npm install npm@next -g # 更新npm开发版 注意:npm下载模块的时候不要用鼠标点命令行, 容易导致下载阻塞 如果下载阻塞了, 按下Esc可恢复下载 npm包管理# 全局 # 安装 $ npm i -g eslint # 展示需要更新的模块 $ npm outdated -g --depth=0 # 更新指定模块 $ npm update -g eslint # 卸载指定模块 $ npm uninstall -g eslint # 查看所有全局安装的模块 $ npm ls -g # 查看全局路径目录 $ npm config get prefix # 修改全局路径目录 $ npm config set prefix "./目录路径" # 本地 # 安装 $ npm i eslint $ npm install eslint@latest # 更新到最新版 $ npm install [email protected] # 更新或回退到指定版本 # 展示需要更新的模块 $ npm outdated # 更新指定模块 $ npm update eslint # 更新所有模块 $ npm update # 查看所有本地安装的模块 $ npm ls # 查看单个模块的具体信息 $ npm ls eslint # 卸载指定模块 $ npm uninstall eslint # 缓存 # 清除本地缓存 $ npm cache clean -f #-f 强制 -force # 优先从缓存下载 $ npm install webpack --cache-min 99999","categories":[{"name":"npm","slug":"npm","permalink":"http://wywppkd.github.io/categories/npm/"}],"tags":[{"name":"npm","slug":"npm","permalink":"http://wywppkd.github.io/tags/npm/"},{"name":"npm常用操作","slug":"npm常用操作","permalink":"http://wywppkd.github.io/tags/npm%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/"}]},{"title":"小程序格式化金额输入","slug":"小程序格式化金额输入","date":"2018-03-07T11:15:43.000Z","updated":"2020-08-11T01:13:15.974Z","comments":true,"path":"2018/03/07/小程序格式化金额输入/","link":"","permalink":"http://wywppkd.github.io/2018/03/07/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%A0%BC%E5%BC%8F%E5%8C%96%E9%87%91%E9%A2%9D%E8%BE%93%E5%85%A5/","excerpt":"","text":"金额输入限制条件 参考支付宝|微信支付的时候输入金额的限制 只能输入0-9和小数点”.” 首位不能出现两个0 第二位不是小数点”.”的情况下, 首位不能是0 首位不能出现小数点”.” 小数点”.”只能出现一次 小数点”.”后最多两位 Page({ // 格式化输入的金额 formatAmount(val) { let num = val.toString(); // 先转换成字符串类型 if (num.indexOf('.') == 0) { // 第一位就是".", 则前面补0 num = '0' + num } num = num.replace(/[^\\d.]/g, ""); // 清除"数字"和"."以外的字符 num = num.replace(/\\.{2,}/g, "."); // 只保留第一个"."清除多余的 num = num.replace(".", "$#$").replace(/\\./g, "").replace("$#$", "."); num = num.replace(/^(\\-)*(\\d+)\\.(\\d\\d).*$/, '$1$2.$3'); // 小数点后只能输入两位 if (num.indexOf(".") < 0 && num != "") { num = parseFloat(num); } return num }, // input输入事件 inputEvent(e){ this.setData({ oilAmount: this.formatAmount(e.detail.value) // money匹配金额输入规则,返回输入值 }); } })","categories":[{"name":"小程序","slug":"小程序","permalink":"http://wywppkd.github.io/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"}],"tags":[{"name":"小程序","slug":"小程序","permalink":"http://wywppkd.github.io/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"},{"name":"金额输入","slug":"金额输入","permalink":"http://wywppkd.github.io/tags/%E9%87%91%E9%A2%9D%E8%BE%93%E5%85%A5/"}]},{"title":"命令行切换小程序开发环境","slug":"命令行切换小程序开发环境","date":"2018-03-03T07:28:42.000Z","updated":"2020-08-11T01:13:15.972Z","comments":true,"path":"2018/03/03/命令行切换小程序开发环境/","link":"","permalink":"http://wywppkd.github.io/2018/03/03/%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%88%87%E6%8D%A2%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/","excerpt":"","text":"命令行切换小程序开发环境 只需要使用node+npm, 就可以实现切换小程序的开发环境 实现思路: 使用npm脚本(npm scripts)指定node脚本main.js. 并根据参数, 将指定的configs/xxx.js配置文件内容读取并写入到当前使用的配置文件ext.js中 目录介绍├── configs // 不同环境的配置文件都在这个目录 │ │── ext.test120001.js // 测试环境1 │ │── ext.test120002.js // 测试环境2 │ │── ext.dev120001.js // 开发环境1 │ │── ext.dev120002.js // 开发环境2 │ │── ext.prod120001.js // 生产环境1 │ └── ext.prod120002.js // 生产环境2 │ │── ext.js // 当前使用的配置文件 │── app.js // 小程序的app.js │── main.js // node执行脚本 └── package.json // package.json配置文件 /config/ext.test120001.js 示例// /config/ext.test120001.js 示例 export default { "blockId": "120001",// 自定义参数 "baseURL": "https://test.yourdomain.com",// 接口地址 "defaultTitle": "y约油-测试" // 小程序首页title } 小程序app.js文件// app.js import extJson from './ext.js'; App({ globalData:{ extJson // ext.js中的环境配置参数 } }) node脚本main.js// main.js const process = require('process') const fs = require('fs') //文件读取和写入 const arr = process.argv // 命令行参数[] const NODE_ENV = arr[2] // node命令第3个参数 // 各个环境对应的小程序名称 const configs = { 'dev120001': '开发小程序1', 'dev120002': '开发小程序2', 'test120001': '测试小程序1', 'test120002': '测试小程序2', 'prod120001': '生产小程序1', 'prod120002': '生产小程序2' } if (NODE_ENV) { let read = fs.readFileSync(`./configs/ext.${NODE_ENV}.js`, 'utf-8') fs.writeFile('./ext.js', read, 'utf-8', err => { if (err) { console.error(`切换环境${NODE_ENV}失败`) } else { console.log(`切换环境${NODE_ENV}成功, 请切换小程序至==>${configs[NODE_ENV]}`) } }) } package.json{ "scripts": { "test120001": "node ./main.js test120001", "test120002": "node ./main.js test120002", "dev120001": "node ./main.js dev120001", "dev120002": "node ./main.js dev120002", "prod120001": "node ./main.js prod120001", "prod120002": "node ./main.js prod120002" } } 命令行切换环境$ npm run dev120001 # 切换到开发环境1 $ npm run dev120002 # 切换到开发环境2 $ npm run test120001 # 切换到测试环境1 $ npm run test120002 # 切换到测试环境2 $ npm run prod120001 # 切换到生产环境1 $ npm run prod120001 # 切换到生产环境2","categories":[{"name":"小程序","slug":"小程序","permalink":"http://wywppkd.github.io/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"}],"tags":[{"name":"小程序","slug":"小程序","permalink":"http://wywppkd.github.io/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"},{"name":"Node","slug":"Node","permalink":"http://wywppkd.github.io/tags/Node/"},{"name":"开发环境","slug":"开发环境","permalink":"http://wywppkd.github.io/tags/%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/"}]},{"title":"如何找到公众号的推荐关注链接","slug":"如何找到公众号的推荐关注链接","date":"2017-12-31T06:42:18.000Z","updated":"2020-08-11T01:13:15.973Z","comments":true,"path":"2017/12/31/如何找到公众号的推荐关注链接/","link":"","permalink":"http://wywppkd.github.io/2017/12/31/%E5%A6%82%E4%BD%95%E6%89%BE%E5%88%B0%E5%85%AC%E4%BC%97%E5%8F%B7%E7%9A%84%E6%8E%A8%E8%8D%90%E5%85%B3%E6%B3%A8%E9%93%BE%E6%8E%A5/","excerpt":"","text":"操作步骤 从目标公众号下随便找一篇公众号文章, 推荐给朋友, 用PC端浏览器打开这篇文章 文章侧边有一个关注二维码, 右键二维码在新标签中打开 从地址栏的链接中找到__biz参数的值 复制这个参数值, 替换到下面这条链接的__biz参数值, 就得到了目标公众的推荐关注链接 https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzAxODE2MjM1MA==&scene=126#wechat_redirect 搞定收工~","categories":[{"name":"微信公众号","slug":"微信公众号","permalink":"http://wywppkd.github.io/categories/%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%8F%B7/"}],"tags":[{"name":"微信公众号","slug":"微信公众号","permalink":"http://wywppkd.github.io/tags/%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%8F%B7/"},{"name":"关注链接","slug":"关注链接","permalink":"http://wywppkd.github.io/tags/%E5%85%B3%E6%B3%A8%E9%93%BE%E6%8E%A5/"}]},{"title":"Axios之Content-Type","slug":"Axios之Content-Type","date":"2017-11-07T13:20:48.000Z","updated":"2020-08-11T01:13:15.965Z","comments":true,"path":"2017/11/07/Axios之Content-Type/","link":"","permalink":"http://wywppkd.github.io/2017/11/07/Axios%E4%B9%8BContent-Type/","excerpt":"","text":"Axios之Content-Type Content-Type属性不需要手动设置: Axios会根据post请求的data数据类型, 自动设置Content-Type Axios会自动设置Content-Type1. 默认值application/json 场景: 请求数据data为对象时, 不需要任何处理 axios({ url:"/loadData", method:"post", data:{ name:"tom" } }).then(res => { console.log(res) }) 2. application/x-www-form-urlencoded 场景: 当请求数据data为字符串或URLSearchParams对象时 URLSearchParams API var params = new URLSearchParams(); params.append('param1', 'value1'); params.append('param2', 'value2'); axios({ url:"/loadData", method:"post", data:params }).then(res =>{ console.log(res) }) 使用qs库将对象转成查询字符串 import Qs from 'qs'; let data = Qs.stringify({name:"Tom"}) axios({ url:"/loadData", method:"post", data:data }).then(res => { console.log(res) }) 3. multipart/form-data 场景: 上传文件时, 请求数据data转为FormData类型时 let params = new FormData(); params.append("name", "Tom"); dparamsata.append("age", "18"); axios({ url:"/loadData", method:"post", data:params }).then(res =>{ console.log(res) }) 如果一定要使用application/x-www-form-urlencoded 处理: 统一将data数据格式化为查询字符串 缺点: 所有post请求都会使用application/x-www-form-urlencoded, 如果需要Content-Type其他类型时就需要单独处理请求了, 比如上传文件时需要使用multipart/form-data; let instance = axios.create({ // 发送前, 修改请求数据, Content-Type会根据修改后的数据自动设置 transformRequest: [ function(data, headers) { return Qs.stringify(data); } ] }); 建议: 与后端沟通一致, 统一使用application/json类型 不影响使用multipart/form-data类型上传文件 并且json数据类型对于多层嵌套的数据更友好","categories":[{"name":"axios","slug":"axios","permalink":"http://wywppkd.github.io/categories/axios/"}],"tags":[{"name":"Content-Type","slug":"Content-Type","permalink":"http://wywppkd.github.io/tags/Content-Type/"},{"name":"axios","slug":"axios","permalink":"http://wywppkd.github.io/tags/axios/"}]},{"title":"Content-Type介绍","slug":"Content-Type介绍","date":"2017-10-18T12:22:45.000Z","updated":"2020-08-11T01:13:15.966Z","comments":true,"path":"2017/10/18/Content-Type介绍/","link":"","permalink":"http://wywppkd.github.io/2017/10/18/Content-Type%E4%BB%8B%E7%BB%8D/","excerpt":"","text":"Content-Type介绍请求头中的Content-Type 作用: 告诉服务器实际发送的数据类型 常见类型: application/x-www-form-urlencoded; multipart/form-data; 常用于上传文件, 支持二进制格式 application/json; text/plain; 很少用 响应头中的Content-Type 告诉客户端实际返回的内容的内容类型 常见类型: application/json; text/html; text/plain; image/png; application/octet-stream; 文件下载","categories":[{"name":"HTTP","slug":"HTTP","permalink":"http://wywppkd.github.io/categories/HTTP/"}],"tags":[{"name":"HTTP","slug":"HTTP","permalink":"http://wywppkd.github.io/tags/HTTP/"},{"name":"Content-Type","slug":"Content-Type","permalink":"http://wywppkd.github.io/tags/Content-Type/"}]},{"title":"获取URL参数的几种方式","slug":"获取URL参数的几种方式","date":"2017-10-14T10:36:14.000Z","updated":"2020-08-11T01:13:15.977Z","comments":true,"path":"2017/10/14/获取URL参数的几种方式/","link":"","permalink":"http://wywppkd.github.io/2017/10/14/%E8%8E%B7%E5%8F%96URL%E5%8F%82%E6%95%B0%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/","excerpt":"","text":"通过URLSearchParams对象function getParam(name){ let params = new URLSearchParams(location.search); return params.get(name); } // URLSearchParams常用实例方法 // https://www.google.com/search?q=JavaScript&source=chrome const params = new URLSearchParams(location.search); params.has("q"); // true 是否有q参数 params.get("q"); // "JavaScript" params.append('q', "React") // 增加参数 params.getAll("q"); // ["JavaScript","React"]查找key为'q'的所有值, 返回一个数组 params.delete('q') // 删除所有参数q 通过match()+正则function getQueryString(name) { var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'); var r = location.search.substr(1).match(reg); if (r != null) { return decodeURIComponent(r[2]); } return null; }","categories":[{"name":"JavaScript","slug":"JavaScript","permalink":"http://wywppkd.github.io/categories/JavaScript/"},{"name":"URL","slug":"JavaScript/URL","permalink":"http://wywppkd.github.io/categories/JavaScript/URL/"}],"tags":[{"name":"URL","slug":"URL","permalink":"http://wywppkd.github.io/tags/URL/"},{"name":"URLSearchParams","slug":"URLSearchParams","permalink":"http://wywppkd.github.io/tags/URLSearchParams/"}]},{"title":"常用时间方法汇总","slug":"常用时间方法汇总","date":"2016-03-04T09:47:23.000Z","updated":"2020-08-11T01:13:15.975Z","comments":true,"path":"2016/03/04/常用时间方法汇总/","link":"","permalink":"http://wywppkd.github.io/2016/03/04/%E5%B8%B8%E7%94%A8%E6%97%B6%E9%97%B4%E6%96%B9%E6%B3%95%E6%B1%87%E6%80%BB/","excerpt":"","text":"先了解Date对象一些原生方法var oDate = new Date() //获取Date对象的某值 console.log(oDate.getFullYear()); //年(以四位数字返回年份) console.log(oDate.getMonth()+1); //月(0 ~ 11) console.log(oDate.getDate()); //日(1 ~ 31) console.log(oDate.getHours()); //时(0 ~ 23) console.log(oDate.getMinutes()); //分(0 ~ 59) console.log(oDate.getSeconds()); //秒(0 ~ 59) console.log(oDate.getMilliseconds()); //毫秒值(0 ~ 999) console.log(oDate.getDay()); //周几(0 ~ 6) console.log(oDate.toDateString()); //将Date对象的日期部分转成字符串(通常用来对比时间是否相同) console.log(oDate.toTimeString()); //将Date对象的时间部分转成字符串 //设置Date对象的某值 oDate.setDate() // 月的某一天 (1 ~ 31)。 oDate.setMonth() // 月份 (0 ~ 11)。 oDate.setFullYear() // 年(四位数字)。 oDate.setHours() // 时 (0 ~ 23)。 oDate.setMinutes() // 分 (0 ~ 59)。 oDate.setSeconds() // 秒 (0 ~ 59)。 oDate.setMilliseconds() // 毫秒值 (0 ~ 999)。 Date对象与时间戳相互转换(3种方法)// Date获取时间戳 Date.parse(new Date()); //只能精确到秒 oDate.getTime(); oDate.valueOf(); // 时间戳转Date对象 oDate.setTime() 时间格式化常用方法 时间戳转固定时间格式 /** * 最常用 * 时间戳 => 2017-12-05 15:55:32 */ function formatTime(s){ var fix = function(num){ return ('' + num).length < 2 ? ((new Array(3)).join('0') + num).slice(-2) : '' + num; } var time = new Date(s); return time.getFullYear()+"-"+fix(time.getMonth()+1)+"-"+fix(time.getDate())+" "+fix(time.getHours())+":"+fix(time.getMinutes())+":"+fix(time.getSeconds()); } /** * 今天星期['日','一','二','三','四','五','六'] */ function severalWeek(){ var arr = ['日','一','二','三','四','五','六']; var severalWeek = new Date(); return arr[severalWeek.getDay()]; } /** * 时间戳 => 2017.12.26 星期二 09:44 */ function formatTime(s){ var fix = function(num){ return ('' + num).length < 2 ? ((new Array(3)).join('0') + num).slice(-2) : '' + num; } var time = new Date(s); var arr = ['日','一','二','三','四','五','六']; day = arr[time.getDay()]; return time.getFullYear()+"."+fix(time.getMonth()+1)+"."+fix(time.getDate())+" 星期"+day+" "+fix(time.getHours())+":"+fix(time.getMinutes()); } /** * 时间戳 => ['今天','昨天','周x'] */ function orderTime(str){ var d = new Date(str); var todaysDate = new Date(); var yestdayDate = new Date(new Date()-24*3600*1000); if(d.toDateString() == todaysDate.toDateString()){ return "今天" }else if(d.toDateString() == yestdayDate.toDateString()){ return "昨天" }else{ var arr = ['周日','周一','周二','周三','周四','周五','周六']; var week = new Date(str); return arr[week.getDay()]; } } /** * 时间戳 => ['刚刚','x分钟前','x小时前','x天前','x个月前','x年前'] */ function formatPassTime(startTime) { var currentTime = Date.parse(new Date()), time = currentTime - startTime, day = parseInt(time / (1000 * 60 * 60 * 24)) hour = parseInt(time / (1000 * 60 * 60)) min = parseInt(time / (1000 * 60)) month = parseInt(day / 30) year = parseInt(month / 12) if (year) return year + "年前" if (month) return month + "个月前" if (day) return day + "天前" if (hour) return hour + "小时前" if (min) return min + "分钟前" else return '刚刚' } /** * 时间戳 => ['今天','昨天','mm:ss','MM-DD'] */ function orderTime(str){ var fix = function(num){ return ('' + num).length < 2 ? ((new Array(3)).join('0') + num).slice(-2) : '' + num; } var d = new Date(str); var todaysDate = new Date(); var yestdayDate = new Date(new Date()-24*3600*1000); if(d.toDateString() == todaysDate.toDateString()){ return fix(d.getHours())+":"+fix(d.getMinutes()) }else if(d.toDateString() == yestdayDate.toDateString()){ return fix(d.getHours())+":"+fix(d.getMinutes()) }else{ return fix(d.getMonth()+1)+"-"+fix(d.getDate()) } } 距离截止日期还有x天 x小时 x分钟 x秒 /** * 距离截止日期还有x天 hh:mm:ss (自动更新) * 截止日期endTime(时间戳) => 倒计时剩余:n天 hh:mm:ss */ function showRemainTime(endTime) { var fix = function(num){ return ('' + num).length < 2 ? ((new Array(3)).join('0') + num).slice(-2) : '' + num; } var nowtime = new Date(); var endtime = new Date(endTime);//截止时间 var timeLag = Math.floor((endtime.getTime() - nowtime.getTime()) / 1000); var d = Math.floor(timeLag / (24 * 60 * 60)); var h = Math.floor(timeLag / (60 * 60) % 24); var m = Math.floor(timeLag / 60 % 60); var s = Math.floor(timeLag % 60); h = fix(h); m = fix(m); s = fix(s); console.log("倒计时剩余" + d + "天 " + h + ":" + m + ":" + s); if(timeLag<=0){ console.log("活动已结束"); return; } setTimeout(showRemainTime,1000,endTime);//1秒后获取当前时间,计算并更新剩余多少时间 } 判断是不是某一天 /** * n天(前|后)的时间 * 时间戳 => n天(前|后)的时间戳 */ var newTime = new Date()-24*3600*1000; // 昨天 var newTime = new Date()-24*3600*1000*2; // 前天 var newTime = new Date()-24*3600*1000*3; // 3天前 var newTime = new Date().getTime()+24*3600*1000; // 明天 var newTime = new Date().getTime()+24*3600*1000*2; // 后天 var newTime = new Date().getTime()+24*3600*1000*3; // 3天后 /** 是不是今天 时间戳 => (是|不是) /function isToday(str){ var d = new Date(str); var todaysDate = new Date(); if(d.toDateString() == todaysDate.toDateString()){ //将需要检测的时间和当前时间的时,分,秒,毫秒分别设置为0,然后对比年月日是否相同return true; } else {return false; }} /** 是不是昨天 ‘2016-06-06 06:06:06’ => (是|不是) /function isYestday(str){ var d = new Date(str); var yestdayDate = new Date(new Date()-2436001000); if(d.toDateString() == yestdayDate.toDateString()){return true; } else {return false; }} 时间排序/** * 时间排序(数组) * in: ['2018-03-05', '2013-06-12','2019-03-12','2018-03-05','2014-02-22'] * out:["2013-06-12", "2014-02-22", "2018-03-05", "2018-03-05", "2019-03-12"] */ var arr = ['2018-03-05', '2013-06-12','2019-03-12','2018-03-05','2014-02-22']; arr.sort(function(a,b){return new Date(a)-new Date(b)}); console.log(arr);//["2013-06-12", "2014-02-22", "2018-03-05", "2018-03-05", "2019-03-12"] iOS端不支持”2018-08-08 11:11:11”需要转换为”2018/08/08 11:11:11”var d = new Date(str.replace(/-/g,"/"));","categories":[{"name":"JavaScript","slug":"JavaScript","permalink":"http://wywppkd.github.io/categories/JavaScript/"}],"tags":[{"name":"Date","slug":"Date","permalink":"http://wywppkd.github.io/tags/Date/"},{"name":"时间格式化","slug":"时间格式化","permalink":"http://wywppkd.github.io/tags/%E6%97%B6%E9%97%B4%E6%A0%BC%E5%BC%8F%E5%8C%96/"}]}]}