小别致真东西
文章77
标签31
分类26
前端开发工具整理

前端开发工具整理

开发工具:

1.代码编辑器

  • visual studio Code

    • 插件

      - Chinese 中文插件
      - language-Stylus
      - LeetCode
      - Vetur
      - Prettier
      - React/Redux/react-router Snippets react便捷输入
      - Prettier
      - GitLens
      - Markdown All in One
      - npm Intellisense
      - Quokka.js
      - Relative Path
      - JavaScript code snippets
      - CSS Peek
      - Bracket Pair Colorizer
      - Better Comments
    • 主题

      one dark pro

2.浏览器及插件

Chrome 浏览器

Ghelper 翻墙插件 可在GitHub上获取
ADBlock
marinara(番茄工作法助理)
FireShot
扩展管理器
WEB前端助手
划词翻译
Imagus
Octotree
React/Vue develop Tool
Chrono
掘金插件
Json-handle

3.其他工具

  • 命令行开发工具:

    • iterm2
    • homebrew
    • oh-my-zsh
  • Git/gitLab && 配置SSH

  • node && NVM


    nvm install 8.9.0 // 安装需要的node版本
    nvm use 8.9.0 // 切换使用相对应的node版本
    nvm list
    nvm version

二零一九年下半年大概规划

二零一九年下半年大概规划

原始文字是人类用来纪录特定事物、简化图像而成的书写符号。文字在发展早期都是图画形式的,有些是以形表意,有些是以形表音,其中有表意文字,与语音无甚关系,中国文字便是从此渐次演变而成。有些中文字可以从表面、部首、字旁看到一些联系旁通的字义。而这些特色是拼音文字所没有的。其实这是一篇加密文章,需要密码查看。
JS 基本数据类型和引用类型

JS 基本数据类型和引用类型

Js 基本数据类型

js基本数据类型包括:undefined, null, number, boolean, string, symbol, bigInt(新增)。基本数据类型是按值访问的,就是说我们可以操作保存在变量中的实际的值

1.基本数据类型的值是不可改变的

任何方法都无法改变一个基本类型的值是不可改变的,比如一个字符串:

var name = "change";
name.substr();//hang
console.log(name);//change

var s = "hello";
s.toUpperCase()//HELLO;
console.log(s)//hello

通过这两个例子, 我们原来发现定义的变量 name 的值始终没有发生改变,而调用 substr() 和 toUpperCase() 方法后返回的是一个新的字符串,跟原先定义的变量 name 并没有关系

按值访问

按值进行访问,操作的是保存在变量中实际的值

不可添加方法属性

基础类型的比较是值的比较

基础类型存放在栈区 变量标识符 + 变量值

引用类型

同时保存在栈区和堆区中

栈区保存变量标识符和指向堆区的方法

基本包装类型(包装对象)

Markdown 语法

Markdown 语法

This post is originated from here and is used for testing markdown style. This post contains nearly every markdown usage. Make sure all the markdown elements below show up correctly.

this

this

this-用于访问当前方法所属的对象

const Obj = {
name: 'jack',
fn() {
console.log(this == Obj);
}
}

Obj.fn(); // true
function showThis() {
console.log(this);
}

show(); // window 在此时 show 相当于被 window 对象调用 本身属于 window 是 js 一开始 this 设计的错误 作者可能当时没有考虑清楚

// 在严格模式下 函数直接调用时 this 指向 undefined
'use strict';
function showThis() {
console.log(this);
}

showThis(); // undefined

setTimeout(showThis, 100); // window 此时的 this 指向 window 因为 setTimeout 属于 window 对象
// 相当于
window.setTimeout(showThis, 100);

每个新生成的函数内部都会新建一个 this、这个 this 在函数被调用的时候被绑定
this 在运行时进行绑定
this 提供了一种更为优雅的方式隐式传递一个对象的引用,让 API 设计更加简洁且易于复用

应用场景:

  • 普通函数中的 this 指向全局
  • 构造器里的 this 指向 new 返回的新对象
  • 函数作为方法被调用时,this 指向该对象
  • 箭头函数不会创建自己的 this,使用一个封闭上下文中的 this

