amenzai / mydiary Goto Github PK
View Code? Open in Web Editor NEWRecord what you do every day
Record what you do every day
2、dialog
HTML 5.2 新增了 元素,这个元素将来一定会广泛使用,因为它提供了浏览器原生 Modal 窗口。
3、[Optimizing React: Virtual DOM explained, by Evil] Martians(https://evilmartians.com/chronicles/optimizing-react-virtual-dom-explained)
React 的虚拟 DOM 机制的详细解释, JSX 代码如何变成虚拟 DOM 的数据结构。
分布式系统的基本概念和基本知识,这篇文章都谈到了。
这篇文章针对初学者,介绍 Array、HashMaps、Sets、Linked Lists、Stacks、Queues 这六种数据结构的 JavaScript 实现。
7、Eloquent JavaScript 3rd edition 中文版
一本开源的 JavaScript 语言的入门教材。
不要用 git push --force,而要用 git push --force-with-lease 代替。在你上次提交之后,只要其他人往该分支提交给代码,git push --force-with-lease 会拒绝覆盖。
node -v
npm -v
验证是否安装成功npm install -g vue-cli
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install -g vue-cli
vue init webpack vue-demo
cd vue-demo
npm install or cnpm install
npm run dev
记住这些用于页面跳转的:
<router-link :to="'/home/:id'"></router-link>
<router-link :to="{path:'/home/login',query:{name:'tom'}}"></router-link>
<router-link :to="{path:'/home/login',params:{id:1}}"></router-link>
//参数可以是字符串或对象
this.$router.push()
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state,
mutations: {
UPDATE_LOADING(state, status) {
state.loading = status
}
},
actions: {
ToggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
addVisitedViews({ commit }, view) {
commit('ADD_VISITED_VIEWS', view)
},
delVisitedViews({ commit, state }, view) {
return new Promise((resolve) => {
commit('DEL_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
}
}
})
父组件向子组件:props
props:['data']
子组件向父组件:父组件自定义事件,子组件$emit
触发事件
this $emit('eventName',data)
keep-alive 将组件保留在内存中,避免重新渲染
slot在子组件设置个插槽,这样父组件在调用时可以用其他结构替换。
子组件中:
<slot name="btn"></slot>
父组件:
<children-component>
<button slot="btn"></button>
</children-component>
JavaScript语言采用的是单线程模型,也就是说,所有任务排成一个队列,一次只能做一件事。随着电脑计算能力的增强,这一点带来很大的不便,无法充分发挥JavaScript的潜力。尤其考虑到,File API允许JavaScript读取本地文件,就更是如此了。
Web Worker的目的,就是为JavaScript创造多线程环境,允许主线程将一些任务分配给子线程。在主线程运行的同时,子线程在后台运行,两者互不干扰。等到子线程完成计算任务,再把结果返回给主线程。因此,每一个子线程就好像一个“工人”(worker),默默地完成自己的工作。
普通的Wek Worker,只能与创造它们的主进程通信。还有另一类Shared worker,能被所有同源的进程获取(比如来自不同的浏览器窗口、iframe窗口和其他Shared worker)。
Web Worker有以下几个特点:
检查支持情况
if (window.Worker) {
// 支持
} else {
// 不支持
}
使用:
// 主进程文件
var worker = new Worker('http://127.0.0.1:9292/work.js');
// 发送的数据可以是字符串或者对象
// worker.postMessage("Hello World");
worker.postMessage({method: 'echo', args: ['Work']});
worker.addEventListener('message', function(e) {
console.log(e.data);
}, false);
// work.js
self.addEventListener('message', function(e) {
console.log(e.data.method)
// 可以进行一些操作在对主进程进行发送信息
self.postMessage('You said: ' + e.data.method);
}, false);
面试环节:
面试准备:
一面二面
// 新建事件实例 如果需要传递数据则需要CustomEvent
var event = new Event('build');
// 添加监听函数
elem.addEventListener('build', function (e) { ... }, false);
// 触发事件
elem.dispatchEvent(event);
二面/三面
面试技巧:
重排Reflow
重绘
布局
三面四面
面试技巧:
考查能力:
最终面
面试技巧:
考察问题:
path.join()
连接路径,正确使用当前系统的路径分隔符path.join(myDir, 'test')
path.resolve()
将相对路径转为绝对路径,可以接受多个参数,依次表示所要进入的路径path.resolve([from ...], to)
readFileSync()
同步读取文件,返回一个字符串
var text = fs.readFileSync(fileName, "utf8");
// 将文件按行拆成数组
text.split(/\r?\n/).forEach(function (line) {
// ...
});
readFile()
异步读取文件
var fs = require('fs');
fs.readFile('example_log.txt', function (err, logData) {
if (err) throw err;
var text = logData.toString();
});
总结:React 非常先进和强大,但是学习和实现成本都不低
使用JSX语法,遇到{}就用JS语法解析,遇到<就用html语法解析,最外层只能有一个节点。
网上有很多组件库可以使用。
核心**:只要 State 发生变化,View 也要随之变化。
React 的本质是将图形界面(GUI)函数化。
React 本身只是一个 DOM 的抽象层,使用组件构建虚拟 DOM。
React 没有解决的问题:
React 只是视图层的解决方案,可以用于任何一种架构。
组件会发生三种通信
Flux 只是一个概念,有30多种实现。
移动端适配方案01:
(function (d, w) {
const doc = d.documentElement;
let tid;
function rem() {
const width = Math.min(doc.getBoundingClientRect().width, 768);
doc.style.fontSize = width / 7.5 + 'px';
}
rem();
w.addEventListener('resize', function () {
clearTimeout(tid)
tid = setTimeout(() => {
rem()
}, 300);
});
})(document, window);
2
npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --S
module.exports = { "plugins": { "postcss-import": {}, "postcss-url": {}, "postcss-aspect-ratio-mini": {}, "postcss-write-svg": { utf8: false }, "postcss-cssnext": {}, "postcss-px-to-viewport": { viewportWidth: 750, // (Number) The width of the viewport. viewportHeight: 1334, // (Number) The height of the viewport. unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to. viewportUnit: 'vw', // (String) Expected units. selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px. minPixelValue: 1, // (Number) Set the minimum pixel value to replace. mediaQuery: false // (Boolean) Allow px to be converted in media queries. }, "postcss-viewport-units":{}, "cssnano": { preset: "advanced", autoprefixer: false, "postcss-zindex": false } } }
网易云音乐banner U1K1 u1ku1ku.lofter.com
时光网banner 宽屏
广告狗:数英网 顶尖文案
剁手党:京东首页 天猫首页 任意一家旗舰店
建立文件夹:积累
搜图关键词:
大气:宇宙星空图 城市 山 大海
科技-VR-HTC vive Oculus Rift
利用不同领域的事物代替(蔬菜、水果代替罩杯?)。
不清楚时,关键词后加 壁纸、高清 HD
百度图片:图片尺寸过滤筛选(要特大尺寸)
比例、色彩等进行过滤筛选
免费图库:Pexels(先在这找,找不到去后面找) Pixabay(量太大,优势会搜出不想干的) Stocksnap(清新文艺)
Librestock(综合搜索)
一些屌的官网找图:Apple Nike
参考官网的排版设计
搜索的图,保存于电脑,设置为桌面壁纸轮播。
怎么找到匹配文本的图?
匹配文案中的关键词
匹配文案中的标点符号(从标点符号揣摩文本中体现的感情)
就是表情类图片啦(从标点符号中读出情绪)
三类图片非常抓眼球:
婴儿、野兽、美女、傻B(逗笑别人的图片)
逗比图库:gratisography.com
www.johnwilhelm.ch
500px.com/horazio
500px.com/adrian_sommeling
文字篇:
现代风:微软雅黑、方正兰亭黑、方正正黑、方正幼线体
**风:文悦青龙体、叶根友唐楷、苏新诗毛糙体
文艺风:方正小标宋、方正清刻本宋、方正粗黑宋、蒙纳秀明简
粗犷风:方正超粗黑、蒙纳简超刚黑、造字工房明黑、造字工房劲黑
柔情风:造字工房悦黑、汉仪意宋体、造字工房妙妙体、汉仪典雅体
可爱风:造字工房丁丁体、汉仪六字黑、汉仪黑荔枝体、字体管家方萌
扁平风:方正兰亭黑、微软雅黑、方正幼线体、造字工房悦黑
可免费上用字体:www.freechinesefont.com/tag/commercial-use-ok/
文字填充图
图标篇:
确保图标风格统一,同一图标在同一PPT中的唯一性。
instantlogosearch.com
pictogram2.com/?lang=en
视频库:
coverr
AmCharts
www.amcharts.com/svg-maps/
pixelmap.amcharts.com/
smartmockups.com
magicmockups.com
freedesignresources.net/4-business-card-mock-ups/
1.41176471 * 1.7
1.5 * 16
1.71428571 * 14
解决了创建多个相似对象的问题,没有解决对象识别的问题(怎样知道一个对象的类型)。
JS基础考题:
原型和原型链:
function fn () {}
console.log(fn.__proto__ === Function.prototype)
console.log(Function.prototype.__proto__ === Object.prototype)
console.log(Object.prototype.__proto__ === null)
instanceof:
原型链继承:
子类的原型对象实例化父类。
作用域和闭包:
执行上下文:
this:
当前作用域没有定义的变量称为自由变量。
闭包的使用场景:
异步和单线程
日期:
Math:
数组API:
对象API:
开发环境:加快开发效率
IDE:
后面三个编辑器,本身功能不多,需要依赖插件进行编码。
Git:
免费的git服务:coding.net github.com
一般公司都有自己的git服务器(搭建工作无需了解太多)
git基本命令和操作.....
模块化:
假如有三个JS文件,until.js a-until.js a.js,a.js依赖a-until.js中的函数,a-until.js依赖until.js里的函数
不使用模块化情况:
使用模块化情况:
AMD:require.js
CommonJs(服务器端,硬盘同步读取):
对比:
构建工具:
上线回滚:
基本流程:
上线
回滚
linux基本命令:
# login
ssh name@server # 回车会让你输入用户名、密码
# 创建目录
mkdir content
ls
ll
cd content
pwd
cd ..
rm -rf content
cp a.js a1.js
mv a1.js src/a1.js
rm a.js
# vi编辑器
vi a.js
i
esc
esc:w
esc:q
wsc:wq
# 查看文件内容
cat a.js
# 查看前一些
head a.js
head -n 1 a.js
# 查看后面一些
tail a.js
tail -n 2 a.js
# 搜索操作
grep '2' a.js
运行环境:(浏览器)
页面加载:
加载资源的形式、加载一个资源的过程、浏览器渲染页面的过程
加载资源的形式:
加载一个资源的过程:
浏览器渲染页面过程:
思考:
性能优化:
从这里入手:
加载资源优化:
渲染优化:
安全性:
大多是后端做的(数据库,服务器层面的)
XSS:
预防:
XSRF:
预防:
面试技巧:
简历:
过程:
我查了一下,更新node版本是:
先清除npm缓存:npm cache clean -f
然后安装n模块:npm install -g n
升级node.js到最新稳定版:n stable
n后面也可以跟随版本号比如:n v 3.7.3
;Notes: #==win !==Alt 2015-05-20 ^==Ctr +==shift
;==========================打开常用网址====================================
#m::Run www.amenzai.me
;==========================打开常用软件====================================
!n::run notepad
!l::run, C:\tools\Listary\Listary.exe
!y::run, C:\Users\amenz\AppData\Roaming\baidu\BaiduNetdisk\baidunetdisk.exe
!w::run, C:\mySoftware\Tencent\WeChat\WeChat.exe
!k::run, C:\mySoftware\YoukuClient\proxy\YoukuDesktop.exe
!q::run, C:\mySoftware\Tencent\TIM\Bin\TIM.exe
!v::run, C:\dev\VMware\VMware Workstation\vmware.exe
!x::run, C:\Program Files (x86)\NetSarang\Xshell 5\Xshell.exe
!g::run, C:\mySoftware\TGP\tgp_daemon.exe
!i::run, C:\Users\amenz\AppData\Local\Programs\iceworks-desktop\Iceworks.exe
!v::run, C:\mySoftware\Microsoft VS Code\Code.exe
!m::run, C:\mySoftware\CloudMusic\cloudmusic.exe
!d::run, C:\mySoftware\微信web开发者工具\微信web开发者工具.exe
;==========================================================================
;----------------------------------
::/mail::775166868@qq.com
::/pass::guojinchao.
::/me::http://amenzai.me/
::/cl::console.log();
::/js::javascript:;
::/j::javascript
::/h::html
;-------------------------------------------
;-----复制对应文件路径-----
^+c::
; null=
send ^c
sleep,200
clipboard=%clipboard% ;%null%
tooltip,%clipboard%
sleep,500
tooltip,
return
;------------------------------------------------
;replace CapsLock to LeftEnter; CapsLock = Alt CapsLock
;$CapsLock::Enter
;LAlt & Capslock::SetCapsLockState, % GetKeyState("CapsLock", "T") ? "Off" : "On"
;!u::Send ^c !{tab} ^v
;------------------------------
^#c::
MouseGetPos, mouseX, mouseY
; 获得鼠标所在坐标,把鼠标的 X 坐标赋值给变量 mouseX ,同理 mouseY
PixelGetColor, color, %mouseX%, %mouseY%, RGB
; 调用 PixelGetColor 函数,获得鼠标所在坐标的 RGB 值,并赋值给 color
StringRight color,color,6
; 截取 color(第二个 color)右边的6个字符,因为获得的值是这样的:#RRGGBB,一般我们只需要 RRGGBB 部分。把截取到的值再赋给 color(第一个 color)。
clipboard = %color%
; 把 color 的值发送到剪贴板
return
;-------------
Cookie 是服务器保存在浏览器的一小段文本信息,每个 Cookie 的大小一般不能超过4KB。浏览器每次向服务器发出请求,就会自动附上这段信息。
window.navigator.cookieEnabled属性返回一个布尔值,表示浏览器是否打开 Cookie 功能。
document.cookie一次只能写入一个 Cookie,而且写入并不是覆盖,而是添加。
document.cookie = 'test1=hello';
document.cookie = 'test2=world';
document.cookie
浏览器向服务器发送 Cookie 的时候,是使用一行将所有 Cookie 全部发送。
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: cookie_name1=cookie_value1; cookie_name2=cookie_value2
Accept: */*
服务器告诉浏览器需要储存 Cookie 的时候,则是分行指定。
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: cookie_name1=cookie_value1
Set-Cookie: cookie_name2=cookie_value2; expires=Sun, 16 Jul 3567 06:23:41 GMT
服务器向浏览器发送 Cookie 的时候,除了 Cookie 本身的内容,还有一些可选的属性也是可以写入的,它们都必须以分号开头。
Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
浏览器根据本地时间,决定 Cookie 是否过期,由于本地时间是不精确的,所以没有办法保证 Cookie 一定会在服务器指定的时间过期。
max-age属性用来指定Cookie有效期,比如60 * 60 * 24 * 365(即一年31536e3秒)。
HttpOnly属性用于设置该Cookie不能被JavaScript读取
Set-Cookie: key=value; HttpOnly
删除一个 Cookie 的唯一方法是设置其expires为一个过去的日期。
document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';
数量的限制:
Firefox 是每个域名最多设置50个 Cookie,而 Safari 和 Chrome 没有域名数量的限制。
所有 Cookie 的累加长度限制为4KB。超过这个长度的 Cookie,将被忽略,不会被设置。
同源政策:
浏览器的同源政策规定,两个网址只要域名相同和端口相同,就可以共享 Cookie。不要求协议相同
// 存入
sessionStorage.setItem("key","value");
localStorage.setItem("key","value");
// 读取
var valueSession = sessionStorage.getItem("key");
var valueLocal = localStorage.getItem("key");
// 清除
sessionStorage.removeItem('key');
localStorage.removeItem('key');
// 所有
sessionStorage.clear();
localStorage.clear();
// 遍历所有的键
for(var i = 0; i < localStorage.length; i++){
console.log(localStorage.key(i));
}
// 当储存的数据发生变化时,会触发storage事件。
window.addEventListener("storage",onStorageChange);
function onStorageChange(e) {
// 保存发生变化的键名
console.log(e.key);
// 其他属性
// oldValue:更新前的值。如果该键为新增加,则这个属性为null。
// newValue:更新后的值。如果该键被删除,则这个属性为null。
// url:原始触发storage事件的那个网页的网址。
}
值得特别注意的是,该事件不在导致数据变化的当前页面触发。如果浏览器同时打开一个域名下面的多个页面,当其中的一个页面改变sessionStorage或localStorage的数据时,其他所有页面的storage事件会被触发,而原始页面并不触发storage事件。可以通过这种机制,实现多个窗口之间的通信。所有浏览器之中,只有IE浏览器除外,它会在所有页面触发storage事件。
/**
* 计算两个大数的和
* @param {[Number]} a [数值A]
* @param {[Number]} b [数值B]
* @return {String]} [大数和]
*/
function sumBIgNum(a, b) {
var l1 = 0,
l2 = 0,
lt, // 参数小数点位数
result = '', // 保存最终结果字符串
carry = 0, // 保存进位
tmpArr = []; // 临时数组
// 获取小数位数开始
try {
l1 = a.toString().split('.')[1].length
}
catch(e) {}
try {
l2 = b.toString().split('.')[1].length
}
catch(e) {}
lt = Math.max(l1, l2);
// 获取小数位数结束
a = (a * Math.pow(10, lt)).toString().split('');
b = (b * Math.pow(10, lt)).toString().split('');
while (a.length || b.length || carry) {
// 对每一项相加
carry += ~~a.pop() + ~~b.pop(); // ~~'1'等 1 ~~undefined 等 0 ~~'2.33' 等 2
result = carry % 10 + result; // 每一项相加后的个位
carry = carry > 9 ? 1 : 0; // 每一项相加和大于10进1
}
result.replace(/^0+/, ''); // 去除最终结果前面的'0'
tmpArr = result.split('');
if (lt > 0) {
tmpArr.splice(-lt, 0, '.');
result = tmpArr.join('');
}
return result;
}
扩展
个人设置
// 将设置放入此文件中以覆盖默认设置
{
"window.zoomLevel": -1,
"editor.tabSize": 2,
"workbench.colorTheme": "One Dark Theme",
"editor.snippetSuggestions": "top",
"explorer.confirmDragAndDrop": false,
// "editor.formatOnSave": true,
// 控制字体系列。
"editor.fontFamily": "Consolas, 'Courier New', monospace, Dengxian",
"editor.multiCursorModifier": "ctrlCmd",
"files.associations": {
"*.inc": "html",
"*.ejs": "html",
"*.wxss": "css",
"*.wpy": "vue"
},
"explorer.confirmDelete": false,
"vsicons.dontShowNewVersionMessage": true,
"prettier.singleQuote": true,
"prettier.semi": false,
"vetur.format.defaultFormatter.html": "js-beautify-html",
"vetur.format.defaultFormatterOptions": {
"wrap_attributes": "force-aligned"
},
"emmet.syntaxProfiles": {
"vue-html": "html",
"vue": "html",
"wpy": "html"
},
"eslint.validate": [
"javascript",
"javascriptreact",
"html",
{
"language": "vue",
"autoFix": true
}
],
"eslint.autoFixOnSave": true,
"beautify.language": {
"js": {
"type": [
"javascript",
"json"
],
"filename": [
".jshintrc",
".jsbeautify"
]
},
"css": [
"css",
"less",
"scss"
],
"html": [
"htm",
"html"
]
},
"git.autofetch": true,
"git.enableSmartCommit": true,
"javascript.implicitProjectConfig.experimentalDecorators": true,
"emmet.includeLanguages": {
"wxml": "html"
},
"minapp-vscode.disableAutoConfig": true
}
和董事长谈了些技术方面的知识,发现有以下几点需要提高:
浙江大学软件学院(330)
专业课:>=120 C语言 数据结构
数学:>=110 高数、线代、数理统计
政治:>=60 找资料背诵
英语:>=60 单词 刷题
总>=350
需要学习哪些知识点?这些知识点在哪些书上?都要做哪些题,做几遍?背哪些东西?
总共的复习时间是几个月?给每一个任务分配多长时间?
最好是把耗神的任务和机械化的任务交错进行
复习前先设定理想分数,把需要掌握的知识点列出来,后面标明它们在过去被考的概率,然后像小坦克碾轧一样,一批一批地消灭掉
是个特殊的数组
var str = 'hello'
str[0] // h
想要使用数组方法需要借助call方法。
unicode编码
\n 反斜杠转义
base64编码:btoa()编码 atob()解码
中文在进行base编码时,先用encodeURIComponent()进行编码,解码一样
创建方法:
var o1 = {};
var o2 = new Object();
var o3 = Object.create(Object.prototype); //用于继承
其他,大括号问题
eval('{foo: 123}') // 123
eval('({foo: 123})') // {foo: 123}
检查变量是否声明:
if ('a' in window) {
// 变量 a 声明过
} else {
// 变量 a 未声明
}
查看对象属性:Object.keys(obj)
删除属性:delete //不能删除继承属性(不可枚举)
var o = Object.defineProperty({}, 'p', {
value: 123,
configurable: false
});
o.p // 123
delete o.p // false
in运算符检查对象是否包含对应属性
不能识别继承的,可以用hasOwnproperty()
var o = { p: 1 };
'p' in o // true
for in 循环遍历对象
它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性
它不仅遍历对象自身的属性,还遍历继承的属性(使用构造函数和原型创建的对象)。
with语句
它的作用是操作同一个对象的多个属性时,提供一些书写的方便。
// 例一
with (o) {
p1 = 1;
p2 = 2;
}
// 等同于
o.p1 = 1;
o.p2 = 2;
单纯从上面的代码块,根本无法判断x到底是全局变量,还是o对象的一个属性。
这非常不利于代码的除错和模块化,编译器也无法对这段代码进行优化,只能留到运行时判断,这就拖慢了运行速度。
因此,建议不要使用with语句,可以考虑用一个临时变量代替with。
with(o1.o2.o3) {
console.log(p1 + p2);
}
// 可以写成
var temp = o1.o2.o3;
console.log(temp.p1 + temp.p2);
数组是个特殊的对象
伪数组转为数组
var arr = Array.prototype.slice.call(arrayLike);
数组空位
var arr = [1,,2]
空位就是数组没有这个元素,所以不会被遍历到,而undefined则表示数组有这个元素,值是undefined,所以遍历不会跳过。
给函数参数设置默认值
function f(a){
a = a || 1;
return a;
}
f('') // 1
f(0) // 1
改进
function f(a) {
(a !== undefined && a !== null) ? a = a : a = 1;
return a;
}
f() // 1
f('') // ""
f(0) // 0
函数参数传递分为:传值传递、传址传递。
函数参数获取的是一个拷贝
// 用于apply方法
myfunction.apply(obj, arguments).
// 使用与另一个数组合并
Array.prototype.concat.apply([1,2,3], arguments)
变为真正的数组
var args = Array.prototype.slice.call(arguments);
// or
var args = [];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
请看下面的例子,闭包使得内部变量记住上一次调用时的运算结果。
function createIncrementor(start) {
return function () {
return start++;
};
}
var inc = createIncrementor(5);
inc() // 5
inc() // 6
inc() // 7
闭包的另一个用处,是封装对象的私有属性和私有方法。
function Person(name) {
var _age;
function setAge(n) {
_age = n;
}
function getAge() {
return _age;
}
return {
name: name,
getAge: getAge,
setAge: setAge
};
}
var p1 = Person('张三');
p1.setAge(25);
p1.getAge() // 25
注意,外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题。
var = function(){}();
(function(){})();
+function(){}();
将字符串当做语句执行
void(0)返回undefined
<a href="javascript:void window.open('http://example.com/')">
点击打开新窗口
</a>
<a href="javascript:void(0);"></a>
Number()
// 数值:转换后还是原来的值
Number(324) // 324
// 字符串:如果可以被解析为数值,则转换为相应的数值
Number('324') // 324
// 字符串:如果不可以被解析为数值,返回NaN
Number('324abc') // NaN
// 空字符串转为0
Number('') // 0
// 布尔值:true 转成1,false 转成0
Number(true) // 1
Number(false) // 0
// undefined:转成 NaN
Number(undefined) // NaN
// null:转成0
Number(null) // 0
Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN。
parseInt('42 cats') // 42
Number('42 cats') // NaN
String()
Boolean()
JavaScript解析或执行时,一旦发生错误,引擎就会抛出一个错误对象。JavaScript原生提供一个Error构造函数,所有抛出的错误都是这个构造函数的实例。
var err = new Error('出错了');
err.message // "出错了"
SyntaxError
语法错误
ReferenceError
ReferenceError是引用一个不存在的变量时发生的错误。
TypeError
TypeError是变量或参数不是预期类型时发生的错误
URIError
URIError是URI相关函数的参数不正确时抛出的错误
可以人为设置错误信息
new Error('出错了!');
new RangeError('出错了,变量超出有效范围!');
new TypeError('出错了,变量类型无效!');
实例的message属性获取
function UserError(message) {
this.message = message || "默认信息";
this.name = "UserError";
}
UserError.prototype = new Error();
UserError.prototype.constructor = UserError;
// 抛出一个字符串
throw "Error!";
// 抛出一个数值
throw 42;
// 抛出一个布尔值
throw true;
// 抛出一个对象
throw {toString: function() { return "Error!"; } };
JavaScript引擎一旦遇到throw语句,就会停止执行后面的语句,并将throw语句的参数值,返回给用户。
为了对错误进行处理,需要使用try...catch结构。
var n = 100;
try {
throw n;
} catch (e) {
if (e <= 50) {
// ...
} else {
throw e;
}
}
try...catch结构允许在最后添加一个finally代码块,表示不管是否出现错误,都必需在最后运行的语句。
openFile();
try {
writeFile(Data);
} catch(e) {
handleError(e);
} finally {
closeFile();
}
Object() // 返回一个空对象
Object() instanceof Object // true
Object(undefined) // 返回一个空对象
Object(undefined) instanceof Object // true
Object(null) // 返回一个空对象
Object(null) instanceof Object // true
Object(1) // 等同于 new Number(1)
Object(1) instanceof Object // true
Object(1) instanceof Number // true
Object('foo') // 等同于 new String('foo')
Object('foo') instanceof Object // true
Object('foo') instanceof String // true
Object(true) // 等同于 new Boolean(true)
Object(true) instanceof Object // true
Object(true) instanceof Boolean // true
如果Object方法的参数是一个对象,它总是返回原对象。
var arr = [];
Object(arr) // 返回原数组
Object(arr) === arr // true
var obj = {};
Object(obj) // 返回原对象
Object(obj) === obj // true
var fn = function () {};
Object(fn) // 返回原函数
Object(fn) === fn // true
Object 对象的静态方法
Object.keys():不包含不可枚举类型属性
Object.getOwnPropertyNames():包含
但两者都不包货继承属性
Object.prototype
valueOf():返回当前对象对应的值。
toString():返回当前对象对应的字符串形式。
toLocaleString():返回当前对象对应的本地字符串形式。
hasOwnProperty():判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性。
isPrototypeOf():判断当前对象是否为另一个对象的原型。
propertyIsEnumerable():判断某个属性是否可枚举。
Array.isArray()判断是否是数组
sort
[10111, 1101, 111].sort(function (a, b) {
return a - b;
})
// [111, 1101, 10111]
[
{ name: "张三", age: 30 },
{ name: "李四", age: 24 },
{ name: "王五", age: 28 }
].sort(function (o1, o2) {
return o1.age - o2.age;
})
// [
// { name: "李四", age: 24 },
// { name: "王五", age: 28 },
// { name: "张三", age: 30 }
// ]
some
some方法是只要有一个数组成员的返回值是true,则整个some方法的返回值就是true,否则false。
var arr = [1, 2, 3, 4, 5];
arr.some(function (elem, index, arr) {
return elem >= 3;
});
// true
every
every方法则是所有数组成员的返回值都是true,才返回true,否则false。
注意,对于空数组,some方法返回false,every方法返回true,回调函数都不会执行
属性:MAX_VALUE MIN_VALUE
方法:toFixed() toString() toExponential() // 科学计数表示 toPrecision() // 保留有效位数
自定义方法
Number.prototype.add = function (x) {
return this + x;
};
match()
match方法用于确定原字符串是否匹配某个子字符串,返回一个数组,成员为匹配的第一个字符串。如果没有找到匹配,则返回null。
'cat, bat, sat, fat'.match('at') // ["at"]
'cat, bat, sat, fat'.match('xt') // null
var matches = 'cat, bat, sat, fat'.match('at');
matches.index // 1
matches.input // "cat, bat, sat, fat"
match方法还可以使用正则表达式作为参数
search()
等同于match,但是返回值为匹配的第一个位置。如果没有找到匹配,则返回-1。
replace()
用于替换匹配的子字符串,一般情况下只替换第一个匹配(除非使用带有g修饰符的正则表达式)。
'aaa'.replace('a', 'b') // "baa"
test esec
Promise对象只有三种状态。
异步操作“未完成”(pending)
异步操作“已完成”(resolved,又称fulfilled)
异步操作“失败”(rejected)
var promise = new Promise(function(resolve, reject) {
// 异步操作的代码
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise应用-图片加载
var preloadImage = function (path) {
return new Promise(function (resolve, reject) {
var image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
};
Ajax
function search(term, onload, onerror) {
var xhr, results, url;
url = 'http://example.com/search?q=' + term;
xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
if (this.status === 200) {
results = JSON.parse(this.responseText);
onload(results);
}
};
xhr.onerror = function (e) {
onerror(e);
};
xhr.send();
}
search("Hello World", console.log, console.error);
or
function search(term) {
var url = 'http://example.com/search?q=' + term;
var xhr = new XMLHttpRequest();
var result;
var p = new Promise(function (resolve, reject) {
xhr.open('GET', url, true);
xhr.onload = function (e) {
if (this.status === 200) {
result = JSON.parse(this.responseText);
resolve(result);
}
};
xhr.onerror = function (e) {
reject(e);
};
xhr.send();
});
return p;
}
search("Hello World").then(console.log, console.error);
var xhr = new XMLHttpRequest();
// 指定通信过程中状态改变时的回调函数
xhr.onreadystatechange = function(){
// 通信成功时,状态值为4
if (xhr.readyState === 4){
if (xhr.status === 200){
console.log(xhr.responseText);
} else {
console.error(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
// open方式用于指定HTTP动词、请求的网址、是否异步
xhr.open('GET', '/endpoint', true);
// 发送HTTP请求
xhr.send(null);
CORS
Q
请求
GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
相应
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
localStorage
sessionStorage
方法:
getItem setItem removeItem clear()
遍历操作
for(var i = 0; i < localStorage.length; i++){
console.log(localStorage.key(i));
}
storage事件
window.addEventListener("storage",onStorageChange);
// 回调函数接受一个event对象作为参数。这个event对象的key属性,保存发生变化的键名。
function onStorageChange(e) {
console.log(e.key);
}
除了key属性,event对象的属性还有三个:
oldValue:更新前的值。如果该键为新增加,则这个属性为null。
newValue:更新后的值。如果该键被删除,则这个属性为null。
url:原始触发storage事件的那个网页的网址。
值得特别注意的是,该事件不在导致数据变化的当前页面触发。如果浏览器同时打开一个域名下面的多个页面,当其中的一个页面改变sessionStorage或localStorage的数据时,其他所有页面的storage事件会被触发,而原始页面并不触发storage事件。可以通过这种机制,实现多个窗口之间的通信。所有浏览器之中,只有IE浏览器除外,它会在所有页面触发storage事件。
现有的浏览器端数据储存方案,都不适合储存大量数据:Cookie 不超过4KB,且每次请求都会发送回服务器端;LocalStorage 在 2.5MB 到 10MB 之间(各家浏览器不同)。
所以,需要一种新的解决方案,这就是 IndexedDB 诞生的背景。
indexedDB.open()打开数据库
var openRequest = indexedDB.open("test",1);
上面代码表示,打开一个名为test、版本为1的数据库。如果该数据库不存在,则会新建该数据库。如果省略第二个参数,则会自动创建版本为1的该数据库。
打开数据库的结果是,有可能触发4种事件。
success:打开成功。
error:打开失败。
upgradeneeded:第一次打开该数据库,或者数据库版本发生变化。
blocked:上一次的数据库连接还未关闭。
var openRequest = indexedDB.open("test",1);
var db;
openRequest.onupgradeneeded = function(e) {
console.log("Upgrading...");
}
openRequest.onsuccess = function(e) {
console.log("Success!");
db = e.target.result;
}
openRequest.onerror = function(e) {
console.log("Error");
console.dir(e);
}
target.result属性就指向打开的IndexedDB数据库。
indexedDB实例对象的方法:
就是上面的DB
createObjectStore方法
用于创建存放数据的“对象仓库”(object store),类似于传统关系型数据库的表格。
db.createObjectStore("firstOS");
cookie localStorage indexedDB iframe DOM Ajax
document.getElementById("myIFrame").contentWindow.document // 父窗口获取子窗口 不同源把偶偶
window.parent.document.body // 同理
对于完全不同源的网站,目前有两种方法,可以解决跨域窗口的通信问题。
片段识别符(fragment identifier)
http://example.com/x.html#fragment的#fragment
// 父窗口可以把信息,写入子窗口的片段标识符。
var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;
// 子窗口通过监听hashchange事件得到通知。
window.onhashchange = checkMessage;
function checkMessage() {
var message = window.location.hash;
// ...
}
// 子对父
parent.location.href= target + “#” + hash;
跨文档通信API(Cross-document messaging) window.postMessage
// 父窗口aaa.com向子窗口bbb.com发消息
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');
window.opener.postMessage('Nice to see you', 'http://aaa.com');
// 父窗口和子窗口都可以通过message事件,监听对方的消息。
<!-- event.source:发送消息的窗口
event.origin: 消息发向的网址
event.data: 消息内容 -->
window.addEventListener('message', function(e) {
console.log(e.data);
},false);
ajax跨域:
JavaScript同时只能执行一个任务,其他任务都必须在后面排队等待。
挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。这种机制就是JavaScript内部采用的Event Loop机制。
运行线程只要发现消息队列不为空,就会取出排在第一位的那个消息,执行它对应的回调函数。等到执行完,再取出排在第二位的消息,不断循环,直到消息队列变空为止。
进入消息队列的消息,必须有对应的回调函数。
另一种情况是setTimeout会在指定时间向消息队列添加一条消息。如果消息队列之中,此时没有其他消息,这条消息会立即得到处理;否则,这条消息会不得不等到其他消息处理完,才会得到处理。因此,setTimeout指定的执行时间,只是一个最早可能发生的时间,并不能保证一定会在那个时间发生。
一旦当前执行栈空了,消息队列就会取出排在第一位的那条消息,传入程序。程序开始执行对应的回调函数,等到执行完,再处理下一条消息。
所谓Event Loop机制,指的是一种内部循环,用来一轮又一轮地处理消息队列之中的消息,即执行对应的回调函数。
下面是一些常见的JavaScript任务
同步任务指的是,在JavaScript执行进程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入JavaScript执行进程、而进入“任务队列”(task queue)的任务,只有“任务队列”通知主进程,某个异步任务可以执行了,该任务(采用回调函数的形式)才会进入JavaScript进程
所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。
运行以后的程序叫做“进程”(process)
待办事项
英语第二章过一遍,复习第一章(早上)
张宇视频第二节,对应书籍章节过一遍
英语背诵情况不太好,估计一开始背的太多,难以消化,明天可以用正确的记忆方法,设置好可以接受的量(每天50个),早上背完,晚上复习,以及新的50个,第二天早上复习昨晚的,加新的50个,如此循环一周,周末对每周背诵的进行全面复习。
数学,以后每晚看章视频和书,题目统一周末做。
技术
生活
学习还是很容易分心,静不下来,正在慢慢从浮躁中过渡。
估计是想的太多,外界因素干扰,明晚要把心沉下来,专注于高数的学习
Less / Sass / Stylus
等CSS预处理语言RequireJS
,能运用模块化、面向对象的方式编程AngularJS
,熟悉Vue、React
gulp、webpack
等构件工具Node
配合MongoDB
编写接口杭州志卓科技股份有限公司( 2017年7月 ~ 2018年4月 )
主要负责云客网、优化师后台的前端开发工作
vue、vueRouter、vuex、axios
)进行开发ElementUI
组件库,自主编写项目需要的组件负责云客网、云搜宝网站的活动页面开发,及前端维护
HTML5 + CSS3
编写页面jquery
编写页面交互效果鼎捷软件股份有限公司( 2017年4月 ~ 2017年7月 )
参与厂内智能物流APP的开发与维护工作
requireJS
进行模块管理,运用angularJS
编写业务逻辑,使用Ionic
开发混合APP,打包及真机测试。镇江巨和网络科技( 2015年3月 ~ 2016年12月 )
负责公司前端开发业务,实现客户需求
html、css、Javascript、Jquery、Ajax
等技术对网站进行布局以及交互效果的编写Git
进行代码版本的管理,使用gulp
自动化构建工具,加快前端开发的速度互联网招聘APP
react
编写虚拟DOM,react-redux
应用数据管理、react-router
路由控制Ant Design Mobile
开发express
框架编写接口MongoDB
数据库储存数据微型植物工厂智能监控系统
webpack
构建CORS
以及nginx
代理解决接口跨域问题响应式web图书馆
html5阅读器
Zepto
基本使用Base64
格式的图片LocalStorange
本地存储Ajax
异步请求、Touch
事件感谢您花时间阅读我的简历,期待能有机会和您共事。
阅读的四个问题?
快速阅读
只读自己喜欢、想读的
一周一本书的训练方法
明确目的、设定时间、检视阅读
主题阅读
例如:
精读一本书:
看、思考、保存、行动
4个人步骤读懂一本书
制定阅读计划(下一周看完xxx书)
实施(从头到尾阅读一本苏,将其中比较重要的点摘取出来,继承笔记)
回顾和整理(把提前放到印象笔记里的进行整理,比如分组和赋予标签或者画出一张思维导图,将书中的要点以一个整体形式再现出来)
带着问题去读书
学会给自己出题然后考核自己
能力
影响力
人脉
如何盈利
营销
个人品牌
成果型:从工作、生活中得到了什么?
制造信息不对称,比别人先懂,先实践,先分享
研究型:钻研某个问题,成为某个领域的专家
模范型:榜样
打造个人能力四个步骤:
天赋、能力、时间
找到HOLD住的方向:
输入(阅读)-整理(思考、实践)-输出(写作)-输入
深度模仿(模仿一群):
找出最厉害的那几个人,模仿他们
学会对每一个技能进行知识管理
获取-整理-分享-利用-创新-提问
刻意练习:
快速迭代,最小可行的产品
建立自己的影响力:
打造自己的爆款产品
多平台占位
系列化输出(输出系统化)
人脉=等价交换
付费、扎堆
简书-打赏
今日头条-广告
微课
职业规划、选定专业领域、个人品牌价值定位
程序员-项目管理-产品
1 为什么要写作
自我?工作?组织
工作之外,做自己喜欢的事,才能找到自我。
工作有考核,自我学习就是用写作检验
写书评40周,锻炼阅读和书写能力
怎么写文章?多读 多写就可以了
2 怎么靠写作赚钱
一日一更,找机会爆款
多平台卡位,不给钱也上场
3 写作的2类型
成果型,研究型
试错:
哪个主题?
文案:
标题勾引、结论硬朗、内容清晰
故事:
让别人讲道理、让我们讲故事
雾满拦江、阿诚
营销:
李叫兽、叶茂中、Frank
服务:
发布只是第一步,需要持续服务来实现用户粘度
模仿大神
忘掉做王红、做产品经理才有星辰大海
获取
整理
分享
利用
创新
提问
知识管理:
生理需求(温饱)、安全需求(保护、隐私、秩序)、社会需求(爱情、友谊)、尊重需求(受尊重和肯定)、自我实现的需求(发挥潜能、实现理想)
知识分层:
通用的知识-专业基础-专业知识
知识的分类:
会?不会 是否知道
通用技能:沟通能力、时间管理、阅读能力
专业基础:写作能力,知识管理、团队管理
产品管理、项目管理
去哪获取我想要的知识?
阅读、微博、微信、搜搜、晕课堂、社群
阅读的分类:
主食:生存需求-美食:**需求-蔬果:工具需求-甜点:休闲需求
随时随地收集信息:剪藏等(使用印象笔记来做知识收集)
花瓣收集图片信息
使用Calibre管理电子书
扫描纸上的有用信息,实现共享
Pocket 印象笔记 有大运笔记 为知笔记
收藏完以后:
分门别类,命好名(定义好命名规则)
文件夹目录+GIT管理自己的文件
收集和整理 分享和利用
例如时间管理的知识管理:A-时间管理 A1-时间管理-收集 整理 分享(添加个分享的名字) 利用
快速在自己的知识库搜索信息
学了为什么老是记不住?
主动学习VS被动学习
主动:训练他人、实际演练、做的过程中学、小组讨论
被动:示范演示、声音图片、阅读、听讲
上述都依次递减的
知识的分享:
行动 转化
知识的创新
演化:基于现有知识的突破
跨界: 跨知识领域进行创新
从自己的专业领域出发
每一个技能都可以用知识管理的6个步骤进行管理
视觉呈现、PPT、思维导图、知识管理、高效阅读、时间管理、行动学习、写作
// 一些属性方法
this.$wxapp
this.$pages
this.$invoke('./ComB', 'func1', 'p1', 'p2');
this.$broadcast('broadcast-event', 'p1', 'p2');
this.$emit('emit-event', 'p1', 'p2');
this.$apply();
this.$nextTick().then(function() {
console.log('UI updated');
});
// 路由
this.$redirect('./page2', {
a: 1,
b: 2
});
this.$redirect({
url: './pages?a=1&b=2'
});
this.$navigate(url: String | Object, [params: Object])
this.$switch(url: String | Object)
wepy.navigateBack({
delta: 2 // 返回的页面数,如果 delta 大于现有页面数,则返回到首页。
})
wepy.reLaunch({ // 关闭所有页面,打开到应用内的某个页面。
url: 'test?id=1'
})
// 登录
wx.login().then(res => {
console.log(res)
if (res.code) {
wepy.getUserInfo().then(res => {
console.log(res)
wepy.request('').then(res => {
console.log(res)
})
})
} else {
console.log('登录失败!' + res.errMsg)
}
})
// 授权
wepy.authorize({
scope: 'scope.record'
}).then(res => {
console.log(res)
})
// 转发
wepy.showShareMenu({
withShareTicket: true
})
wepy.hideShareMenu()
onShareAppMessage(res) {
if (res.from === 'button') {
// 来自页面内转发按钮
console.log(res.target)
}
return {
title: 'eeeeee',
// imageUrl: ''
path: '/pages/draw/draw',
success(res) {
console.log(res)
}
}
}
// 请求
const requestTask = wepy.request({
url: 'test.php', //仅为示例,并非真实的接口地址
method: 'GET',
data: {
x: '',
y: ''
},
header: {
'content-type': 'application/json'
}
}).then(res => {
console.log(res.data)
})
requestTask.abort() // 取消请求任务
// 本地存储
wx.setStorage({
key: "key",
data: "value"
})
wx.setStorageSync('key', 'value')
wx.getStorage({
key: 'key',
success: function(res) {
console.log(res.data)
}
})
wx.getStorageInfo({
success: function(res) {
console.log(res.keys)
console.log(res.currentSize)
console.log(res.limitSize)
}
})
wx.removeStorage({
key: 'key',
success: function(res) {
console.log(res.data)
}
})
try {
wx.removeStorageSync('key')
} catch (e) {
// Do something when catch error
}
wx.clearStorage()
// 界面交互 弹窗等
wx.showToast({
title: '成功',
icon: 'success', // loading none
image: '',
mask: false, // 默认为false
duration: 2000
})
wx.hideToast()
wx.showLoading({
title: '加载中',
mask: false
})
wx.hideLoading()
wx.showModal({
title: '提示',
content: '这是一个模态弹窗',
showCancel: true, // 是否显示取消按钮
cancelText: '取消',
cancelColor: '#444',
confirmText: '确认',
confirmColor: '#3CC51F',
success: function(res) {
if (res.confirm) {
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
wx.showActionSheet({
itemList: ['A', 'B', 'C'], // 按钮的文字数组
itemColor: '#444', // 按钮的文字颜色
success: function(res) {
console.log(res.tapIndex) // 用户点击的按钮,从上到下的顺序,从0开始
},
fail: function(res) {
console.log(res.errMsg)
}
})
// 在当前页面显示导航条加载动画。
wx.showNavigationBarLoading()
// 隐藏
wx.hideNavigationBarLoading()
wepy.setTabBarBadge({
index: 0, // tabBar的哪一项,从左边算起
text: '1' // 显示的文本,超过 3 个字符则显示成“…”
})
wx.removeTabBarBadge({
index: 0 // tabBar的哪一项,从左边算起
})
wx.showTabBarRedDot({
index: 0
})
wx.hideTabBarRedDot({
index: 0
})
// 点击 tab 时触发
onTabItemTap(item) {
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
}
// 动画使用方法
// <view animation="{{animationData}}" style="background:red;height:100rpx;width:100rpx"></view>
{
data: {
animationData: {}
},
onShow: function() {
var animation = wx.createAnimation({ // 创建动画
duration: 1000,
timingFunction: 'ease',
// delay: '' 动画延迟时间
})
this.animation = animation
animation.scale(2, 2).rotate(45).step()
this.setData({
animationData: animation.export()
})
setTimeout(function() {
animation.translate(30).step()
this.setData({
animationData: animation.export()
})
}.bind(this), 1000)
},
rotateAndScale: function() {
// 旋转同时放大
this.animation.rotate(45).scale(2, 2).step()
this.setData({
animationData: this.animation.export()
})
},
rotateThenScale: function() {
// 先旋转后放大
this.animation.rotate(45).step()
this.animation.scale(2, 2).step()
this.setData({
animationData: this.animation.export()
})
},
rotateAndScaleThenTranslate: function() {
// 先旋转同时放大,然后平移
this.animation.rotate(45).scale(2, 2).step()
this.animation.translate(100, 100).step({ duration: 1000 })
this.setData({
animationData: this.animation.export()
})
}
}
// 回到顶部
wepy.pageScrollTo({
scrollTop: 0,
duration: 300
})
// 自动下拉刷新
wepy.startPullDownRefresh()
// 停止
wepy.stopPullDownRefresh()
// 页面相关事件方法
onPullDownRefresh: function() {
// Do something when pull down.
}
onReachBottom: function() {
// Do something when page reach bottom.
}
onShareAppMessage: function() {
// return custom share data when user share.
}
onPageScroll: function() {
// Do something when page scroll
}
// 登陆
wepy.login().then(res => {
console.log('loginInfo', res)
if (res.code) {
wx.request({
url: 'https://test.com/onLogin',
data: {
code: res.code
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
})
// 获取用户信息
wepy.getUserInfo().then(res => {
console.log('userInfo', res)
this.globalData.userInfo = res.userInfo
})
// 微信支付
wepy.requestPayment({
'timeStamp': '',
'nonceStr': '', // 随机字符串,长度为32个字符以下。
'package': '', // 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
'signType': 'MD5',
'paySign': '', // 签名
'success':function(res){
},
'fail':function(res){
}
})
# 安装工具
npm install wepy-cli -g
# 查看项目模板
wepy list
# 初始化项目
wepy init standard myproject
cd myproject
npm install
# 实时监控修改并编译
wepy build --watch
app.wpy
<style lang='less'>
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
}
</style>
<script>
import wepy from 'wepy'
import 'wepy-async-function'
export default class extends wepy.app {
config = {
// 配置需要展示的页面路径
pages: [
'pages/index'
],
window: {
// backgroundColor: '#fff', 窗口背景色
// enablePullDownRefresh 是否开启下拉刷新
// onReachBottomDistance 页面上拉触底事件触发时距页面底部距离,单位为px
backgroundTextStyle: 'light', // 下拉 loading 的样式,仅支持 dark/light
navigationBarBackgroundColor: '#fff', // 导航栏背景色
navigationBarTitleText: 'WeChat', // 文字内容
navigationBarTextStyle: 'black' // 导航栏标题色
},
tabBar: {
color: '#888', // 文字
selectedColor: '#89bdf7', // 选中文字
backgroundColor: '#fff',
borderStyle: 'white', // 上边框颜色 white black
position: 'bottom', // 'top', default: 'bottom'
list: [{
pagePath: 'pages/index/index', // 点击跳转的页面路径
text: '首页',
iconPath: 'images/home.png',
selectedIconPath: 'images/home_active.png'
}]
},
debug: true,
networkTimeout: {
// 相关请求超时时间
request: 10000,
connectSocket: 10000,
uploadFile: 10000,
downloadFile: 10000
}
}
globalData = {
userInfo: null
}
constructor () {
super()
this.use('promisify') // 开启promise
this.use('requestfix')
this.intercept('request', {
// 发出请求时的回调函数
config (p) {
// 对所有request请求中的OBJECT参数对象统一附加时间戳属性
p.timestamp = +new Date();
console.log('config request: ', p);
// 必须返回OBJECT参数对象,否则无法发送请求到服务端
return p;
},
// 请求成功后的回调函数
success (p) {
// 可以在这里对收到的响应数据对象进行加工处理
console.log('request success: ', p);
// 必须返回响应数据对象,否则后续无法对响应数据进行处理
return p;
},
// 请求失败后的回调函数
fail (p) {
console.log('request fail: ', p);
// 必须返回响应数据对象,否则后续无法对响应数据进行处理
return p;
},
// 请求完成时的回调函数(请求成功或失败都会被执行)
complete (p) {
console.log('request complete: ', p);
}
})
}
onLaunch() {
this.testAsync()
}
sleep (s) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise resolved')
}, s * 1000)
})
}
async testAsync () {
const data = await this.sleep(3)
console.log(data)
}
getUserInfo(cb) {
const that = this
if (this.globalData.userInfo) {
return this.globalData.userInfo
}
wepy.getUserInfo({
success (res) {
that.globalData.userInfo = res.userInfo
cb && cb(res.userInfo)
}
})
}
}
</script>
index.wpy
<!-- 存在src属性且有效时,会忽略内联代码。 -->
<style lang="less">
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.userinfo-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #aaa;
}
</style>
<template>
<!-- 循环渲染用 repeat标签 -->
<!-- <repeat for="{{list}}" key="index" index="index" item="item">
<child :item="item">这个是引入的组件 传递了item数据</child>
</repeat> -->
<!-- <view @tap="tapName({{index}}, 'wepy', 'otherparams')"> Click me! </view> -->
<view class="container">
<view class="userinfo" @tap="handleViewTap">
<image class="userinfo-avatar" src="{{ userInfo.avatarUrl }}" background-size="cover"/>
<view class="userinfo-nickname">{{ userInfo.nickName }}</view>
</view>
<panel>
<view class="title" slot="title">测试数据绑定</view>
<text class="info">{{normalTitle}}</text>
<text class="info">{{setTimeoutTitle}}</text>
<text class="info">{{mixin}}</text>
<text class="info">{{mynum}}</text>
<text class="info">{{now}}</text>
<button @tap="plus('a')" size="mini"> + </button>
</panel>
<panel>
<view class="title" slot="title">其它测试</view>
<button @tap="toast" size="mini">第三方组件</button>
<button @tap="communicate" size="mini">组件通信</button>
<button @tap="tap" size="mini">混合TAP事件</button>
</panel>
<panel>
<view class="title" slot="title">测试并发网络请求</view>
<view>返回结果: <text>{{netrst}}</text></view>
<button @tap="request" size="mini"> 点我发起10个请求 </button>
</panel>
<panel>
<view class="title" slot="title">测试组件</view>
<text class="testcounter">计数组件1: </text>
<view class="counterview">
<counter1 @index-emit.user="counterEmit" />
</view>
<text class="testcounter">计数组件2: </text>
<view class="counterview">
<counter2 :num.sync="mynum"></counter2>
</view>
</panel>
<panel>
<view class="title" slot="title">测试组件Repeat</view>
<repeat for="" index="index" item="item" key="key">
<group :grouplist="item" :indexa="index"></group>
</repeat>
</panel>
<panel>
<view class="title" slot="title">测试列表</view>
<list></list>
</panel>
<toast />
</view>
</template>
<script>
// 异步函数中更新数据的时,必须手动调用$apply方法,才会触发脏数据检查流程的运行
// wepy.request('xxxx').then((d) => console.log(d));
// this.$parent 获取APP实例中的方法 数据
import wepy from 'wepy'
import Panel from '@/components/panel' // alias example
import Counter from 'counter' // alias example
import List from '../components/list' // aliasFields example
import moduleA from 'module-a' // aliasFields ignore module example
import Group from '../components/group'
import Toast from 'wepy-com-toast'
import testMixin from '../mixins/test'
console.log('moduleA ignored: ', moduleA) // => moduleA ignored: {}
export default class Index extends wepy.page {
// 页面配置
config = {
navigationBarTitleText: 'test'
}
// 组件调用
// 组件传值: 静态传值、动态传值
// 静态(只能传递String字符串类型): <child title="mytitle"></child> props = {title: String };
// 动态:<child :title="parentTitle" :syncTitle.sync="parentTitle" :twoWayTitle="parentTitle"></child>
// child.wpy
// props = {
// // 静态传值
// title: String,
// // 父向子单向动态传值
// syncTitle: {
// type: String,
// default: 'null'
// },
// twoWayTitle: {
// type: Number,
// default: 'nothing',
// twoWay: true
// }
// };
// this.$parent.parentTitle = 'p-title-changed'; 拿到父组件数据,进行更改
// this.$parent.$apply(); 同步
components = {
panel: Panel,
counter1: Counter, // 为两个相同组件的不同实例分配不同的组件ID,从而避免数据同步变化的问题
counter2: Counter,
list: List,
group: Group,
toast: Toast
}
// 公用属性、方法、事件对象
// methods响应事件 先响应组件本身响应事件,然后再响应混合对象中响应事件
mixins = [testMixin]
// 内部数据
data = {
mynum: 20,
userInfo: {
nickName: '加载中...'
},
normalTitle: '原始标题',
setTimeoutTitle: '标题三秒后会被修改',
count: 0,
netrst: '',
groupList: [
{
id: 1,
name: '点击改变',
list: [
{
childid: '1.1',
childname: '子项,点我改变'
}, {
childid: '1.2',
childname: '子项,点我改变'
}, {
childid: '1.3',
childname: '子项,点我改变'
}
]
},
{
id: 2,
name: '点击改变',
list: [
{
childid: '2.1',
childname: '子项,点我改变'
}, {
childid: '2.2',
childname: '子项,点我改变'
}, {
childid: '2.3',
childname: '子项,点我改变'
}
]
},
{
id: 3,
name: '点击改变',
list: [
{
childid: '3.1',
childname: '子项,点我改变'
}
]
}
]
}
// 计算属性 和vue一样
computed = {
now () {
return +new Date()
}
}
watch = {
// num (newValue, oldValue) {
// console.log(`num value: ${oldValue} -> ${newValue}`)
// }
}
// 页面绑定事件对应的处理函数
methods = {
plus () {
this.mynum++
},
toast () {
let promise = this.$invoke('toast', 'show', {
title: '自定义标题',
img: 'https://raw.githubusercontent.com/kiinlam/wetoast/master/images/star.png'
})
promise.then((d) => {
console.log('toast done')
})
},
tap () {
console.log('do noting from ' + this.$name)
},
communicate () {
console.log(this.$name + ' tap')
this.$invoke('counter2', 'minus', 45, 6)
this.$invoke('counter1', 'plus', 45, 6)
this.$broadcast('index-broadcast', 1, 3, 4)
},
request () {
let self = this
let i = 10
let map = ['MA==', 'MQo=', 'Mg==', 'Mw==', 'NA==', 'NQ==', 'Ng==', 'Nw==', 'OA==', 'OQ==']
while (i--) {
wepy.request({
url: 'https://www.madcoder.cn/tests/sleep.php?time=1&t=css&c=' + map[i] + '&i=' + i,
success: function (d) {
self.netrst += d.data + '.'
self.$apply()
}
})
}
},
counterEmit (...args) {
let $event = args[args.length - 1]
console.log(`${this.$name} receive ${$event.name} from ${$event.source.$name}`)
}
}
// WePY组件事件处理函数对象,存放响应组件之间通过$broadcast、$emit、$invoke所传递的事件的函数
// this.$broadcast('some-event', arg) 父亲向所有孩子
// this.$emit('some-event', arg) 孩子向所有父亲
// this.$invoke('Acomponent path', 'someMethod' ,arg) A组件调用B组件
events = {
'index-emit': (...args) => {
let $event = args[args.length - 1]
console.log(`${this.$name} receive ${$event.name} from ${$event.source.$name}`)
}
}
// 生命周期函数
onLoad() {
let self = this
this.$parent.getUserInfo(function (userInfo) {
if (userInfo) {
self.userInfo = userInfo
}
self.normalTitle = '标题已被修改'
self.setTimeoutTitle = '标题三秒后会被修改'
setTimeout(() => {
self.setTimeoutTitle = '到三秒了'
self.$apply()
}, 3000)
self.$apply()
})
}
}
</script>
App({
onLaunch: function(options) {
// 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
},
onShow: function(options) {
// 当小程序启动,或从后台进入前台显示,会触发 onShow
},
onHide: function() {
// 当小程序从前台进入后台,会触发 onHide
},
onError: function(msg) {
// 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
console.log(msg)
},
globalData: 'I am global data' // 可以添加任意的函数或数据到 Object 参数中,用 this 可以访问
})
getApp()
// other.js
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data
//index.js
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// 监听页面加载
},
onReady: function() {
// 监听页面初次渲染完成
},
onShow: function() {
// 监听页面显示
},
onHide: function() {
// 监听页面隐藏
// 当navigateTo或底部tab切换时调用。
},
onUnload: function() {
// 监听页面卸载
// 当redirectTo或navigateBack的时候调用。
},
onPullDownRefresh: function() {
// 监听用户下拉动作
},
onReachBottom: function() {
// 页面上拉触底事件的处理函数
},
onShareAppMessage: function () {
// 用户点击右上角转发
return {
title: '自定义转发标题',
path: '/page/user?id=123'
}
},
onPageScroll: function() {
// 页面滚动触发事件的处理函数
},
onTabItemTap(item) {
// 当前是 tab 页时,点击 tab 时触发
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// Event handler.
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
}, function() {
// this is setData callback
})
},
customData: { // 可以添加任意的函数或数据到 object 参数中,在页面的函数中用 this 可以访问
hi: 'MINA'
}
})
// common.js
function sayHello(name) {
console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
console.log(`Goodbye ${name} !`)
}
module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye
---
var common = require('common.js')
Page({
helloMINA: function() {
common.sayHello('MINA')
},
goodbyeMINA: function() {
common.sayGoodbye('MINA')
}
})
不支持直接引入 node_modules,需要使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中。
<!--wxml-->
// 列表循环
<view wx:for="{{array}}"> {{item}} </view>
// 条件渲染
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
// 事件绑定
<view bindtap="add"> {{count}} </view>
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5],
view: 'MINA',
count: 1
},
add: function(e) {
this.setData({
count: this.data.count + 1
})
}
})
elementUI
// 全部引入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 按需引入
import { Button, Select } from 'element-ui';
// 插件配置示例
Vue.use(Button);
Vue.use(Loading.directive);
Vue.prototype.$loading = Loading.service;
Vue.prototype.$msgbox = MessageBox;
Vue.prototype.$alert = MessageBox.alert;
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
Vue.prototype.$notify = Notification;
Vue.prototype.$message = Message;
按需引入:
npm install babel-plugin-component -D
// .babelrc
{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
vux
// 使用插件
import AlertPlugin from 'vux/src/plugins/Alert'
import ToastPlugin from 'vux/src/plugins/Alert'
or
import { AlertPlugin, ToastPlugin } from 'vux'
// 使用组件
import { Group, Cell } from 'vux'
vant
// 全部引入
import Vant from 'vant';
import 'vant/lib/vant-css/index.css';
// 按需引入
import Button from 'vant/lib/button';
import 'vant/lib/vant-css/base.css';
import 'vant/lib/vant-css/button.css';
or
import { Button } from 'vant';
1、img-2
一个 WebComponent 组件,使用 取代 ,可以只显示第一屏的图片,其他图片通过 Web Worker 预下载,一旦该图片进入可视区域后再加载显示。
2、ReLaXed
一个将 HTML 文件转为 PDF 文件的命令行工具。
3、IPBlade
有的网络服务限制 IP 地址,比如只有**的 IP 地址才能使用。这个 Chrome 插件点击一下就可以改变浏览器的 IP 地址,从而绕过这些限制。免费版只能改成美国的 IP 地址。
.gitignore 文件设置了哪些文件可以不用进入 Git 版本管理。这个命令行工具可以根据项目类型,自动生成 .gitignore 文件。
5、tlsh-js
一个生成字符串哈希的 JavaScript 库。它的特点是,字符串越相似,或者重复同样的模式,生成的哈希也越相似,可以用来计算两个字符串的相似程度。
一个有手绘效果的网页组件库。但是,真正特别之处在于它的底层是 Web components,让我们看到了除了React/Vue之外,还有其他的路。
7、sucrase
一个新的 JavaScript 转码器,号称比 Babel 快20倍。
React router 的两位创始人闹翻了,其中一位另起门户,写了一个功能相同的 Reach router
待办事项
英语LIST2(早上)
张宇视频第三讲,对应书籍章节过一遍(晚上)
英语LIST2未复习完一遍,明早继续
数学视频过完,书籍未完成,明晚补加第四讲
技术
Element.getBoundingClientRect()
方法返回元素的大小及其相对于视口的位置。生活
最近想的太多,要慢慢沉下心了。
大脑每天不要输入太多无关东西,毕竟人脑每天记忆量有限。
一些分辨率术语的含义 :
向服务端传递的数据格式:
ArrayBufferView, Blob, DOMString, 或者 FormData 类型的数据。
Navigator.sendBeacon()
待办事项
英语LIST3(早上)
张宇视频第四讲,对应书籍章节过一遍(晚上)
技术
生活
大学生毕业人数多,企业裁员,薪资预期不要太高,行业需求看招聘岗位要求。
关注行业讯息,同行动态,多看好的APP,了解可用性和用户体验。知道该怎么设计,这都是在看APP多的话就会在脑袋里留下印象。
产品经济时代:以产品为中心的设计,直接看到实物,用户围观。
体验经济时代:只有元素,以用户为中心的设计,用户参与,产品的手段。买的不是产品,是体验。
是卖产品还是卖用户直接的体验。用户直接参与进来,例如那些我们可以自己写内容的产品(微博,博客,社交等)
流程职位。
经验,动力
UI设计8件事
怎么火的
百度指数:去找关键词搜索量可以看出他的流行度。
工资为啥高
互联网创业高潮让UI设计师变得炙手可热。
非科班的UI设计师都是来自哪里
源自工业设计,下一个时代是移动互联网,好多人开始转行,平面-网页-UI,培训班出来。
传统设计师一定能做好UI吗
传统设计师是为了推广和宣传,UI为了服务。
平面都是个性 创意,有个人特点。 UI都是形式服务于内容,团队协同设计。
你真的了解UI设计的工作吗
boss-pm-ue-ui-RD-QA-OP
老板有钱、点子、资源;产品需求文档,时间排期;低保真原型,交互说明;视觉设计稿,视觉规范,切图标注适配;代码实现;QA测试,找BUG,可用性测试;产品运营,用户反馈。
UI设计还能火多久
硬件发展的话,就需要UI,只要有操作面板,可视化界面。智能家居、可穿戴设备、VR/AR。传统公司转型。
用户体验设计师,产品思维是未来所有行业的思维方式。
代码实现类设计师
全栈设计师
3D表现类设计师
运用手绘类UI:情感类插图
动效表现设计师,直观表现交互思维
野路子怎么学UI
英语:Medium Dribbble
找参考,找资料,英文非常重要。
看书:用户体验的书籍,交互设计精髓,用户体验设计,用户体验要素,别让我思考,设计师要懂心理学。
手机不去自动更新,每次更新记得截取前一版本的界面设计。
定个小目标,每天督促自己做个小案例。
关于UI市场上的两种声音
产品思维,做产品,别重视软件视觉操作。
圈子学习,社交圈子。
插件学习,快速学习能力,发现问题,解决问题。别再去系统学习完然后在解决问题。
学完以后,出教程。
什么是UI设计
UI设计的日常工作
设计出用户内心期望的产品。
风格定位、产品迭代、BANNER、专题活动
做好风格定位的两个关键点:
流程:
产品迭代:
诞生-成长-成熟-结束
UI设计的发展路径
PS-临摹-理论-沉淀自己的作品
UI设计师的必备习惯
储备素材-平常整理素材库-创作时的参考
分出它对应的学习点(分类):
交互、文案、摄影、字体设计、活动、配色、BANNER、印刷品、web产品、欢迎页、主界面、ICON、动效
设计思考
培养自己设计的敏感度,感受生活中的美和丑,什么东西让我们产生这种感受,多思考其中原因。
了解行业
通过哪些网站和APP关注相应信息。
面试那些事
准备面试材料
5大系统
修炼设计技法
目前,W3C 正在设计一个基于密钥的网站注册流程。以后,注册用户时不需要密码,也不用担心破解。
简单说,就是注册的时候,浏览器自动生成公钥和私钥,然后把公钥发给服务器,私钥保留在本地。以后登录的时候,用户只需要输入用户名,浏览器用私钥加密后发给服务器,如果能被公钥解开,就证明了用户的身份。
2、AI 的发展速度
有研究称,2012年开始, AI 的运算速度每过3.5个月翻一倍,至今已经增加了30多万倍。相比之下,摩尔定律(每18个月翻一倍)简直慢得不值一提。要是按照摩尔定律,AI 的运算速度只会增长12倍。
总之,AI 的进化速度远远快于人类的想象,在你不知不觉之间,机器的聪明已经超乎想象。
3、打印的卵巢
美国科学家使用3D打印机做出来的明胶卵巢,替换掉小白鼠的天然卵巢,结果居然有效。7只实验老鼠有3只产下了健康的后代。
《未来简史》描述的场景正在变成现实:未来的人们不再是纯自然的产物,而是半自然、半人工的一种新人类。
4、Firefox 浏览器支持 Web Components
Firefox 浏览器最新的 Nightly测试版本 已经支持 Web Components。这是 Chrome 浏览器5年前开始推广的一种新技术,现在除了 Edge 浏览器,其他主要浏览器都已经支持了。
Web Components 是浏览器原生的组件解决方案。如果你愿意对新技术下赌注,可以考虑它。
5、JavaScript 的新数据类型:大整数 BigInt
经过很长一段时间的测试以后,V8 引擎正式宣布支持 JS 的第8种数据类型:大整数 BigInt。从此,JS 可以精确表示任意位数的整数,再也不受64位双精度浮点数格式的限制了。
谷歌宣布了人工智能客服系统 Google Duplex。以后,你打电话订餐、投诉、咨询,跟你交谈的都不是真人,而是一个软件。客服这个行业从此要被消灭了。
另一方面,如果你意识不到对方是软件,就意味着它通过了图灵测试。这是不是意味着,以后软件冒充人已经没问题了?
索尼公司推出了新一代机器宠物狗 aibo(爱宝),根据产品主页的介绍,它跟人的互动达到了前所未有的程度,已经很接近真实的狗。
人跟机器人做伴侣的时代真的不远了。
8、技术发展例子
举例来说,我看到一个消息,麻省理工学院发明了一种远程充电技术,可以隔空用无线电波给微型电子设备充电。他们做了一个实验,把传感器埋入一头猪的体内,大约皮下10公分的地方,然后相隔一米发送无线电波,居然就把传感器驱动起来了!
这意味着微型电子设备从此不需要电池了,可以做得很小(比米粒还小),从而能够植入人体,使用的时候,发送电波就行了。以前做不到,是因为无线电波携带的能量非常微弱,又不知道设备的具体位置,没法用来充电。新技术克服了这些难点。
一旦人体可以植入电子设备,不再有充电的难题,那会带来怎样的变革?我的想象力都不够了……以后可能不再需要身份证了,每个人的体内植入私钥,检查身份的时候,一发信号,返回一个私钥签名的证书,只要跟公钥匹配,立刻就验明正身。
1、人必有痴,而后有成。(林语堂)
2、创业公司成功的原因,这是最难的问题。大多数人只是指出非常明显的事情:”创始人很勤奋,企业文化也非常优秀。“问题在于,其他5000家创业公司也是如此,但都失败了。
3、如果你在很年轻的时候,就遭受到了失败,一定要把它当作老天送你的礼物。如果等到四十岁再失败,你会经受不起的。为什么年纪越大,走路越小心,因为越来越经不起跌倒了。
4、人生就像玻璃窗上的苍蝇,前途一片光明,却找不到出路。
5、十八年前刚刚接触网络,常常有世界触手可及的奇妙感觉。如今技术越来越先进,那种感觉却越来越少。
6、现在的开发者需要具备的,不仅仅是技能树,而是技能森林。
7、现实中的用户处于痛苦和失望的状态,你需要为他们设置一个放松和缓冲的区域,与外部世界隔离,让他们以一种兴奋的状态,进入你的产品。
8、千万别上瘾只想去解决那些困难的问题。如果那些问题本身就是错的,你会浪费时间;如果你解决不了,也会浪费时间。
9、没用分布式架构之前,你只有一个问题:并发性能不足。用了分布式架构,多出了一堆问题: 数据如何同步、主键如何产生、如何熔断、分布式事务如何处理……
10、读再多的书都不如内生动力给人带来的变化大。
找到你早起的真正动力,那应该跟你最渴望实现的梦想有关,然后,明明白白地写在墙上。
找出问题的原因然后解决它。(解决晚睡的问题)
有时候我们很努力,是因为没有能力。没有能力把自己的时间安排好,没有能力控制自己的行为,所以才把自己推到了废寝忘食的境地。
长期坚持就会形成一种固定的思维习惯:“我的一天会在十一点结束,所以一定要珍惜白天的时间,更要珍惜晚上的时间,不要把晚上当作无休止的放纵时间,更不要把晚上当作主要的工作时间。
给自己一个起床时间,找人一起打卡,或者找另外的什么非起不可的理由,逼自己早点睡觉。
每日复盘,制定明日计划。
早上的时间,简直是造物主的恩赐,这是一段跟现实无关的时间,在他人沉睡时静悄悄地起床,这一段时间,最适合去为自己的珍贵梦想做努力,在每一个早晨,都离它更近一点。
要达到目标,只需要做五件事。
1.选择一个清晰的目标。
2.找到那些阻碍目标实现的问题。
3.精确地诊断问题。
4.设计计划并列出任务清单。
5.坚决执行并完成计划里的任务清单。
自己到底需要做什么,还没做什么,先做什么,后做什么,困难是什么,方法是什么。
大部分学生都没有管理自己和规划人生的能力,你被拖着、拽着、鞭策着、鼓励着,也挨着、麻木着,像一台机器一样毫无目的地转动着。
如何规划自己的人生,怎么才能找一个有意义的目标,怎么做才能实现这个目标,如何克服懒惰、对付拖延、安排时间。
设定目标、制定计划、时间管理
让自己变得有趣:
1.积累素材,学习套路。
2.反复试验,分析反馈。
3.形成风格,养成习惯。
为人处世有分寸感,心地善良不讨人厌,看什么都高兴,做什么都好玩,并且能够感染到周围的人,这就是有趣了。
学习前准备:
我为什么要学这些东西?
我今天要解决什么问题?
我预估多久可以学完这些东西?
怎么样学习才能达到目标,这个问题包括三个要素:
A.要达到什么样的目标。考什么学校?这个学校要多少分数?单科目标分数是多少?
B.要做什么事情。都需要学习哪些知识点?这些知识点在哪些书上?都要做哪些题,做几遍?背哪些东西?
C.这些事情要做多久。总共的复习时间是几个月?给每一个任务分配多长时间?
带着明确的目的去做,与模模糊糊,只是知道应该这么做,专注度也会有差别。
脑中一定要有这样的概念:学习时间绝对不可以中断,绝对不可以中断,绝对不中断,就算是无法集中注意力,也不要放弃为集中注意力而努力。
学习过程的干扰因素:杂念(先记下来,统一处理)、烦恼(记下解决方案或忽视)、手机(远离)、暗恋。
我挚爱的记忆方式,就是“说出来”,让自己特别郑重地站在一个地方,然后对着空气说,对着马路说。
我克服拖延和提高效率的办法就是把deadline交到别人的手上。
梦想这个词太概括了,要把它具体化、画面化,去想象做到之后的场景,我会变成什么样子,我会得到什么,父母会很高兴吧,越细越好。
最好是把耗神的任务和机械化的任务交错进行。、
最好把休息的时间固定下来,每天的晚上几点,每周的哪一天。
有进益,有阻碍,开始时没想太多,完成后才惊觉自己神功大成,反而有点落寞。
成功最重要的就是“延迟享受”的能力。也就是自律。
克服拖延:
第一,一定要找到实现目标的明确途径,清楚每一个行动的作用和效果,这样才会愿意行动起来。
准备研究生考试时,我就曾试图把达成目标的任务都明确下来。在复习前先设定理想分数,把需要掌握的知识点列出来,后面标明它们在过去被考的概率,然后像小坦克碾轧一样,一批一批地消灭掉,这过程居然还有点爽呢。
找出这个人,然后看一下成为他、取代他需要做哪几件事,包括需要学习哪些东西,需要掌握什么资源,需要升几级,怎么做会更快,把过程清晰地写出来。
第二,从想做的事情开始做。
每次要开始做一件我非常不想做的事情时,就从一件比较想做的事情开始,或者从那件事情中比较简单的一部分开始。
第三,如果能及时看到行动的反馈,坚持起来就会更容易。
好胜心会让你在听到差评的时候更努力,成就感会让你在听到好评的时候去继续努力。
第四,周期性坚持。
为了避免周一进入学习状态时不适应或者太痛苦,周日晚上就坐在桌子前去熟悉一下周一的事情,稍微做一点简单的任务或者做一个规划。
第五,别去做任何一个你根本做不到的计划。
一定要结合自己现在的水平和实际情况去做一个“一定可以完成”的计划,在时间上留一点余地。
第六,找到那些做出错误决定的瞬间。
记录自己失控的那些瞬间,找到自己失控的原因。
定目标,悄悄干。
当别人还在沉睡的时候,你就出发吧;当别人还在挣扎的时候,你就到达吧。
我算不上优秀,只是足够主动
下次v型才是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的
电风扇的
是电风扇的
requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘。
requestAnimationFrame的优势,在于充分利用显示器的刷新机制,比较节省系统资源。
html:
<div id="anim">Click here to start animation</div>
css:
#anim {
position:absolute;
left:0px;
width:150px;
height:150px;
background: blue;
font-size: larger;
color: white;
border-radius: 10px;
padding: 1em;
}
js:
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
var elem = document.getElementById("anim");
var startTime = undefined;
function render(time) {
if (time === undefined)
time = Date.now();
if (startTime === undefined)
startTime = time;
elem.style.left = ((time - startTime)/10 % 500) + "px";
}
elem.onclick = function() {
(function animloop(){
render();
requestAnimFrame(animloop, elem);
})();
};
chrome://version/
,找到个人资料路径,输入到资源管理器,进入Extensions
文件夹chrome://extensions/
这里面找到,记得勾选上面的开发者模式)C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Extensions\dogkpdfcklifaemcdfbildhcofnopogp\0.6.3_0
chrome://extensions/
,点击页面上部的打包扩展程序
,填入扩展程序目录,然后打包crx
文件的路径待办事项
英语LIST1-2(早上)
张宇视频第四讲,对应书籍章节过一遍(晚上)
英语第一单元完毕。
数学由于其他原因,未完成,移至明天完成。
技术
公司开始了Vue的移动端项目,使用了有赞的组件库链接
生活
财政告急,这个月要吃土了-。-
受同源限制有如下几点:
两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享 Cookie。
// A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html
document.domain = 'example.com';
// 现在,A 网页通过脚本设置一个 Cookie。
document.cookie = "test1=hello";
// B 网页就可以读到这个 Cookie。
var allCookie = document.cookie;
服务器也可以在设置 Cookie 的时候,指定 Cookie 的所属域名为一级域名,比如.example.com。
Set-Cookie: key=value; domain=.example.com; path=/
这样的话,二级域名和三级域名不用做任何设置,都可以读取这个Cookie。
iframe窗口之中的脚本,可以获得父窗口和子窗口。但是,只有在同源的情况下,父窗口和子窗口才能通信;如果跨域,就无法拿到对方的DOM。
// 父窗口运行下面的命令,如果iframe窗口不是同源,就会报错。
document.getElementById("myIFrame").contentWindow.document
// Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.
// 窗口获取主窗口的DOM也会报错。
window.parent.document.body
// 报错
这种情况还适用于window.open方法打开的窗口,只要跨域,父窗口与子窗口之间就无法通信。
如果两个窗口一级域名相同,只是二级域名不同,那么设置上一节介绍的document.domain属性,就可以规避同源政策,拿到DOM。
对于完全不同源的网站,目前有两种方法,可以解决跨域窗口的通信问题。
URL的#号后面的部分。如果只是改变片段标识符,页面不会重新刷新。
// 父窗口可以把信息,写入子窗口的片段标识符。
var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;
// 子窗口通过监听hashchange事件得到通知。
window.onhashchange = checkMessage;
function checkMessage() {
var message = window.location.hash;
// ...
}
// 同样的,子窗口也可以改变父窗口的片段标识符。
parent.location.href= target + '#' + hash;
postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即“协议 + 域名 + 端口”。也可以设为*,表示不限制域名,向所有窗口发送。
// 父窗口aaa.com向子窗口bbb.com发消息
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');
// 子窗口向父窗口发送消息的写法类似。
window.opener.postMessage('Nice to see you', 'http://aaa.com');
// 父窗口和子窗口都可以通过message事件,监听对方的消息。
window.addEventListener('message', function(e) {
console.log(e.data);
},false);
event对象的几个属性:
window.postMessage,也可以读写其他窗口的 LocalStorage
// 主窗口写入iframe子窗口的localStorage
window.onmessage = function(e) {
if (e.origin !== 'http://bbb.com') {
return;
}
var payload = JSON.parse(e.data);
localStorage.setItem(payload.key, JSON.stringify(payload.data));
};
// 父窗口发送消息的代码如下。
var win = document.getElementsByTagName('iframe')[0].contentWindow;
var obj = { name: 'Jack' };
win.postMessage(JSON.stringify({key: 'storage', data: obj}), 'http://bbb.com');
跨域解决:
它的基本**是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。
foo({
"ip": "8.8.8.8"
});
该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
浏览器发出的WebSocket请求的头信息
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
服务器可以根据Origin这个字段,判断是否许可本次通信。如果该域名在白名单内,服务器就会做出如下回应。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
相比JSONP只能发GET请求,CORS允许任何类型的请求。
只要服务器实现了CORS接口,就可以跨源通信。
// 简单请求
// request
GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
// response
Access-Control-Allow-Origin: http://api.bob.com
// 默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
想要在CORS请求中发送cookie,则需要:
服务器:Access-Control-Allow-Credentials: true
浏览器xhr:var xhr = new XMLHttpRequest(); xhr.withCredentials = true;
需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。
代码示例
html
<form id="file-form" action="handler.php" method="POST">
<input type="file" id="file-select" name="photos[]" multiple onchange="handleChanage()"/>
<button type="submit" id="upload-button">上传</button>
</form>
js
var fileSelect = document.getElementById('file-select')
function handleChanage(e) {
var files = fileSelect.files
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
var file = files[i];
// if (!file.type.match('image')) {
// continue;
// }
formData.append('photos[]', file, file.name);
}
console.log(formData)
}
var formData = new FormData();
formData.append('name','tom');
formData.append('age','12');
SSE,就是浏览器向服务器发送一个HTTP请求,然后服务器不断单向地向浏览器推送“信息”(message)。这种信息在格式上很简单,就是“信息”加上前缀“data: ”,然后以“\n\n”结尾。
$ curl http://example.com/dates
data: 1394572346452
data: 1394572347457
data: 1394572348463
^C
使用:
// 检查浏览器是否支持
if (!!window.EventSource) {
// ...
}
// 向服务器发起连接 参数url就是服务器网址,必须与当前网页的网址在同一个网域(domain),而且协议和端口都必须相同。
var source = new EventSource('/dates');
source.onmessage = function(e){
console.log(e.data);
};
source.addEventListener("open", function(event) {
// handle open event
}, false);
// event有以下属性
// data:服务器端传回的数据(文本格式)。
// origin: 服务器端URL的域名部分,即协议、域名和端口。
// lastEventId:数据的编号,由服务器端发送。如果没有编号,这个属性为空。
source.addEventListener("message", function(event) {
var data = event.data;
var origin = event.origin;
var lastEventId = event.lastEventId;
// handle message
}, false);
source.addEventListener("error", function(event) {
// handle error event
}, false);
技术
语言只是负责描述一个程序,而程序运行速度,其实很大程度不取决于语言,而主要取决于算法和编译器的质量。
技术选型,先选框架再选语言。
判断node项目环境变量:process.env.NODE_ENV === 'production';
包为cross-env
命令举例:"build": "cross-env NODE_ENV=production wepy build --no-cache",
//加法函数
function accAdd(arg1, arg2) {
var r1, r2, m;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
return (arg1 * m + arg2 * m) / m;
}
//给Number类型增加一个add方法,,使用时直接用 .add 即可完成计算。
Number.prototype.add = function (arg) {
return accAdd(arg, this);
};
//减法函数
function Subtr(arg1, arg2) {
var r1, r2, m, n;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
//last modify by deeka
//动态控制精度长度
n = (r1 >= r2) ? r1 : r2;
return ((arg1 * m - arg2 * m) / m).toFixed(n);
}
//给Number类型增加一个sub方法,,使用时直接用 .sub 即可完成计算。
Number.prototype.sub = function (arg) {
return Subtr(this, arg);
};
//乘法函数
function accMul(arg1, arg2) {
var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
try {
m += s1.split(".")[1].length;
}
catch (e) {
}
try {
m += s2.split(".")[1].length;
}
catch (e) {
}
return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}
//给Number类型增加一个mul方法,使用时直接用 .mul 即可完成计算。
Number.prototype.mul = function (arg) {
return accMul(arg, this);
};
//除法函数
function accDiv(arg1, arg2) {
var t1 = 0, t2 = 0, r1, r2;
try {
t1 = arg1.toString().split(".")[1].length;
}
catch (e) {
}
try {
t2 = arg2.toString().split(".")[1].length;
}
catch (e) {
}
with (Math) {
r1 = Number(arg1.toString().replace(".", ""));
r2 = Number(arg2.toString().replace(".", ""));
return (r1 / r2) * pow(10, t2 - t1);
}
}
//给Number类型增加一个div方法,,使用时直接用 .div 即可完成计算。
Number.prototype.div = function (arg) {
return accDiv(this, arg);
};
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.