1.函數(shù)柯里化
http://www.reibang.com/p/2975c25e4d71
函數(shù)柯里化是一種閉包。
最后的面試題例子 ,如果打印的話就是執(zhí)行隱式轉(zhuǎn)換的toSTring console.log應(yīng)該也算是一種賦值操作吧
vue源碼的patch也用了函數(shù)柯里化谅年,就是為了把執(zhí)行在多個(gè)平臺(tái)的patch函數(shù)分開(kāi)摊溶,而不是在函數(shù)里面進(jìn)行判斷飒货。
2感凤、typeof在判斷array類型的時(shí)候也會(huì)返回‘object’丸相,只能用來(lái)檢測(cè)5種基礎(chǔ)類型俯在。(我這個(gè)笨蛋竟秫,在看vue源碼的時(shí)候忘記了這個(gè) 一直思考 為啥數(shù)組不給響應(yīng)式。跷乐。)
3、那些UI框架中的折疊面板什么的為什么 不是在data中聲明的數(shù)據(jù)就不能折疊和打開(kāi)了呢?
因?yàn)榻Y(jié)合vue的ui框架中都是用vue寫(xiě)的举娩。而這個(gè)數(shù)據(jù)如果不是在data或者其他中聲明 就是一個(gè)普通的對(duì)象(沒(méi)有戈getter和setter函數(shù))這樣僅僅是一個(gè)對(duì)象 不依靠vue的setter和getter去更新dom 這樣dom怎么會(huì)更新呢华匾?這些框架內(nèi)部想要更新dom肯定都是通過(guò)vue的虛擬dom這些一步一步去更新的。腦子短路了 想好久浅侨。纽谒。。如输。
4鼓黔、發(fā)布/訂閱模式和觀察者模式的區(qū)別
觀察者模式只有2個(gè)角色 發(fā)布者和訂閱者, 他們是直接聯(lián)系不见,通過(guò)notify去循環(huán)調(diào)用update澳化。 vue雙向綁定就是觀察者模式(下文例子中的這個(gè)有個(gè)觀察者列表,vue源碼中把這個(gè)省略掉了 直接在dep中定義了個(gè)數(shù)組來(lái)代替觀察者list,更簡(jiǎn)便)
發(fā)布訂閱者模式 多了一個(gè)調(diào)度中心 由調(diào)度中心去操控
http://www.reibang.com/p/9f2c8ae57cac
5脖祈、Vue 能做哪些性能優(yōu)化肆捕?
①、路由懶加載
②盖高、組件按需加載
③慎陵、keep-alive
④、preload/prefetch
⑤喻奥、key
⑥席纽、減少不必要的響應(yīng)式依賴
⑦、預(yù)加載和懶加載
⑧撞蚕、v-if / v-show润梯,computed / watch
⑨、事件銷毀
⑩、按需 Polyfill纺铭、模板預(yù)編譯
...
5寇钉、axios能取消請(qǐng)求嗎?
可以 提供有這個(gè)函數(shù)舶赔。
比如在重復(fù)點(diǎn)擊的時(shí)候會(huì)重復(fù)的去請(qǐng)求服務(wù)端的接口扫倡,這時(shí)候可以在請(qǐng)求前去清除上一次沒(méi)有響應(yīng)的相關(guān)的請(qǐng)求。
http://www.reibang.com/p/22b49e6ad819
6竟纳、簡(jiǎn)單理解websoket協(xié)議撵溃?
websoket不同于http協(xié)議,http協(xié)議是單向的 只能客戶端向服務(wù)端發(fā)送消息锥累,而websoket是雙向的 可以互發(fā)消息
需要依靠http建立連接缘挑。
簡(jiǎn)單來(lái)說(shuō),WebSocket是一種協(xié)議桶略,與HTTP協(xié)議一樣位于應(yīng)用層语淘,都是TCP/IP協(xié)議的子集。HTTP協(xié)議是單向通信協(xié)議删性,只有客戶端發(fā)起HTTP請(qǐng)求亏娜,服務(wù)端才會(huì)返回?cái)?shù)據(jù)。而WebSocket協(xié)議是雙向通信協(xié)議蹬挺,在建立連接之后维贺,客戶端和服務(wù)器都可以主動(dòng)向?qū)Ψ桨l(fā)送或接受數(shù)據(jù)。WebSocket協(xié)議建立的前提需要借助HTTP協(xié)議巴帮,建立連接之后溯泣,持久連接的雙向通信就與HTTP協(xié)議無(wú)關(guān)了。
使用:
// 打開(kāi)WebSocket, 傳遞的參數(shù)url沒(méi)有同源策略的限制榕茧。
let websocket = new WebSocket(url)
// 監(jiān)聽(tīng)open事件垃沦,在成功建立websocket時(shí)向url發(fā)送純文本字符串?dāng)?shù)據(jù)(如果是對(duì)象則必須序列化處理)。
websocket.onopen = () => {
if (websocket.readyState === WebSocket.OPEN) {
websocket.send('hello world')
}
}
// 監(jiān)聽(tīng)message事件用押,在服務(wù)器響應(yīng)時(shí)接受數(shù)據(jù)肢簿。返回的數(shù)據(jù)存儲(chǔ)在事件對(duì)象中。
websocket.onmessage = e => {
let data = e.data
console.log(data)
}
// 監(jiān)聽(tīng)error事件蜻拨,在發(fā)生錯(cuò)誤時(shí)觸發(fā)池充,連接不能持續(xù)。
websocket.onerror = () => {
console.log('websocket connecting error!!')
}
// 監(jiān)聽(tīng)close事件缎讼,在連接關(guān)閉時(shí)觸發(fā)收夸。只有close事件的事件對(duì)象擁有額外的信息⊙福可以通過(guò)這些信息來(lái)查看關(guān)閉狀態(tài)
websocket.onclose = e => {
let clean = e.wasClean // 是否已經(jīng)關(guān)閉
let code = e.code // 服務(wù)器返回的數(shù)值狀態(tài)碼卧惜。
let reason = e.reason //服務(wù)器返回的消息厘灼。
參考連接:
https://www.cnblogs.com/unclekeith/p/8087182.html
7、node的超級(jí)簡(jiǎn)單入門學(xué)習(xí)
node有三大模塊:
全局模塊:何時(shí)何地都能直接訪問(wèn)咽瓷,不需要引用
process.env 則是訪問(wèn)自己電腦下的環(huán)境變量
process.argv 則node *** a b c則是把a(bǔ) b c添加到一個(gè)有數(shù)據(jù)的一個(gè)數(shù)組里面设凹,使用的時(shí)候可以做一些操作
系統(tǒng)模塊:需要用require去引入,但是不需要下載
如:path 路徑茅姜,最常見(jiàn)的則是path.resolve(__dirname,index.js) //則是返回index.js文件的絕對(duì)路徑
fs 文件讀寫(xiě)操作围来, ,fs.whriteFile()匈睁,fs.readFile()等
還有http模塊 一會(huì)再說(shuō)
自定義模塊 就是我們平常自己寫(xiě)的一些代碼 比如JS文件下的代碼 函數(shù) 或者變量等等
exports->單個(gè)導(dǎo)出
module.exports={}->合并導(dǎo)出
require->在路徑中去引入,如果沒(méi)有路徑 直接是一個(gè)字符串 則取node_module中去查找
http模塊可以幫我們創(chuàng)建服務(wù)器桶错。
是服務(wù)器 可以在瀏覽器上輸入地址去訪問(wèn)
app.js
let http = require('http');
let url = require('url');
let fs = require("fs");
http.createServer((req,res)=>{
let {pathname, query} = url.parse(req.url, true);
console.log(pathname)
fs.readFile(`./${pathname}`, (err, data)=>{
if(err){
res.writeHead(404);
res.end('404');
}else{
res.end(data);
}
})
}).listen(8888)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="http://localhost:8888" method="GET">
用戶名:<input type="text" name="username"><br/>
密碼:<input type="password" name="password"><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
上面則是在瀏覽器下輸入http://localhost:8888就訪問(wèn)了我們定義的服務(wù)器航唆,然后獲得地址/去訪問(wèn)這個(gè)文件 ,發(fā)現(xiàn)沒(méi)有的話 則會(huì)返回404
如果訪問(wèn)http://localhost:8888/index.html則會(huì)拿到index.html然后去返回給瀏覽器 這樣我們?yōu)g覽器就可以顯示這個(gè)表單了院刁。
這樣就算是交互成功了
接下來(lái)做一個(gè)簡(jiǎn)單的登錄注冊(cè)
設(shè)計(jì)api
首先明白get和post傳輸糯钙。login使用get傳輸, reg注冊(cè)使用post傳輸
get因?yàn)閿?shù)據(jù)在鏈接少 所以比較少 <=32k post數(shù)據(jù)在身體上 所以傳輸?shù)臄?shù)據(jù)上限比較大 <=2G
而且post的數(shù)據(jù)由于比較多退腥,所以可以分段傳輸
加下來(lái)做個(gè)例子任岸,簡(jiǎn)單的登錄注冊(cè),有登錄成功 密碼錯(cuò)誤和用戶不存在 注冊(cè)有用戶已經(jīng)存在和注冊(cè)成功
html代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
用戶名:<input type="text" name="username" id="username">
密碼:<input type="password" name="password" id="password">
<button id="login">登錄</button>
<button id="reg">注冊(cè)</button>
<script src="./jquery.min.js"></script>
<script>
$('#login').click(function(){
$.ajax({
url:"/login",
data:{
username:$('#username').val(),
password:$('#password').val()
},
success(res){
res = JSON.parse(res)
alert(res.msg)
}
})
})
$('#reg').click(function(){
$.ajax({
url:"/reg",
method: "post",
dataType:'json',
data:{
username:$('#username').val(),
password:$('#password').val()
},
success(res){
alert(res.msg)
}
})
})
</script>
</body>
</html>
服務(wù)端代碼:
let http = require("http");
let url = require("url");
let fs = require("fs");
let querystring = require("querystring");
let user = {
admin: 12345
}
http.createServer((req, res)=>{
let path, get, post;
if(req.method == 'GET'){
let {pathname, query} = url.parse(req.url, true);
path = pathname;
get = query;
complete();
}else if(req.method == 'POST'){
path = req.url;
let arr = [];
req.on('data', buffer=>{
arr.push(buffer);
})
req.on('end', ()=>{
post = querystring.parse(Buffer.concat(arr).toString());
complete();
})
}
function complete(){
if(path == '/login'){
res.writeHead(200,{
'content-Type': "text/plain;charset=utf-8"
})
let {username, password} = get;
if(!user[username]){
res.end(JSON.stringify({
err: 1,
msg:'用戶名不存在'
}))
}else if(user[username] !=password){
res.end(JSON.stringify({
err: 1,
msg:'密碼錯(cuò)誤'
}))
}else{
res.end(JSON.stringify({
err: 0,
msg:'登錄成功'
}))
}
}else if(path == '/reg'){
res.writeHead(200,{
'content-Type': "text/plain;charset=utf-8"
})
let {username, password} = post;
if(user[username]){
res.end(JSON.stringify({
err: 1,
msg:'用戶存在'
}))
}else{
user[username] = password;
res.end(JSON.stringify({
err: 0,
msg:'注冊(cè)成功'
}))
}
}else{
let path1 = './' + path;
fs.readFile(path1, (err,data)=>{
if(err){
res.end('404');
}else{
res.end(data);
}
})
}
}
}).listen(8080)
這樣既可實(shí)現(xiàn)狡刘。
但是有個(gè)問(wèn)題 我不知道為啥登錄的時(shí)候傳回來(lái)的數(shù)據(jù)是Json格式享潜,但是注冊(cè)的時(shí)候返回的卻是對(duì)象格式,明明在傳輸之前轉(zhuǎn)換成了json格式的 嗅蔬。剑按。。 百思不得其解
8澜术、手寫(xiě)簡(jiǎn)單async/await
async/await單看是generator的語(yǔ)法糖艺蝴。
generator簡(jiǎn)單說(shuō)就是函數(shù)聲明之后 執(zhí)行就會(huì)返回一個(gè)遍歷器 然后執(zhí)行一席next()從開(kāi)頭或者yieldield執(zhí)行到下一個(gè)yield(感覺(jué)像是打了斷點(diǎn))
具體看廖雪峰的generator
async/await語(yǔ)法糖就是使用Generator函數(shù)+自動(dòng)執(zhí)行器來(lái)運(yùn)作的。 我們可以參考以下例子
// 定義了一個(gè)promise鸟废,用來(lái)模擬異步請(qǐng)求猜敢,作用是傳入?yún)?shù)++
function getNum(num){
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num+1)
}, 1000)
})
}
//自動(dòng)執(zhí)行器,如果一個(gè)Generator函數(shù)沒(méi)有執(zhí)行完盒延,則遞歸調(diào)用
function asyncFun(func){
var gen = func();
function next(data){
var result = gen.next(data);
if (result.done) return result.value;
result.value.then(function(data){
next(data);
});
}
next();
}
// 所需要執(zhí)行的Generator函數(shù)缩擂,內(nèi)部的數(shù)據(jù)在執(zhí)行完成一步的promise之后,再調(diào)用下一步
var func = function* (){
var f1 = yield getNum(1);
var f2 = yield getNum(f1);
console.log(f2) ;
};
asyncFun(func);
在執(zhí)行的過(guò)程中兰英,判斷一個(gè)函數(shù)的promise是否完成撇叁,如果已經(jīng)完成,將結(jié)果傳入下一個(gè)函數(shù)畦贸,繼續(xù)重復(fù)此步驟陨闹。
參考自:https://segmentfault.com/a/1190000020785563?utm_source=tag-newest#item-2-3
9楞捂、JavaScript的惰性函數(shù)
有這個(gè)需求就是返回第一次執(zhí)行這個(gè)函數(shù)的時(shí)間。
普通的做法則是聲明一個(gè)變量 賦值為第一次的時(shí)間趋厉,每次進(jìn)來(lái)判斷這個(gè)變量是否存在 存在即不是第一次 寨闹,不獲取時(shí)間 ,直接返回君账。
這樣的缺點(diǎn)就是每次進(jìn)函數(shù)都要判斷
var t;
function foo() {
if (t) return t;
t = new Date()
return t;
}
所以這個(gè)時(shí)候?yàn)榱私鉀Q這個(gè)問(wèn)題繁堡,就有了惰性函數(shù),簡(jiǎn)單的說(shuō)就是滿足條件之后 就把函數(shù)的索引指向一個(gè)新的函數(shù)乡数。這樣就不用每次都判斷了: 即重寫(xiě)函數(shù)
var foo = function() {
var t = new Date();
foo = function() {
return t;
};
return foo();
};
10椭蹄、JavaScript的組合函數(shù)
一個(gè)函數(shù)傳入的參數(shù)即為另一個(gè)函數(shù)返回的值 這樣多老幾層, 則看起來(lái)不友好 不優(yōu)雅
我們需要寫(xiě)一個(gè)函數(shù)净赴,輸入 'kevin'绳矩,返回 'HELLO, KEVIN'。
var toUpperCase = function(x) { return x.toUpperCase(); };
var hello = function(x) { return 'HELLO, ' + x; };
var greet = function(x){
return hello(toUpperCase(x));
};
greet('kevin');
還好我們只有兩個(gè)步驟玖翅,首先小寫(xiě)轉(zhuǎn)大寫(xiě)翼馆,然后拼接字符串。如果有更多的操作金度,greet 函數(shù)里就需要更多的嵌套应媚,類似于 fn3(fn2(fn1(fn0(x))))。
試想我們寫(xiě)個(gè) compose 函數(shù):
var compose = function(f,g) {
return function(x) {
return f(g(x));
};
};
var greet = compose(hello, toUpperCase);
greet('kevin');
利用 compose 將兩個(gè)函數(shù)組合成一個(gè)函數(shù)猜极,讓代碼從右向左運(yùn)行中姜,而不是由內(nèi)而外運(yùn)行,可讀性大大提升跟伏。這便是函數(shù)組合扎筒。
最后寫(xiě)一個(gè) compose 函數(shù)支持傳入多個(gè)函數(shù)呢?這樣就變成了:
compose(d, c, b, a)
我們直接抄襲 underscore 的 compose 函數(shù)的實(shí)現(xiàn):
function compose() {
var args = arguments;
var start = args.length - 1;
return function() {
var i = start;
var result = args[start].apply(this, arguments);
while (i--) result = args[i].call(this, result);
return result;
};
};
這樣就可以支持多個(gè)函數(shù)了的使用了
使用方法:
function compose() {
var args = arguments;
var start = args.length - 1;
return function () {
var i = start;
var result = args[start].apply(this, arguments);
while (i--) result = args[i].call(this, result);
return result;
};
};
var toUpperCase = function (x) { return x.toUpperCase(); };
var hello = function (x) { return 'HELLO, ' + x; };
var happy = function (x) { return 'happy ' + x; };
let greet = compose(happy, hello, toUpperCase);
console.log(greet('xff')); //happy HELLO, XFF
11酬姆、JavaScript函數(shù)記憶
函數(shù)記憶是指將上次的計(jì)算結(jié)果緩存起來(lái)嗜桌,當(dāng)下次調(diào)用時(shí),如果遇到相同的參數(shù)辞色,就直接返回緩存中的數(shù)據(jù)骨宠。
function add(a, b) {
return a + b;
}
// 假設(shè) memoize 可以實(shí)現(xiàn)函數(shù)記憶
var memoizedAdd = memoize(add);
memoizedAdd(1, 2) // 3
memoizedAdd(1, 2) // 相同的參數(shù),第二次調(diào)用時(shí)相满,從緩存中取出數(shù)據(jù)层亿,而非重新計(jì)算一次
實(shí)現(xiàn)這樣一個(gè) memoize 函數(shù)很簡(jiǎn)單,原理上只用把參數(shù)和對(duì)應(yīng)的結(jié)果數(shù)據(jù)存到一個(gè)對(duì)象中立美,調(diào)用時(shí)匿又,判斷參數(shù)對(duì)應(yīng)的數(shù)據(jù)是否存在,存在就返回對(duì)應(yīng)的結(jié)果數(shù)據(jù)建蹄。
函數(shù)的實(shí)現(xiàn):
function memoize(f) {
var cache = {};
return function(){
var key = arguments.length + Array.prototype.join.call(arguments, ",");
if (key in cache) {
return cache[key]
}
else {
return cache[key] = f.apply(this, arguments)
}
}
}
即可碌更。但是參數(shù)為對(duì)象的時(shí)候裕偿,就會(huì)自動(dòng)調(diào)用 toString 方法轉(zhuǎn)換成 [Object object],再拼接字符串作為 key 值痛单。我們寫(xiě)個(gè) demo 驗(yàn)證一下這個(gè)問(wèn)題:
var propValue = function(obj){
return obj.value
}
var memoizedAdd = memoize(propValue)
console.log(memoizedAdd({value: 1})) // 1
console.log(memoizedAdd({value: 2})) // 1
所以進(jìn)行改良
var memoize = function(func, hasher) {
var memoize = function(key) {
var cache = memoize.cache;
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
if (!cache[address]) {
cache[address] = func.apply(this, arguments);
}
return cache[address];
};
memoize.cache = {};
return memoize;
};
var memoizedAdd = memoize(add, function(){
var args = Array.prototype.slice.call(arguments)
return JSON.stringify(args)
})
console.log(memoizedAdd(1, 2, 3)) // 6
console.log(memoizedAdd(1, 2, 4)) // 7
如果使用 JSON.stringify嘿棘,參數(shù)是對(duì)象的問(wèn)題也可以得到解決,因?yàn)榇鎯?chǔ)的是對(duì)象序列化后的字符串旭绒。
函數(shù)記憶只是一種編程技巧鸟妙,本質(zhì)上是犧牲算法的空間復(fù)雜度以換取更優(yōu)的時(shí)間復(fù)雜度,在客戶端 JavaScript 中代碼的執(zhí)行時(shí)間復(fù)雜度往往成為瓶頸挥吵,因此在大多數(shù)場(chǎng)景下重父,這種犧牲空間換取時(shí)間的做法以提升程序執(zhí)行效率的做法是非常可取的忽匈。
斐波拉契數(shù)可用坪郭,這個(gè)例子是用來(lái)表明一種使用的場(chǎng)景,也就是如果需要大量重復(fù)的計(jì)算脉幢,或者大量計(jì)算又依賴于之前的結(jié)果,便可以考慮使用函數(shù)記憶嗦锐。而這種場(chǎng)景嫌松,當(dāng)你遇到的時(shí)候,你就會(huì)知道的奕污。
大佬鏈接
12萎羔、es6的definePropty和proxy
使用 defineProperty 和 proxy 的區(qū)別,當(dāng)使用 defineProperty碳默,我們修改原來(lái)的 obj 對(duì)象就可以觸發(fā)攔截贾陷,而使用 proxy,就必須修改代理對(duì)象嘱根,即 Proxy 的實(shí)例才可以觸發(fā)攔截髓废。
大佬鏈接
13、vue官方api閱讀:
①该抒、vue API的 Vue.directive 指令綁定怎么用慌洪?
在vue框架中,我們開(kāi)發(fā)者凑保,時(shí)常使用vue自帶的指令冈爹,比如v-on,v-for欧引,v-modal等等频伤。
同樣的,vue提供給開(kāi)發(fā)者一些鉤子芝此,用以幫助開(kāi)發(fā)者自定義vue指令憋肖,用法和v-on等是一樣的因痛。
這個(gè)寫(xiě)得清楚
②、Vue.use 瞬哼?
這個(gè)是針對(duì)vue插件的api
https://segmentfault.com/a/1190000012296163
③婚肆、Vue.compile:將一個(gè)模板字符串編譯成 render 函數(shù)。只在完整版時(shí)可用坐慰。
var res = Vue.compile('<div><span>{{ msg }}</span></div>')
new Vue({
data: {
msg: 'hello'
},
render: res.render,
staticRenderFns: res.staticRenderFns
})
④较性、Vue.observable 可以將一個(gè)對(duì)象響應(yīng)式
返回的對(duì)象可以直接用于渲染函數(shù)和計(jì)算屬性內(nèi),并且會(huì)在發(fā)生變更時(shí)觸發(fā)相應(yīng)的更新结胀。也可以作為最小化的跨組件狀態(tài)存儲(chǔ)器赞咙,用于簡(jiǎn)單的場(chǎng)景
const state = Vue.observable({ count: 0 })
const Demo = {
render(h) {
return h('button', {
on: { click: () => { state.count++ }}
}, `count is: ${state.count}`)
}
}
⑤、Vue.version 提供字符串形式的 Vue 安裝版本號(hào)糟港。這對(duì)社區(qū)的插件和組件來(lái)說(shuō)非常有用攀操,你可以根據(jù)不同的版本號(hào)采取不同的策略。
⑥秸抚、propsData 創(chuàng)建實(shí)例時(shí)傳遞 props速和。主要作用是方便測(cè)試。只用于 new 創(chuàng)建的實(shí)例中剥汤。
var Comp = Vue.extend({
props: ['msg'],
template: '<div>{{ msg }}</div>'
})
var vm = new Comp({
propsData: {
msg: 'hello'
}
})
⑦颠放、renderError
當(dāng) render 函數(shù)遭遇錯(cuò)誤時(shí),提供另外一種渲染輸出吭敢。其錯(cuò)誤將會(huì)作為第二個(gè)參數(shù)傳遞到 renderError碰凶。這個(gè)功能配合 hot-reload 非常實(shí)用。
⑧鹿驼、provide/inject
在父組件中通過(guò)provider來(lái)提供變量欲低,然后在子組件中通過(guò)inject來(lái)注入變量。
需要注意的是這里不論子組件有多深畜晰,只要調(diào)用了inject那么就可以注入provider中的數(shù)據(jù)砾莱。而不是局限于只能從當(dāng)前父組件的prop屬性來(lái)獲取數(shù)據(jù)。
用法見(jiàn):provide/inject
⑨凄鼻、listeners
這個(gè)可用于多層組件中傳遞信息 恤磷,跟上面的provide/inject 差不多呢
⑩、vm.on
emit的使用
https://www.cnblogs.com/kadima-zy/p/emit.html
$forceUpdate 強(qiáng)制重新渲染vue實(shí)例 只影響當(dāng)前自己的組件以及子組件
v-html和v-text
http://www.reibang.com/p/a69173cd33c0
v-cloak
CSS屬性加上這個(gè)元素之后一直到編譯結(jié)束才會(huì)顯示
v-cloak
在解決rem布局的時(shí)候會(huì)先布局錯(cuò)亂再恢復(fù)正常的問(wèn)題時(shí)可以用這個(gè)來(lái)解決。
v-pre 跳過(guò)這個(gè)元素和它的子元素的編譯過(guò)程虎敦∮卧溃可以用來(lái)顯示原始 Mustache 標(biāo)簽政敢。跳過(guò)大量沒(méi)有指令的節(jié)點(diǎn)會(huì)加快編譯。
v-once 只渲染元素和組件一次胚迫。隨后的重新渲染喷户,元素/組件及其所有的子節(jié)點(diǎn)將被視為靜態(tài)內(nèi)容并跳過(guò)。這可以用于優(yōu)化更新性能访锻。
14褪尝、Vue.extend的使用?
Vue.extend是vue的全局api
對(duì)比普通場(chǎng)景的使用:
組件模板都是事先定義好的期犬,如果我要從接口動(dòng)態(tài)渲染組件怎么辦河哑?
有內(nèi)容都是在 #app 下渲染,注冊(cè)組件都是在當(dāng)前位置渲染龟虎。如果我要實(shí)現(xiàn)一個(gè)類似于 window.alert() 提示組件要求像調(diào)用 JS 函數(shù)一樣調(diào)用它璃谨,該怎么辦?
大佬鏈接
可以做一個(gè)自定義的全局的彈框 然后自定義傳入相應(yīng)數(shù)據(jù)
export const confirm = function (text, title, onConfirm = () => {}) {
if (typeof title === "function") {
onConfirm = title;
title = undefined;
}
const ConfirmCtor = Vue.extend(Confirm);
const getInstance = () => {
if (!instanceCache) {
instanceCache = new ConfirmCtor({
propsData: {
text,
title,
onConfirm,
},
});
// 生成dom
instanceCache.$mount();
document.body.appendChild(instanceCache.$el);
} else {
// 更新屬性
instanceCache.text = text;
instanceCache.title = title;
instanceCache.onConfirm = onConfirm;
}
return instanceCache;
};
const instance = getInstance();
// 確保更新的prop渲染到dom
// 確保動(dòng)畫(huà)效果
Vue.nextTick(() => {
instance.visible = true;
});
};
作者:晨曦時(shí)夢(mèng)見(jiàn)兮
鏈接:https://juejin.im/post/5e7c08bde51d455c4c66ddad
來(lái)源:掘金
著作權(quán)歸作者所有鲤妥。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)佳吞,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
使用的時(shí)候直接引入這個(gè)組件 然后使用函數(shù)式的調(diào)用即可
15棉安、事件隊(duì)列的理解底扳?
先來(lái)一個(gè)經(jīng)典面試題:
setTimeout(function () {
console.log(4)
}, 0);
new Promise(function (resolve) {
console.log(1)
for (var i = 0;i < 10000;i++) {
i == 9999 && resolve()
}
console.log(2)
}).then(function () {
console.log(5)
});
console.log(3);
為什么打印的正確順序是1,2,3,5,4
而不是1,2,3,4,5
原因:有一個(gè)事件循環(huán),但是任務(wù)隊(duì)列可以有多個(gè)垂券。整個(gè)script代碼,放在了macrotask queue中羡滑,setTimeout也放入macrotask queue菇爪。但是,promise.then放到了另一個(gè)任務(wù)隊(duì)列microtask queue中柒昏。這兩個(gè)任務(wù)隊(duì)列執(zhí)行順序如下凳宙,取1個(gè)macrotask queue中的task,執(zhí)行之职祷。然后把所有microtask queue順序執(zhí)行完氏涩,再取macrotask queue中的下一個(gè)任務(wù)。代碼開(kāi)始執(zhí)行時(shí)有梆,所有這些代碼在macrotask
queue中是尖,取出來(lái)執(zhí)行之。后面遇到了setTimeout泥耀,又加入到macrotask queue中饺汹,然后,遇到了promise.then痰催,放入到了另一個(gè)隊(duì)列microtask queue兜辞。等整個(gè)execution context
stack執(zhí)行完后迎瞧,下一步該取的是microtask queue中的任務(wù)了。因此promise.then的回調(diào)比setTimeout先執(zhí)行逸吵。
鏈接:來(lái)自大佬的鏈接
16: vue.nextTick 的實(shí)現(xiàn)和原理
大佬鏈接
17凶硅、hoc 高階函數(shù)
說(shuō)到這里,我們就要思考一下高階組件到底是什么概念扫皱,其實(shí)說(shuō)到底足绅,高階組件就是:
一個(gè)函數(shù)接受一個(gè)組件為參數(shù),返回一個(gè)包裝后的組件啸罢。
18编检、二、HTTP與HTTPS有什么區(qū)別扰才?
HTTP協(xié)議傳輸?shù)臄?shù)據(jù)都是未加密的允懂,也就是明文的,因此使用HTTP協(xié)議傳輸隱私信息非常不安全衩匣,為了保證這些隱私數(shù)據(jù)能加密傳輸蕾总,于是網(wǎng)景公司設(shè)計(jì)了SSL(Secure Sockets Layer)協(xié)議用于對(duì)HTTP協(xié)議傳輸?shù)臄?shù)據(jù)進(jìn)行加密,從而就誕生了HTTPS琅捏。簡(jiǎn)單來(lái)說(shuō)生百,HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議柄延,要比http協(xié)議安全蚀浆。
HTTPS和HTTP的區(qū)別主要如下:
1、https協(xié)議需要到ca申請(qǐng)證書(shū)搜吧,一般免費(fèi)證書(shū)較少市俊,因而需要一定費(fèi)用。
2滤奈、http是超文本傳輸協(xié)議摆昧,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議蜒程。
3绅你、http和https使用的是完全不同的連接方式,用的端口也不一樣昭躺,前者是80忌锯,后者是443。
4领炫、http的連接很簡(jiǎn)單汉规,是無(wú)狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議针史,比http協(xié)議安全晶伦。
19、移動(dòng)端的邊框0.5px 怎么設(shè)置啄枕?
使用偽元素
給偽元素設(shè)置高度1px 然后背景顏色漸變 或者給y方向縮小0.5
https://www.cnblogs.com/sese/p/7067961.html
20婚陪、vue2.x中怎么修改數(shù)組中的某一項(xiàng)的值?
不能使用arr[i] = xxx;
需要使用arr.splice(index, 1, newitem);
刪除和添加和修改都可以用之后函數(shù)
21频祝、找出字符串中出現(xiàn)次數(shù)最多的字符
我只會(huì)用最low的方法
排序 然后一個(gè)一個(gè)的找
網(wǎng)上看到
通過(guò)obj[key] = num 遇到就累加
obj兩種方法:普通的和reduce的
let testStr = 'asdasddsfdsfadsfdghdadsdfdgdasd';
function getMax(str) {
let obj = {};
for(let i in str) {
if(obj[str[i]]) {
obj[str[i]]++;
}else{
obj[str[i]] = 1;
}
}
let keys = Object.keys(obj); // 獲取對(duì)象中所有key的值返回?cái)?shù)組
let values = Object.values(obj); // 獲取所有value返回?cái)?shù)組
let maxVal = Math.max(...values);// Math.max可以找出傳入?yún)?shù)的最大值泌参,如:Math.max(1,2);這里可使用es6中的解構(gòu),
也可以使用Math.max.apply(Math,values)可認(rèn)為是apply(Math.max, arr)
然后常空,arr是一個(gè)參數(shù)列表沽一,對(duì)于max方法,其參數(shù)是若干個(gè)數(shù)漓糙,即Math.max(a, b, c, d, ...)
console.log(keys[values.indexOf(maxVal)],maxVal);
}
getMax(testStr);
// obj值:{a: 5, s: 7, d: 12, f: 4, g: 2, h: 1, s: 7,}
// 很牛的reduce方法
var testStr = 'asdasddsfdsfadsfdghdadsdfdgdasd';
var testArray = testStr.split('');
var a = testArray.reduce(function(prev,next){
if(next in prev) {
prev[next]++;
}else {
prev[next] = 1;
}
return prev
},{})
console.log(a)
正則:
let stringMax = (str) => {
str = str.split('').sort().join('');
var s = str.match(/(\w+)(\1)/g);
if(s === null) {
return str[0];
}
s = s.map(e => e=e+e[0]);
var out = s.sort((a,b) =>b.length - a.length);
console.log(out[0][0],out[0].length);
};
stringMax(testStr)
22铣缠、把數(shù)字金額轉(zhuǎn)成貨幣格式?