改变 this 的指向:

  • .apply()
  • .bind()
  • .call()

forEach 中的 this 指向

const myForEach(cb, thisArg) {
for(let i = 0; i < this.length; i ++) {
cb.call(thisArg, (this[i]));
}
}

// 使用 forEach
const arr = [1, 2, 3];
arr.forEach(function(item){
console.log(this, item); // undefined 1 undefined 2 undefined 3 此时的 this 指向为 undefined
})

改变 this 指向 call 里面的参数

性能优化之浏览器篇

性能优化之浏览器篇

把 Css 放在head 中加载

在浏览器解析完head 部分后、让浏览器知道需要引入哪些css文件,开始并行的去下载css资源,一边下载Css文件一边解析Html, 能够使页面更早的开始渲染

  • 让页面更早的开始渲染、避免闪屏 (DOM 结构先加载出来,css慢了一拍 页面重新渲染)
  • 最好能包含关键渲染路径的样式、首页的样式应该尽快的完成加载、提高用户体验

JS放在 body 标签结束前加载

js 资源的加载会阻塞 HTML 的解析 和 Css的渲染

不使用CSS 表达式

在css属性后使用 expression() 连接一段JavaScript表达式,css属性的值是JavaScript表达式的结果。

background-color: expression((new Date()).getHours()%2?"#FFFFFF": "#000000" );

看似强大, 实际性能开销很大,可能导致页面卡顿

表达式的问题就在于它的计算频率要比我们想象的多。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次。给 CSS 表达式增加一个计数器可以跟踪表达式的计算频率。在页面中随便移动鼠标都可以轻松达到 10000 次以上的计算量。
calc() 性能待验证

移除无匹配的样式

移除无匹配的样式,有两个好处:

  • 删除无用的样式后可以缩减样式文件的体积,加快资源下载速度;

  • 对于浏览器而言,所有的样式规则的都会被解析后索引起来,即使是当前页面无匹配的规则。移除无匹配的规则,减少索引项,加快浏览器查找速度;

用外链的方式引入css 和 js

  • 通过使用外链可以减少html 文件的体积
  • 作为外链文件、Css/Js 可以作为静态资源、通过合理的利用浏览器的缓存对需要的文件进行缓存; 在第二次访问时可以加快页面的加载速度

不要重复加载JS

  • 在IE中,例如在加载一个jquery以后再加载一个jquery,仍然是算作两个不同的请求,不能发挥缓存的优势
  • 重复加载js意味着更长的JS执行时间

用 Get 方式发起 Ajax 请求

  • Get 方式可以缓存
  • 如果是获取信息 Get 更加语义化

如果是提交数据 使用Post 更加语义化

组件延迟加载

规划页面中引用的姿态资源加载顺序、优先级的能力

  • 保障关键页面资源的优先加载: 浏览器的并发数限制

    在同一个域名下面,一般现代浏览器的并发数为6

  • 按需加载 Lazyload 典型: 电商网站

    在图片比较多的电商网站中,lazyload 十分实用 data-src -> src

避免在页面中使用iFrame

  • 会阻塞父文档的 onload 事件
  • 即使是空白iFrame 也比较耗时

减少COOKIE体积

  • COOKIE每次请求都会全都带上
    COOKIE了解更多

    每次请求跟主文档相关的信息,所有的cookie都会带上

减少 JS 中的 DOM 访问

JS中对DOM 的访问是不可避免的, 但可以进行一下优化

  • 对于查找到的元素, 先将其缓存在变量中
  • 节点增加时合理利用 DocumentFragment
  • 不要用JS 去频繁修改样式

使用常见的图片优化手段

相比代码, 图片的体积很大

不要在HTML中缩放图片

在实际中使用什么尺寸的图片就提供多大尺寸的图片

  • 徒增渲染开销, 提供适当尺寸即可

    不要把图片的src置空

  • 在主流浏览器中 IE、Chrome、FireFox 都会引发指向当前主文档的额外请求

参考文档

高性能 CSS

RegExp 正则表达式

RegExp 正则表达式

