2019/10/31 周四
#HTML注釋的重要性
當(dāng)看別人代碼時(shí)會(huì)有大用,
<!-- 每個(gè)功能模塊前必須加注釋 -->
...
<!-- 如果涉及隱藏的必須加end_其他可不加end_start -->
...
<!-- 如果涉及隱藏的必須加end_其他可不加end_end -->
#2019/10/30 周三
#svn拉取代碼
# checkout svn巢音,注意如果密碼錯(cuò)誤,會(huì)不提示重新輸入,如果403forbidden,就是沒權(quán)限
svn checkout http://倉(cāng)庫(kù)地址 --username=用戶名
#如果mac沒有裝xcode挑童,怎么安裝svn
最簡(jiǎn)單的方法:安裝idea或webstorm等工具刻蟹,在里面chenckout svn項(xiàng)目割择,會(huì)提示安裝立宜,按照提示來(lái)即可冒萄。
#2019/10/28 周一
#nginx默認(rèn)超時(shí)時(shí)間為60s
需要注意,前端就算超時(shí)設(shè)置為2分橙数,但如果前端代碼部署到了nginx上尊流,也會(huì)導(dǎo)致1分鐘超時(shí)
location / {
root d:/test/;
fastcgi_connect_timeout 600; # set timeout
fastcgi_send_timeout 600;
fastcgi_read_timeout 600;
}
#常用的組件函數(shù)整理
- 發(fā)布訂閱模式代碼
- 文件大小默認(rèn)為B,轉(zhuǎn)為合適的函數(shù)
- 當(dāng)前時(shí)間獲取函數(shù)
#JS到底是解釋型語(yǔ)言還是編譯型語(yǔ)言
Is JavaScript really interpreted or compiled language ? https://segmentfault.com/a/1190000013126460
Js是一種解釋型語(yǔ)言灯帮,令人困惑的地方:
- —般解釋型語(yǔ)言是逐行解釋執(zhí)行的奠旺,為什么JS會(huì)有変曩提升(hoisting)的能力?
- 執(zhí)行JS時(shí)會(huì)用到JIT, JIT(just in time compilers 及時(shí)編譯)會(huì)做代碼優(yōu)化(同時(shí)也會(huì)創(chuàng)建代碼的編譯版本),解釋型語(yǔ)言無(wú)法做到這些
#變量提升問(wèn)題
在函數(shù)作用域內(nèi)的任何變量聲明都會(huì)被提升到頂部施流,且值為undefined响疚,JS處理聲明語(yǔ)句的過(guò)程:
- 一旦v8引擎進(jìn)入一個(gè)執(zhí)行具體代碼的執(zhí)行上下文(函數(shù)),會(huì)對(duì)代碼進(jìn)行詞法分析或分詞(lexing and tokenizing the code), 會(huì)將代碼切分為原子性的令牌(atomic token) , 比 如foo = 10
- 在分析完當(dāng)前作用域后瞪醋,它會(huì)將翻譯后的版本解析為AST(抽象語(yǔ)法樹)
- 每次遇到聲明都會(huì)將其發(fā)送到作用域忿晕,并創(chuàng)建綁定,每次聲明都會(huì)為變量分配內(nèi)存银受,只是分配內(nèi)存践盼,并不會(huì)通過(guò)修改源代碼來(lái)將變最聲明語(yǔ)句提升,在JS中分配內(nèi)存宾巍,意味著將變量默認(rèn)設(shè)置為undefined
- 在這之后咕幻,引擎每次遇到賦值或者取值,都會(huì)通過(guò)作用域(scope)查找綁定顶霞。如果當(dāng)前作用域中沒有找到肄程,就接著向上級(jí)作用域中查找,直到找到為止
- 接著引擎生成CPU可執(zhí)行的機(jī)器碼
- 最后选浑,代碼執(zhí)行完畢
#JIT是什么
JS start out slow, but then got faster thanks to something colled the JIT, but how does the JiT work ? 通俗一點(diǎn)說(shuō):瀏覽器在解釋執(zhí)行JS時(shí)蓝厌,如果遇到某些語(yǔ)句多次執(zhí)行,會(huì)將對(duì)應(yīng)的語(yǔ)句編譯古徒,并存儲(chǔ)拓提。下次再執(zhí)行相同的語(yǔ)句時(shí),不用再重新編譯隧膘,而是直接執(zhí)行之前存儲(chǔ)的該語(yǔ)句編譯的版本代态。當(dāng)然里面不止這么簡(jiǎn)單,還有很多優(yōu)化疹吃, 詳情參考: A crash course in just-in-time (JIT) compilers
#總結(jié)
- JS需要有JS引擎解析才能執(zhí)行蹦疑。這是解釋型語(yǔ)需要的,編譯型語(yǔ)言程序你能直接運(yùn)行互墓。
- 變量提升只是JS解釋器處理事情的方式導(dǎo)致的必尼,
- JIT 是唯一一點(diǎn)可以對(duì)JS是否是解釋型語(yǔ)言提出疑問(wèn)的理由蒋搜。但JIT不是完整的編譯器篡撵,它僅在執(zhí)行前編譯判莉,且JIT只是Mozilla 和 Google開發(fā)人員為了提升瀏覽器性能才引入的,JS或TC39從沒有強(qiáng)制要求使用JIT育谬, 綜上:JS是解釋型語(yǔ)言或混合型語(yǔ)言(編譯型型和解釋型的混合)券盅,而不是編譯型語(yǔ)畝。
#2019/10/26 周六
#原生JS實(shí)現(xiàn)遮罩動(dòng)畫
只需引入一個(gè)JS膛檀,即可載入該動(dòng)畫锰镀,demo地址: https://github.com/zuoxiaobai/fedemo/tree/master/src/DebugDemo/%E9%81%AE%E7%BD%A9%E5%8A%A8%E7%94%BB%E6%95%88%E6%9E%9C
#2019/10/24 周四
#element percentage大于100
element UI報(bào)錯(cuò) custom validator check failed for prop "percentage",進(jìn)度大于100或出錯(cuò)
#2019/10/23 周三
#node res大文件字符串時(shí)內(nèi)存溢出
想把buffer數(shù)據(jù)轉(zhuǎn)為stirng咖刃,設(shè)置為json格式傳到前端泳炉,但如文件過(guò)大,直接就崩了嚎杨。
#2019/10/18 周五
#骨架屏研究
- 一種自動(dòng)化生成骨架屏的方案 https://blog.csdn.net/sinat_17775997/article/details/83443744
- 教你實(shí)現(xiàn)超流行的骨架屏預(yù)加載動(dòng)態(tài)效果 http://www.dxcu.com/news/show-531569.html
- repeating-linear-gradient 線性漸變研究TODO
<head>
<style>
.fast-loading {
height: 20px;
margin: 10px 0;
width: 200px;
background-color: rgb(245, 245, 245);
background-image: repeating-linear-gradient(90deg, #eee, #f5f5f5 100%);
animation-name: fastLoading;
animation-timing-function: linear;
animation-duration: 1s;
animation-iteration-count: infinite;
}
@keyframes fastLoading {
from {
background-position: 0 0;
}
to {
background-position: 100px 0;
}
}
.w100 { width: 100% }
.w80 { width: 80% }
.w60 { width: 60% }
.w40 { width: 50% }
.w30 { width: 30% }
</style>
</head>
<body>
<div style="width: 50%;margin: 50px auto;">
<div class="fast-loading"></div>
<div class="fast-loading w40"></div>
<div class="fast-loading w80"></div>
<div class="fast-loading w60"></div>
<div class="fast-loading w30"></div>
<div class="fast-loading w30"></div>
<div class="fast-loading w50"></div>
<div class="fast-loading w60"></div>
</div>
</body>
#下載文件帶進(jìn)度顯示
- 本地搭建node服務(wù)花鹅,模擬download接口
// index.js
// 運(yùn)行:在控制臺(tái) node index.js
const http = require("http");
const fs = require("fs");
const app = http.createServer((req, res) => {
const { method, url } = req;
if (method === "GET" && url === "/api/download") {
fs.readFile("./file.pdf", (err, data) => {
// 這里以pdf為例子
res.setHeader("Content-Type", "application/pdf");
const fileName = encodeURI('中文')
res.setHeader('Content-Disposition' ,`attachment; filename="${fileName}.pdf"`)
res.end(data);
});
}
})
app.listen(3000)
- 從后端接收文件數(shù)據(jù)時(shí),進(jìn)度顯示
<!-- 導(dǎo)出按鈕 -->
<div class="title-right">
<a href="javascript:void(0)"
:class="{ 'disabled-a': isShowProgress }"
@click="exportExecl">
全部導(dǎo)出
</a>
</div>
<!-- 顯示下載進(jìn)度組件封裝 -->
<download-progress
:progressEvent="progressEvent"
:isShowProgress="isShowProgress"
:cancelDownload="handleWhenPorgresss('end')"
></download-progress>
<script>
import DownloadProgress from './DownloadProgress'
import axios from 'axios'
export default {
components: { DownloadProgress },
data() {
return {
progressEvent: {}, // 下載進(jìn)度
isShowProgress: false, // 是否顯示progress面板, disabled導(dǎo)出按鈕
axiosCancelTokenSource: '', // axios取消請(qǐng)求
}
},
methods: {
onDonloadProgress(progressEvent) {
cosnole.log(progressEvent)
this.progressEvent = progressEvent
},
async exportExecl() {
if (this.isShowProgess) {
console.log('導(dǎo)出中枫浙,點(diǎn)擊無(wú)效')
return
}
try {
this.handleWhenProgress('start')
let axiosConfig = {
onDonloadProgress: this.onDownloadProgess.bind(this),
cancelToken: this.axiosCancelTokenSource.token,
timeout: 120000
}
let data = await xxx.getFileData(null, axiosConfig)
console.log(data)
// blobdata刨肃,在axios配置中 responseType: 'blob' 就會(huì)返回Blob類型數(shù)據(jù)
// 就是是json格式數(shù)據(jù),也會(huì)被轉(zhuǎn)Blob箩帚,TODO 當(dāng)為JSON數(shù)據(jù)時(shí)特殊處理
let fileType = "文件的MIME類型"
if (data.type !=== fileType) {
throw new Error("服務(wù)器返回?cái)?shù)據(jù)類型異常")
}
this.handleWhenProgress('end')
// 下載
this.downloadFile(data, fileType, '文件名')
} catch(e) {
console.log('導(dǎo)出發(fā)生了異常', e)
axios.isCancel(e) ? console.log('請(qǐng)求已取消') : this.$message.error(e.message)
this.handleWhenProgress('end')
}
},
hanldeWhenProgress(state) {
if (state === 'start') {
this.showProgress = true
// 創(chuàng)建axios cancelToken
this.axiosCanelTokenSource = axios.CancelToken.source()
} else {
// 取消axios請(qǐng)求
this.axiosCancelTokenSource.cancal('請(qǐng)求取消')
// 初始化
Object.assign(this, {
isShowProgress: false,
progress: {}
})
}
}
}
}
</script>
<style lang="less“>
.title-right {
a {
color: rgb(36, 156, 211);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
.disabled-a {
color: #888;
&:hover {
cursor: wait;
text-decoration: none;
}
}
}
</style>
- 文件數(shù)據(jù)接收完成后真友,使用axios配合Vue下載文件
// data 后端返回的文件數(shù)據(jù)
function downloadFile(data, fileType, fileName) {
// window.open(dataUrl)
// fileType 文件的MIME類型
// 參考: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
const blobData = new Blob([data], {
type: fileType
})
console.log(blobData) // 檢查數(shù)據(jù)是否正常
//如果是IE,特殊處理紧帕,防止IE下提提示 "拒絕訪問(wèn)"
if (window.navigator.msSaveBlob) {
try {
window.navigator.msSaveBlob(blobData, fileName, + '.xlsx')
} catch(e) {
console.log('msSaveBlob異常', e)
}
return
}
// 創(chuàng)建下載鏈接盔然,并觸發(fā)下載
// https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a#瀏覽器兼容性
// <a> download attribute not support IE, iOS safari
const dataUrl = window.URL.createObjectUrl(blobData)
const downloadElement = document.createElement('a')
downloadElement.href = dataUrl
downloadElement.download = fileName // download文件名
// 觸發(fā)點(diǎn)擊,下載
document.body.appendChild(downloadElement)
documentElement.click()
// 移除輔助下載DOM及對(duì)象URL
document.body.removeChild(downloadElement)
window.URL.revokeObjectURL(dataUrl)
}
#2019/10/17 周四
#純前端實(shí)現(xiàn)execl文件導(dǎo)出
js-xlsx是嗜,github: https://github.com/SheetJS/js-xlsx
#eslint禁止在return中使用賦值
為什么會(huì)有這個(gè)限制轻纪?
function doSomething() {
return foo = bar + 2
}
官方的解釋是:對(duì)于上面的代碼,很難說(shuō)明return的意圖
- 該函數(shù)返回的結(jié)果是bar + 2 為什么要賦值給foo
- 目的還可能是比較運(yùn)算符叠纷,如 ==
存在歧義刻帚,因此最好不要在return語(yǔ)句中使用賦值操作, 解決辦法
- 鼠標(biāo)移動(dòng)到錯(cuò)誤的位置,知道出現(xiàn)快速修復(fù)的按鈕涩嚣,Disabled no-return-assgin for this line崇众,就會(huì)添加異常注釋,// eslint-disabled-next-line on-return-assign
- 為了增強(qiáng)代碼可讀性有些自動(dòng)修復(fù)去掉的括號(hào)可以加上航厚,在配合上面的注釋即可讓eslint忽略
#2019/10/16 周三
#/deep/ 樣式
深度選擇器顷歌,Vue單文件組件中scope樣式,對(duì)子組件會(huì)不生效幔睬。如果想讓某些樣式在子組件里面生效眯漩,可以使用/deep/
<style lang="less" scoped>
/deep/ .el-checkbox {
min-width: 180px;
margin-bottom: 4px;
}
</style>
#2019/10/15 周二
#滾動(dòng)條消失的問(wèn)題
和高度設(shè)置有關(guān),如果,注意用 min-height: calc(100vh - top高度)
#遍歷對(duì)象優(yōu)雅寫法
let obj = {
a: 1,
b: 2
}
Object.keys(obj).forEach(key => {
cosnole.log(key, obj[key])
})
#2019/10/12 周六
##ffffff 與 #fff 的區(qū)別
3位是6位的縮寫赦抖,比如#ccc就是#cccccc的縮寫舱卡。并不是所有的都可以縮寫,必須符合一定的格式队萤。注意:與移動(dòng)端原生交互時(shí)轮锥,顏色不要使用縮寫,安卓可能會(huì)顯示異常要尔。
// 縮寫都是以每?jī)晌粸榭s寫的單位
// #abc => #aabbcc
// #1D2 => #11DD22
#eslint保存時(shí)自動(dòng)fix
vscode默認(rèn)的autofix只能fix .js的文件舍杜,無(wú)法fix .vue的文件,加入下面的配置即可
// config
{
"edit.formatOnSave": false, // 取消自帶fix赵辕,使用eslint自動(dòng)保存fix
"eslint.autoFixOnSave": true, // 每次保存的時(shí)候?qū)⒋a按eslint格式進(jìn)行修復(fù)
"eslint.validate": [
"javascript",
"javascriptreact",
{
"language": "vue",
"autoFix": true
},
"html"
]
}
#全局修改el菜單樣式不影響其他
.vue單文件組件style元素加上scope后既绩,當(dāng)前頁(yè)面修改el-tree的默認(rèn)樣式無(wú)效需要去掉scope,將樣式暴露到全局还惠,但對(duì)全局可能有影響熬词,解決方法是最外層使用特殊的class包裹
<style lang="less">
.root-menu-left {
/* el樣式修改 */
}
</style>
#axios請(qǐng)求攔截
- 請(qǐng)求攔截 axios.interceptors.request.use(resolve func, reject func)
- 響應(yīng)攔截 axios.interceptors.response.use(resolve func, reject func)
- 執(zhí)行順序
- 先執(zhí)行請(qǐng)求攔截(特意在攔截中加了一個(gè)阻塞5s的await)
- 向后端發(fā)送請(qǐng)求
- 觸發(fā)響應(yīng)攔截(這里也可能存在等待時(shí)間)
- 最后才會(huì)執(zhí)行axios請(qǐng)求then后面的內(nèi)容
<!-- demo -->
<body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
// Add a request interceptor
axios.interceptors.request.use(async function (config) {
// Do something before request is sent
console.log('request 攔截: ', config)
// 打印內(nèi)容格式如下:
// {
// "url": "https://zuo11.com/getList?num=5&start=5",
// "data": undefined
// "method": "get",
// "headers": {
// "common": {
// "Accept": "application/json, text/plain, */*"
// }
// },
// "timeout": 0,
// "xsrfCookieName": "XSRF-TOKEN",
// "xsrfHeaderName": "X-XSRF-TOKEN",
// "maxContentLength": -1
// }
// 為所有請(qǐng)求加一個(gè)時(shí)間戳參數(shù)
config.url += (config.url.includes('?') ? '&' : '?') + 't=' + (+new Date())
// Request URL: https://zuo11.com/getList?num=5&start=5&t=1575620590972
await new Promise((resolve, reject) => {
console.log('開始等待中...')
setTimeout(()=> {
resolve('結(jié)束等待')
}, 5000)
})
return config; // 用來(lái)請(qǐng)求的參數(shù)
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
console.log('響應(yīng)攔截', response)
// 如果身份校驗(yàn)失敗,返回登錄頁(yè)
response.data.code === 111 && (window.location.href = response.data)
return response.data // 過(guò)濾掉除data參數(shù)外的其它參數(shù)吸重,響應(yīng)接收到的值互拾。
// return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
});
axios.get('https://zuo11.com/getList?num=5&start=5').then((res) => {
console.log('請(qǐng)求成功,', res)
}, (err)=> {
console.log('請(qǐng)求發(fā)生了錯(cuò)誤,', err)
})
</script>
</body>
參考文檔: https://github.com/axios/axios#interceptors
#2019/10/11 周五
#eltree 懶加載問(wèn)題
懶加載每次加載數(shù)據(jù)都是從后臺(tái)搜索而來(lái)嚎幸,對(duì)于復(fù)雜的邏輯颜矿,建議用文字來(lái)整理,按步驟分解嫉晶,不管邏輯多復(fù)雜骑疆,條理都會(huì)很清晰。
#eltree highlight 屬性
加上后替废,當(dāng)前選中的背景色會(huì)稍微深一點(diǎn)
#v-cloak 指令
防止由于網(wǎng)絡(luò)原因vue.js未渲染時(shí)箍铭,頁(yè)面顯示 的問(wèn)題
// 當(dāng)編譯完成后,v-cloak屬性會(huì)被自動(dòng)移除椎镣。
[v-cloak] {
display: none;
}
<div v-cloak>
{{message/}}
</div>
#2019/10/10 周四
#URLSearchParams() 查詢字符串處理
https://developer.mozilla.org/zh-CN/docs/Web/API/URLSearchParams
var searchParams = new URLSearchParams()
searchParams.append('a', 1212)
searchParams.append('b', 'xxx')
searchParams.toString() // "a=1212&b=xxxx"
// 結(jié)合fromEntries函數(shù)诈火,將查詢字符串轉(zhuǎn)對(duì)象
// https://www.yuque.com/guoqzuo/js_es6/rxu7ms#e6a375d4
Object.fromEntries(new URLSearchParams('foo=bar&baz=qux'))
#前端ajax請(qǐng)求時(shí),設(shè)置Cookie請(qǐng)求頭無(wú)效状答。
W3c規(guī)定冷守,當(dāng)請(qǐng)求的header匹配以下不安全的字符時(shí),將被終止
...
Cookie
Host
Referer
User-Agent
...
#elementUI 全局觸發(fā)消息
// $message(), $alet()
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
// 注意:引入方式不是 .use
Vue.prototype.$message = ElementUI.Message
Vue.prototype.$alert = ElementUI.MessageBox.alert
this.$message({
type: 'error', // warning
message: '這是一條消息'
})
this.$message.error(e.message)
#2019/10/09 周三
#Vue中img的src是動(dòng)態(tài)參數(shù)時(shí)不顯示
解決方法:使用require來(lái)加載圖片惊科, 參考 Vue中img的src是動(dòng)態(tài)渲染時(shí)不顯示(opens new window)
#滾動(dòng)相關(guān)問(wèn)題
進(jìn)入頁(yè)面后拍摇,計(jì)算某個(gè)id的offsetTop,再通過(guò)設(shè)置documet.documentElement.scrollTop滾動(dòng)到該位置馆截。這里滾動(dòng)不了是因?yàn)楦叨仁钱惒郊虞d數(shù)據(jù)后才計(jì)算出來(lái)充活,需要在加載數(shù)據(jù)成功后,再執(zhí)行,并使用 this.$nextTick(()=> {})混卵。這里有耦合映穗,可以用到設(shè)計(jì)模式中的發(fā)布訂閱模式,mounted鉤子函數(shù)訂閱數(shù)據(jù)請(qǐng)求成功的消息淮菠,當(dāng)接收該消息時(shí)執(zhí)行dom操作男公。在異步數(shù)據(jù)請(qǐng)求ok后荤堪,發(fā)布數(shù)據(jù)請(qǐng)求成功的消息合陵。另外這里是否不用操作dom,直接使用hash來(lái)滾動(dòng)澄阳?直接使用element.scrollIntoView()方法拥知?
#window.scroll(x-coord, y-coord)
滾動(dòng)到指定位置
#window.scrollTo()
// https://developer.mozilla.org/zh-CN/docs/Web/API/Window/scrollTo
window.scrollTo(x-coord,y-coord )
window.scrollTo(options)
// * x-coord 是文檔中的橫軸坐標(biāo)。
// * y-coord 是文檔中的縱軸坐標(biāo)碎赢。
// * options 是一個(gè)包含三個(gè)屬性的對(duì)象:
// 1\. top 等同于 y-coord
// 2\. left 等同于 x-coord
// 3\. behavior 類型String,表示滾動(dòng)行為,支持參數(shù) smooth(平滑滾動(dòng)),instant(瞬間滾動(dòng)),默認(rèn)值auto,實(shí)測(cè)效果等同于instant
window.scrollTo( 0, 1000 );
// 設(shè)置滾動(dòng)行為改為平滑的滾動(dòng)
window.scrollTo({
top: 1000,
behavior: "smooth"
});
#window.scrollBy() 相對(duì)于當(dāng)前位置
window.scrollBy(x-coord, y-coord);
window.scrollBy(options)
// * x是水平滾動(dòng)的偏移量低剔,單位:像素。
// * Y 是垂直滾動(dòng)的偏移量肮塞,單位:像素襟齿。
// 正數(shù)坐標(biāo)會(huì)朝頁(yè)面的右下方滾動(dòng),負(fù)數(shù)坐標(biāo)會(huì)滾向頁(yè)面的左上方枕赵。
window.scrollBy(0, window.innerHeight); // 向下滾動(dòng) 一頁(yè)(瀏覽器可視高度)
#Element.scrollTop
Element.scrollTop 屬性可以獲取或設(shè)置一個(gè)元素的內(nèi)容垂直滾動(dòng)的像素?cái)?shù)猜欺。返回文檔在垂直方向已滾動(dòng)的像素值。
window.scrollY
document.documentElement.scrollTop = 100 頁(yè)面滾動(dòng)
#Element.scrollIntoView()
參數(shù)是一個(gè)布爾值拷窜,默認(rèn)為true开皿,滾動(dòng)到元素位置
document.getElementById('注意').scrollIntoView(true)
// https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollIntoView#%E7%A4%BA%E4%BE%8B
#使用hash
url設(shè)置hash,可以滾動(dòng)到對(duì)應(yīng)的id位置
#vue vue-touer 滾動(dòng)
創(chuàng)建Router實(shí)例時(shí)篮昧,可以提供scrollBehavior方法赋荆,來(lái)設(shè)置對(duì)應(yīng)的滾動(dòng)效果。參考: vue-router滾動(dòng)行為
text-overflow: ellipsis
文本溢出處理懊昨,在HTML5權(quán)威指南這本書里是沒有講到這個(gè)知識(shí)點(diǎn)
div.test {
text-overflow: ellipsis;
}
/* 需要結(jié)合下面的三個(gè)屬使用 */
{
white-space: nowrap; /* 不換行 */
overflow: hidden; /* 溢出內(nèi)容隱藏 */
width: 20em; /* 指定寬度 */
}
npm run 端口被占用
npm run dev退出后依舊占用端口窄潭,vscode的console,有時(shí)候可能沒關(guān)閉就開了新的terminal酵颁,把vscode整體退出狈孔,在打開就可以了,可以不依賴vscode的終端材义,使用系統(tǒng)自帶的terminal
# mac 查看端口占用情況:
lsof -i :7000
sudo kill -9 716
# -9后面加一個(gè)空格均抽,然后加上占用端口的進(jìn)程PID,就可以殺掉占用端口的進(jìn)程其掂。最后重啟terminal就ok油挥。
# Mac 查看端口占用情況及殺死進(jìn)程 http://www.reibang.com/p/9216b6127a82