klren0312 / daliy_knowledge Goto Github PK
View Code? Open in Web Editor NEW知识积累,正确使用方式是watch
知识积累,正确使用方式是watch
mix.js('resources/assets/vuejs/user/user.js', 'public/js');
mix.sass('resources/assets/vuejs/user/assets/theme/black.scss', 'public/css', {outputStyle: 'compressed'});
mix.sass('resources/assets/vuejs/user/assets/theme/white.scss', 'public/css', {outputStyle: 'compressed'});
// 生产环境
if (mix.inProduction()) {
mix.version([]);
mix.options({
uglify: {
parallel: true, // 加快构建速度
sourceMap: false
}
});
// 去除console.log
mix.config.uglify.uglifyOptions = {
compress: {
warnings: false,
drop_console: true,
pure_funcs: ['console.log']
}
};
}
网页可见区域宽:document.body.clientWidth
网页可见区域高:document.body.clientHeight
网页可见区域宽:document.body.offsetWidth (包括边线的宽)
网页可见区域高:document.body.offsetHeight (包括边线的宽)
网页正文全文宽:document.body.scrollWidth
网页正文全文高:document.body.scrollHeight
网页被卷去的高:document.body.scrollTop
网页被卷去的左:document.body.scrollLeft
网页正文部分上:window.screenTop
网页正文部分左:window.screenLeft
屏幕分辨率的高:window.screen.height
屏幕分辨率的宽:window.screen.width
屏幕可用工作区高度:window.screen.availHeight
屏幕可用工作区宽度:window.screen.availWidth
HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth
scrollHeight: 获取对象的滚动高度。
scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离
scrollWidth:获取对象的滚动宽度
offsetHeight:获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度
offsetLeft:获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置
offsetTop:获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置
event.clientX 相对文档的水平座标
event.clientY 相对文档的垂直座标
event.offsetX 相对容器的水平坐标
event.offsetY 相对容器的垂直坐标
document.documentElement.scrollTop 垂直方向滚动的值
event.clientX+document.documentElement.scrollTop 相对文档的水平座标+垂直方向滚动的
git branch -m 旧分支名 新分支名
git push origin :旧分支
git push origin 新分支
"dependencies": {
"lerna": "file:core/lerna"
}
var taskChartOpt = {
color: ['#d5a200', '#10d092', '#4cc3cb', '#716cc5', '#ef5350'],
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
},
formatter: function (params) {
return params[0].name + '<br>' + params[0].marker + params[0].seriesName + ': ' + byteFormat(params[0].value)
}
},
grid: {
left: '3%',
right: '4%',
bottom: '0',
containLabel: true
},
xAxis: {
type: 'category',
data: [],
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: '#5182c1',
interval: 0,
rotate: 20
}
},
yAxis: {
type: 'value',
axisLine: {
show: false,
},
axisTick: {
show: false
},
splitLine: {
lineStyle: {
type: 'dashed',
color: '#1f385e5f'
}
},
axisLabel: {
color: '#5182c1',
}
},
series: [{
name: '空间占用',
type: 'bar',
itemStyle: {
normal: {
color: function (params) {
var colorList = ['#d5a200', '#10d092', '#4cc3cb', '#716cc5', '#ef5350'];
return colorList[params.dataIndex];
}
}
},
barWidth: '30%',
data: []
}]
};
选项 | 说明 |
---|---|
%H | 提交对象(commit)的完整哈希字串 |
%h | 提交对象的简短哈希字串 |
%T | 树对象(tree)的完整哈希字串 |
%t | 树对象的简短哈希字串 |
%P | 父对象(parent)的完整哈希字串 |
%p | 父对象的简短哈希字串 |
%an | 作者(author)的名字 |
%ae | 作者的电子邮件地址 |
%ad | 作者修订日期(可以用 --date= 选项定制格式) |
%ar | 作者修订日期,按多久以前的方式显示 |
%cn | 提交者(committer)的名字 |
%ce | 提交者的电子邮件地址 |
%cd | 提交日期 |
%cr | 提交日期,按多久以前的方式显示 |
%s | 提交说明 |
git log --pretty=format:"%s"
scope
改为 slot-scope
import 'element-ui/lib/theme-default/index.css'
改为
import 'element-ui/lib/theme-chalk/index.css'
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
原因: vue.config.js
中添加别名
configureWebpack: {
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
}
https://element.eleme.cn/2.8/#/zh-CN/component/checkbox#indeterminate-zhuang-tai
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
handleCheckAllChange
在v1.x
中返回的是事件, 而v2.x
中返回的是全选后的数组
v1.x
没有value-format
npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist
npm config set puppeteer_download_host https://npm.taobao.org/mirrors
yarn config set registry https://registry.npm.taobao.org
yarn config set disturl https://npm.taobao.org/dist
yarn config set puppeteer_download_host https://npm.taobao.org/mirrors
https://github.com/vuejs/vue-router/issues/296
1.搞个重定向页面
<script>
export default {
beforeCreate() {
const { params, query } = this.$route
const { path } = params
this.$router.replace({ path: '/' + path, query })
},
render: function(h) {
return h() // avoid warning message
}
}
</script>
2.刷新
// 手动重定向页面到 '/redirect' 页面
const { fullPath } = this.$route
this.$router.replace({
path: '/redirect' + fullPath
})
1.App.vue
定义
<template>
<div id="app">
<router-view v-if="isRouterAlive"></router-view>
</div>
</template>
<script>
export default {
name: 'App',
provide() {
return {
reload: this.reload
}
},
data() {
return {
isRouterAlive: true
}
},
methods: {
reload() {
this.isRouterAlive = false
this.$nextTick(_ => {
this.isRouterAlive = true
})
}
}
}
</script>
2.使用
<script>
export default {
inject: ['reload']
}
</script>
在方法中调用即可this.reload()
function onScroll() {
var scrollH = $('#carousel-container').height()
var windowH = $(window).scrollTop()
if (windowH > scrollH) {
$('.navbar-default').addClass('active')
} else {
$('.navbar-default').removeClass('active')
}
}
window.addEventListener('scroll', onScroll, false);
let a = document.createElement('a')
a.setAttribute('href', `文件的地址`)
a.setAttribute('download', '') // 强制下载
document.body.appendChild(a)
a.click()
document.body.removeChild(a) // 下载后移除a标签
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
input[type="number"]{
-moz-appearance: textfield;
}
通过每次对比当前时间 与 基本时间加上延迟时间的大小
/**
* 函数节流
* @param {Function} fn 函数
* @param {Number} delay 延时
*/
function throttle(fn, delay) {
var baseTime = 0
return function () {
var currentTime = Date.now()
if (baseTime + delay <= currentTime) {
baseTime = currentTime
fn.apply(this, arguments)
}
}
}
通过判断是否存在timeout
序号, 来判断是否处于节流时间, 但是这会导致第一次执行也会有delay
时间的延时
/**
* 函数节流
* @param {Function} fn 函数
* @param {Number} delay 延时
* @param {Object} context 上下文
*/
function throttle (fn, delay = 100, context = this) {
let timeout = null
let fnArgs = null
return (...args) => {
if (!timeout) {
fnArgs = args
timeout = setTimeout(() => {
fn.apply(context, fnArgs)
timeout = null
}, delay)
}
}
}
const mutations = {
EDIT (state, obj) {
for(var i in obj){
state[i] = obj[i] // 覆盖
}
}
}
toTree(data) {
data.forEach((item) => {
delete item.children
})
this.treeObj = {}
let map = {}
data.forEach((item) => {
map[item.Id] = item
})
this.treeObj = map
let val = []
data.forEach((item) => {
let parent = map[item.ParentId]
if (parent) {
(parent.children || ( parent.children = [] )).push(item)
} else {
item.children = []
val.push(item)
}
})
return val
}
/**
* @jest-environment node
*/
function insertContent(content) {
if (!content) { // 如果插入的内容为空则返回
return
}
let sel = null
if (document.selection) { // IE9以下
sel = document.selection
sel.createRange().pasteHTML(content)
} else {
sel = window.getSelection()
console.log(sel)
if (sel.rangeCount > 0) {
let range = sel.getRangeAt(0) // 获取选择范围
range.deleteContents() // 删除选中的内容
let el = document.createElement("div") // 创建一个空的div外壳
el.innerHTML = content // 设置div内容为我们想要插入的内容。
let frag = document.createDocumentFragment() // 创建一个空白的文档片段,便于之后插入dom树
let node = el.firstChild
let lastNode = frag.appendChild(node)
range.insertNode(frag) // 设置选择范围的内容为插入的内容
let contentRange = range.cloneRange() // 克隆选区
contentRange.setStartAfter(lastNode) // 设置光标位置为插入内容的末尾
contentRange.collapse(true) // 移动光标位置到末尾
sel.removeAllRanges() // 移出所有选区
sel.addRange(contentRange) // 添加修改后的选区
}
}
}
}
正常开发模式, 会在安装puppeteer
时安装chromium
但是编译打包后会漏掉chromium
所以我们可以改用puppeteer-core
, 然后自己配置路径
export default function getChromePath () {
if (process.platform === 'win32') {
return 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
} else {
return '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
}
}
使用的时候
const puppeteer = require('puppeteer-core')
... ...
await puppeteer.launch({
headless: true,
executablePath: this.getChromePath()
})
https://epic-spinners.epicmax.co/#/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style>
.loading-spinner {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
.orbit-spinner, .orbit-spinner * {
box-sizing: border-box;
}
.orbit-spinner {
height: 55px;
width: 55px;
border-radius: 50%;
perspective: 800px;
}
.orbit-spinner .orbit {
position: absolute;
box-sizing: border-box;
width: 100%;
height: 100%;
border-radius: 50%;
}
.orbit-spinner .orbit:nth-child(1) {
left: 0%;
top: 0%;
animation: orbit-spinner-orbit-one-animation 1200ms linear infinite;
border-bottom: 3px solid #009688;
}
.orbit-spinner .orbit:nth-child(2) {
right: 0%;
top: 0%;
animation: orbit-spinner-orbit-two-animation 1200ms linear infinite;
border-right: 3px solid #009688;
}
.orbit-spinner .orbit:nth-child(3) {
right: 0%;
bottom: 0%;
animation: orbit-spinner-orbit-three-animation 1200ms linear infinite;
border-top: 3px solid #009688;
}
@keyframes orbit-spinner-orbit-one-animation {
0% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
@keyframes orbit-spinner-orbit-two-animation {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
@keyframes orbit-spinner-orbit-three-animation {
0% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}
</style>
</head>
<body>
<div class="loading-spinner">
<div class="orbit-spinner">
<div class="orbit"></div>
<div class="orbit"></div>
<div class="orbit"></div>
</div>
</div>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
App.vue
中将加载动画删除... ...
created () {
try {
document.body.removeChild(document.getElementById('loading-spinner'))
} catch (e) {
}
},
... ...
<label for="file-import" class="import-btn">
...
</label>
<input style="display: none;" id="file-import" type="file" @change="fileChange" accept=".txt">
fileChange (e) {
const file = e.target.files[0]
const reader = new FileReader()
reader.onload = (evt) => {
this.importContent = evt.target.result
}
reader.readAsText(file)
}
this.$options.filters
document.querySelector('css选择器').scrollIntoView({
behavior: 'smooth'
})
window.scroll({
top: 2500,
left: 0,
behavior: 'smooth'
});
testestetaet<0,1,5,1,False,False>ewfafewf
<>
中的0,1,5,1,False,False
/\<([^)]+>\>/
`testestetaet<0,1,5,1,False,False>ewfafewf`.match(/\<([^>]+)\>/)[1]
/ \< ( [^>] + ) \> /
\<
: 匹配前括号>
的其他字符\>
: 匹配后括号dom.value(newval)
dom.dispatchEvent(new Event('input'))
先创建一个textarea, 绝对定位到看不到的地方, 将需要复制的字符串放入, 并选中, 使用document.execCommand('copy')
复制文本, 然后删除textarea
const copyToClipboard = str => {
const el = document.createElement('textarea');
el.value = str;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
const selected =
document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
el.select();
document.execCommand('copy');
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
};
学习一下vuex的deepCopy源码
https://github.com/vuejs/vuex/blob/dev/src/util.js#L22
我直接把第29行用的find函数放到里面了, 这样好看一点
/**
* 深拷贝
* @param {*} obj 拷贝对象(object or array)
* @param {*} cache 缓存数组
*/
function deepCopy (obj, cache = []) {
// typeof [] => 'object'
// typeof {} => 'object'
if (obj === null || typeof obj !== 'object') {
return obj
}
// 如果传入的对象与缓存的相等, 则递归结束, 这样防止循环
/**
* 类似下面这种
* var a = {b:1}
* a.c = a
* 资料: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value
*/
const hit = cache.filter(c => c.original === obj)[0]
if (hit) {
return hit.copy
}
const copy = Array.isArray(obj) ? [] : {}
// 将copy首先放入cache, 因为我们需要在递归deepCopy的时候引用它
cache.push({
original: obj,
copy
})
Object.keys(obj).forEach(key => {
copy[key] = deepCopy(obj[key], cache)
})
return copy
}
if obj is hit, it is in circular structure
一开始没理解什么是循环结构, 后来在MDN的一个文章中看到了, 就类似于下图这样的循环结构
typeof
方法对应的是基本类型注: 如果要区分数组和对象, 使用使用 Array.isArray
或者 Object.prototype.toString.call
就是使用递归对数组或者对象进行每一项的复制, 数组当做对象时, 下标即为key
直接使用JSON.parse(JSON.stringify(Object))
来进行
缺点: 如果对象或者数组里有函数什么的, 就会出问题啦
当然对于函数可以使用JSON.stringify()和JSON.parse()的第二个参数进行转换
function stringifyRep(key, value) {
if (typeof value === "function") {
return `${value}`;
}
return value;
}
function parseRep(key, value) {
return eval(value);
}
var a = {
b: () => 1 + 1
}
var aa = JSON.parse(JSON.stringify(a, stringifyRep), parseRep)
更多小方法, 可以查看https://github.com/klren0312/daliy_knowledge/issues
webpack文档: https://webpack.js.org/guides/dependency-management/#requirecontext
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
Vue.use(Vuex)
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', false, /\.js$/)
// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
// set './app.js' => 'app'
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
const store = new Vuex.Store({
modules,
getters
})
export default store
/<\/?.+?\/?>/g
getSuperResultTree() {
// 初始化结果树
this.treeResultData = JSON.parse(JSON.stringify(this.defaultResultData))
const arr = JSON.parse(JSON.stringify(this.$refs.leftTree.getCheckedNodes(true)))
this.useTotal = arr.length // 计入高级搜索的分类数, 用于判断结束
// 将选择的分类相关节点遍历到指定位置
arr.forEach(v => {
let i1 = this.treeResultData.findIndex(t1 => {
return t1.id === v.res[0]
})
let i2 = this.treeResultData[i1].children.findIndex(t2 => {
return t2.data_type === v.res[1]
})
this.treeResultData[i1].children[i2].children.push(v)
})
// 清除未用节点
this.treeResultData = this.treeResultData.filter(v => {
v.children = v.children.filter(u => {
return u.children.length !== 0
})
return v.children.length !== 0
})
console.log('高级结果树', this.treeResultData)
}
Feature | Bull | Kue | Bee | Agenda |
---|---|---|---|---|
Backend | redis | redis | redis | mongo |
Priorities | ✓ | ✓ | ✓ | |
Concurrency | ✓ | ✓ | ✓ | ✓ |
Delayed jobs | ✓ | ✓ | ✓ | |
Global events | ✓ | ✓ | ||
Rate Limiter | ✓ | |||
Pause/Resume | ✓ | ✓ | ||
Sandboxed worker | ✓ | |||
Repeatable jobs | ✓ | ✓ | ||
Atomic ops | ✓ | ✓ | ||
Persistence | ✓ | ✓ | ✓ | ✓ |
UI | ✓ | ✓ | ✓ | |
REST API | ✓ | |||
Optimized for | Jobs / Messages | Jobs | Messages | Jobs |
function ImgToBase64(file, maxLen, callBack) {
var img = new Image();
var reader = new FileReader();//读取客户端上的文件
reader.onload = function () {
var url = reader.result;//读取到的文件内容.这个属性只在读取操作完成之后才有效,并且数据的格式取决于读取操作是由哪个方法发起的.所以必须使用reader.onload,
img.src = url;//reader读取的文件内容是base64,利用这个url就能实现上传前预览图片
};
img.onload = function () {
img.width = maxLen;
img.height = maxLen;
//生成canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
var base64 = canvas.toDataURL('image/jpeg', 0.9);
callBack(base64);
};
reader.readAsDataURL(file);
}
var obj = Object.create(null)
若要使用Object的相关方法, 可以使用call, apply, bind
obj.test = 'ttt'
obj.hasOwnProperty('test') // => Uncaught TypeError: obj.hasOwnProperty is not a function
Object.hasOwnProperty.call(obj, 'test') // => true
Object.hasOwnProperty.apply(obj, ['test']) // => true
Object.hasOwnProperty.bind(obj)('test') // => true
你可以通过 CDN 将其引入:
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>
然后 window.Promise 会自动可用。
如果你喜欢使用诸如 npm 或 Yarn 等包管理器,可以按照下列方式执行安装:
npm install es6-promise --save # npm
yarn add es6-promise # Yarn
或者更进一步,将下列代码添加到你使用 Vuex 之前的一个地方:
import 'es6-promise/auto'
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.