RegRxp(正则表达式)

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等,简化对字符串的操作

Vue组件通信

Vue组件通信

组件

(Component) 是 Vue.js最强大的功能之一。组件可以扩展,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。

通信类型

父组件与子组件通信

  • 父组件给子组件传递数据 props: 使用props,父组件可以使用props向子组件传递数据
// 父组件 
<template>
<child :msg="message"></child>
</template>

<script>

import child from './child.vue';

export default {
components: {
child
},
data () {
return {
message: 'father message';
}
}
}
</script>
// 子组件
<template>
<div>{{msg}}</div>
</template>

<script>
export default {
// props 另一种写法, 不声明类型与默认值
// props: ['msg']
props: {
msg: {
type: String,
required: true
}
}
}
</script>
```

- 子组件向父组件通信

> 在Vue 中子组件一般不具有操作数据和处理事件的权利,所有的数据和事件的处理都要交给父组件进行操作

**方法一 :** 在子组件中通过$emit()将组件内部的时间传递给父组件的事件进行

```js
// 父组件
<template>
<child @msgFunc="func"></child>
</template>

<script>

import child from './child.vue';

export default {
components: {
child
},
methods: {
func (msg) {
console.log(msg);
}
}
}
</script>

// 子组件
<template>
<button @click="handleClick">点我</button>
</template>

<script>
export default {
props: {
msg: {
type: String,
required: true
}
},
methods () {
handleClick () {
// 提交出去的处理方法的名称与父组件接收的需一致
this.$emit('msgFunc');
}
}
}
</script>
```

**方法二:** 通过修改父组件传递的props来修改父组件数据
> 这种方法只能在父组件传递一个引用变量时可以使用,字面变量无法达到相应效果。因为饮用变量最终无论是父组件中的数据还是子组件得到的props中的数据都是指向同一块内存地址,所以修改了子组件中props的数据即修改了父组件的数据。

> 但是并不推荐这么做,并不建议直接修改props的值,如果数据是用于显示修改的,在实际开发中我经常会将其放入data中,在需要回传给父组件的时候再用事件回传数据。这样做保持了组件独立以及解耦,不会因为使用同一份数据而导致数据流异常混乱,只通过特定的接口传递数据来达到修改数据的目的,而内部数据状态由专门的data负责管理

---

## 兄弟组件进行通信

> 刚开始学习使用Vue时, 在Vue项目中的两个兄弟组件之间如果要进行通信, 通常会通过一个父组件进行数据请求再给子组件传递数据。


- Vuex 是官方推荐的状态管理方案, 不过如果只是中小型项目,状态管理也没有很复杂的话,使用 Vuex 有种杀鸡用牛刀的感觉

- Vue 官方推荐使用一个 Vue 实例作为中央事件总线, 即 `EventBus` ,在需要使用的地方import该Bus

> EventBus 解决了兄弟组件之间的事件传递问题,它的本质是订阅发布者模式,同一个事件发布组件发布了,订阅组件就能获得事件的改变摆脱了兄弟组件之间传值需要父组件转达,Vue事件实例,作为中间者不在页面上显示且具有vue的API 如 emit on

```js
// bus.js => new 一个 Vue 实例
import Vue from 'vue'
export default new Vue()

// clickComponent.vue 相当于发布者, 在需要的组件中订阅就能进行通信
<template>
<div>
<a href="#"class="click" :data-index="index" @click.prevent="doClick($event)">点我</a>
</div>
</template>

<script>
import Bus from '@/common/bus.js'
export default {
props: {
index: Number
},
methods: {
doClick (event) {
// console.log(event.target.dataset.index)
Bus.$emit('getTarget', event.target.dataset.index)
// this.$emit('global: getTarget', event.target.dataset.index)
}
}
}
</script>

// showComponents.vue 另一个兄弟组件 进行订阅

<template>
<div>
{{html}}
</div>
</template>

<script>
import Bus from '@/common/bus.js'
export default {
data () {
return {
html: '还没有点击'
}
},
created () {
Bus.$on('getTarget', index => {
this.html = `第${index}个元素`
})
//this.$on('global: getTarget', index => {
// this.html = `第${index}个元素`
// })
}
}
</script>
```
在node中有一个 `vue-event-proxy` npm包能够实现与EventBus同样的功能,需要安装该npm包, 并且在main.js中进行`引入 `


```js
import EventProxy from 'vue-event-proxy'
Vue.use(EventProxy) // 激活使用
// 完成后即可以使用上面组件中js注释部分的代码代替Bus代码
排序

排序

算法题

如下数字: 35 99 18 76 12  
  • 桶排序
    有[100] for初始化数组
    将数字放到相应的位置

    思想

        利用数组的下标是有序的,待排序的数字大小在下标的范围内,当数组下标等于要排序的数组时
    用待排序的数字坐桶的下标 给相应项+1 类似于做标记的
    myIdea:当下标等于待排序的数字大小 即输出下标 相当于输出较小的数字
    ```

    **时间复杂度:**
    时间复杂度 循环
    O(M+N) 一重循环最大值99 100,又一重循环N,
    之后又有一层循环M 有值的桶子
    嵌套循环 >= 0 1 2 3有限的,<N M+N
    多层循环是最花时间M+N
    O(M+N+M+N)=O(2*(M+N)) O(M+N)

    **缺点:** 占物理内存,因为要分配M个元素的数组

    - 冒泡排序

    ```js
    // 冒泡排序
    // 思想: 比较相邻的元素。如果第一个比第二个大,就交换两数顺序
    const source_arr = [35,18, 99, 18, 76, 12];
    function bubbleSort(arr) {
    const len = arr.length;
    for (let i = 0; i < len; i++) {
    for (let j = 0; j < len - 1 - i; j++) {
    if (arr[j] > arr[j+1]) { // 相邻元素两两对比
    let temp = arr[j+1]; // 元素交换
    arr[j+1] = arr[j];
    arr[j] = temp;
    }
    }
    }
    return arr;
    }
    console.log(bubbleSort(source_arr));
  • 选择排序

    第一重循环默认把 i 个作为最小值与后面 j 循环中的的数进行比较,也就是通过第二重循环与后面的值进行比较

    // n^2
    // 找到数组中最小的值放在第一位,第二小的放在第二位...
    // 基址查询
    function SelectSort(arr) {
    let len = arr.length
    for(let i = 0; i < len; i++) {
    let minIndex = i
    // 如果已经选择了, 前面的就一定是有序的
    for( let j = i; j < len; j++) {
    if( arr[j] < arr[minIndex]) {
    // 循环和默认的最小值进行比较, 如果更小纪录下标
    minIndex = j
    console.log(i, j)
    }
    }
    if(minIndex !== i) {
    [arr[minIndex], arr[i]] = [arr[i], arr[minIndex]]
    }
    }
    return arr
    }
    console.log(SelectSort([45,21,45,12,56,12,67,32,98]))

  • 快排排序

    因为采用了分治思想,所以快 形象的例子 三个数之间进行排序 a b c 再加递归

// 简单排序: 冒泡、选择、插入 时间复杂度都是 n^2
// 复杂排序: 快排、堆排、归并排序 时间复杂度都是 (log2^n)* n
// 分治
// 快排 log2(n)* n for循环 n次
// 1. 随机选择一个数组中的一个数作为一个基准 一般是中点
// 2. 其余数字跟他比较, 小的放左边 大的放右边
// 3. 利用递归的思想, 将左右两边的数重复以上两步
function QuickSort(arr) {
// 这里是出口 当数组长度小于等于1的时候结束递归
if(arr.length <= 1) {
return arr
}
let pivotIndex = Math.floor(arr.length /2)
// 把中间基准值从数组提出来
pivot = arr.splice(pivotIndex, 1)[0] // 选出相应位置的值
console.log(pivot)
let left = [], right = []
for(let i = 0, len = arr.length ; i < len; i++) {
if( arr[i] < pivot) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return QuickSort(left).concat(pivot, QuickSort(right))
}
console.log(QuickSort([85, 24, 63, 45, 17, 31, 78, 56]))
Webpack 相关

Webpack 相关