分类
未分类

前端拾遗|从前端函数式编程开始

函数式编程是什么呢?是一种编程范式,比较经典的函数式语言有 Haskell ,实际上 JacaScript 本身作为一门多范式的语言也是支持函数式的。

函数式具有五个鲜明的特点:

  1. 函数是一等公民
  2. Lambda表达式
  3. 纯函数,也叫没有副作用,不影响外部变量
  4. 不修改外部状态
  5. 引用透明,只依赖于输入的参数

来看一个例子


const arguments = ['qiupu'];
const callName = name => {
  console.log(arguments[0])
}
const callRealName = function(name) {
  console.log(arguments[0])
}
callName('knight'); // qiupu
callRealName ('knight'); // knight

这就是典型的上下文透传的例子。


数组里有一些方法可以实现类似Lodash库的语句组合形式,如链式调用、函数作为参数调用,也可以做一些控制语句代替for/while等。

来看一个例子

在JSX中我们常常看到这样的用法


const menu = (
<div>
  {
    props.post.filter(item =>item.name).map(item=>{
    return <div key={item.id}>{item.name}<div>
    })
  }
</div>
)

这里常见的map、filter等就是常见的 组合子 的包装。

分类
未分类

vue3变化

vue3的变化

全局api

createApp 返回实例 替代 new Vue 使得返回实例不再共享全局配置 全局的方法也从Vue上转移到了实例上

2.x全局API 3.x实例API(app)
Vue.config app.config
Vue.config.productionTip removed
Vue.config.ignoredElements app.config.isCustomElement
Vue.component app.component
Vue.directive app.directive
Vue.mixin app.mixin
Vue.use app.use
Vue.prototype app.config.globalProperties

config.ignoredElements 就是现在 config.isCustomElement

引入此配置选项旨在支持本机自定义元素,因此重命名可以更好地传达其功能。新选项还期望一个比旧字符串/ RegExp方法具有更大灵活性的函数:

 // before
 Vue.config.ignoredElements = ['my-el', /^ion-/]
    
 // after
 const app = Vue.createApp({})
 app.config.isCustomElement = tag => tag.startsWith('ion-')

Vue.prototype 取而代之 config.globalProperties

在Vue 2中,Vue.prototype通常用于添加所有组件都可以访问的属性。 Vue 3中的等效项是config.globalProperties。在实例化应用程序内的组件时,将复制这些属性:

// before - Vue 2
Vue.prototype.$http = () => {}
// after - Vue 3
const app = Vue.createApp({})
app.config.globalProperties.$http = () => {}

一个经过转换的例子如下

const app = createApp(MyApp)

app.component('button-counter', {
  data: () => ({
    count: 0
  }),
  template: '<button @click="count++">Clicked {{ count }} times.</button>'
})

app.directive('focus', {
  mounted: el => el.focus()
})

// button-counter 组件与 focus指令 不会污染全局 只在当前实例
app.mount('#app')

Provide / Inject

// 在父级
app.provide('guide', 'Vue 3 Guide')

// 在任意层次的子级
export default {
  inject: {
    book: {
      from: 'guide'
    }
  },
  template: `<div>{{ book }}</div>`
}

Tree-shaking

因为内部都重写了,所以组件内部也完全是支持摇树优化的,带来的后果就是一些方法需要显式导入来使用

import { nextTick } from 'vue'

nextTick(() => {
  // something DOM-related
})
//before
import { shallowMount } from '@vue/test-utils'
import { MyComponent } from './MyComponent.vue'

test('an async feature', async () => {
    const wrapper = shallowMount(MyComponent)

    // execute some DOM-related tasks

    await wrapper.vm.$nextTick()

    // run your assertions
})
//after
import { shallowMount } from '@vue/test-utils'
import { MyComponent } from './MyComponent.vue'
import { nextTick } from 'vue'

test('an async feature', async () => {
    const wrapper = shallowMount(MyComponent)

    // execute some DOM-related tasks

    await nextTick()

    // run your assertions
})

####受影响的API

2.x全局API 3.x用法
Vue.nextTick 拆分
Vue.observable 替换为 Vue.reactive
Vue.version 拆分
Vue.compile 仅完整版本
Vue.set 仅在兼容版本中
Vue.delete 仅在兼容版本中

参考链接

$attrs的变化

在vue2中,classstyle会被直接设置到组件的根元素并且不会出现在 $attrs中, 当inheritAttrs:false的时候

<template>
  <label>
    <input type="text" v-bind="$attrs" />
  </label>
</template>
<script>
export default {
  inheritAttrs: false
}
</script>

当这样使用的时候

<my-component id="my-id" class="my-class"></my-component>

vue2将生成以下html

<label class="my-class">
    <input type="text" id="my-id" />
</label>

vue3中$attr包含所有属性包括class与style vue3将生成以下html

<label>
    <input type="text" id="my-id" class="my-class" />
</label>

$listeners 在vue3也被移除,现在是$attrs的一部分

自定义指令的生命周期变化

简要总结:

  • API 已重命名,以便更好地与组件生命周期保持一致
  • 自定义指令将由子组件通过 v-bind="$attrs"

对比

2.x 3.x
bind beforeMount
inserted mounted
beforeUpdate
update 已经移除 改用 updated
componentUpdated updated
beforeUnmount
unbind unmounted

###生命周期变化 TODO

###scopedSlots正式弃用 v-slot 指令自 Vue 2.6.0 起被引入,提供更好的支持 slot 和 slot-scope attribute 的 API 替代方案。 v-slot 完整的由来参见这份 RFC 。 在接下来所有的 2.x 版本中 slot slot-scopeattribute 仍会被支持, 但不会出现在 Vue 3 中。 结合具名插槽要这样写

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

异步组件需要显式定义

Mixin合并行为变更

当来自组件的 data() 及其 mixin 或 extends 基类被合并时,现在将浅层次执行合并:

const Mixin = {
  data() {
    return {
      user: {
        name: 'Jack',
        id: 1
      }
    }
  }
}
const CompA = {
  mixins: [Mixin],
  data() {
    return {
      user: {
        id: 2
      }
    }
  }
}

vue2中结果是

{
  user: {
    id: 2,
    name: 'Jack'
  }
}

vue3中结果是

{
  user: {
    id: 2
  }
}
分类
未分类

flex布局常用属性

写组件的时候常常遇到这种情况

设计给的一个设计图 头是固定高度的 底下是自适应的

一般情况下

div{
display:flex;
flex-direction: column;
height:100%;
}

header{
height:50px;
}

body{
height:100%;
}

对一些要求不高的已经可以实现了,但是当下面组件高度很高的时候,flex会进行缩放,导致实际的header高度与预期的不一致,这个时候显式的给header 加上这两个属性就可以让他不缩放了

header{
flex-grow:0;
flex-shrink:0;
height:50px;
}

顺带一提 flex:1 flex: 1; !== flex: 1 1 auto;

  • 第一个参数表示: flex-grow 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
  • 第二个参数表示: flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
  • 第三个参数表示: flex-basis 给上面两个属性分配多余空间之前, 计算项目是否有多余空间, 默认值为 auto, 即项目本身的大小

分类
未分类

typescript 给ws添加属性类型报错怎么解决?类型“WebSocket”上不存在属性xxx

其实很简单 我以我这边使用的ws库为例子 新建一个 shims.d.ts 文件

import ws from "ws";

declare module "ws" {
  export interface WebSocket extends ws {
    $id: string;
  }
}

这样就可以实现扩展了,成功的在ws 上扩展了$id属性

另外注意一点 d.ts文件不要和.ts文件一样命名 不推荐通过后缀区分文件

还有疑问可以加群讨论 秋秋群:768901972

分类
未分类

学习网站记录

项目模板:https://github.com/gothinkster/realworld

博客:V8: https://v8.dev/

Chromium:https://blog.chromium.org/

Google:https://web.dev/blog/

React Dan:https://overreacted.io/

Chrome Manager:https://medium.com/@addyosmani

Google Chrome Developer: https://jakearchibald.com/
Vue: https://zhuanlan.zhihu.com/evanyou

设计模式:https://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html

司徒正美:https://www.cnblogs.com/rubylouvre/
Egg:https://www.yuque.com/egg

Taobao: https://fed.taobao.org/blogs/?spm=taofed.homepage.header.3.7eab5ac8VeGZCx

腾讯:http://www.alloyteam.com/page/0/

网易:https://zhuanlan.zhihu.com/musicfe

编码规范 https://github.com/ecomfe/spec
JavaScript权威指南pdf版 http://rjxz7.gds.name/2015/JavaScriptqwzn6.pdf
git 简易指南 http://rogerdudler.github.io/git-guide/index.zh.html
svn 手册 http://svnbook.red-bean.com/nightly/zh/index.html
史上最全设计模式导学目录 https://blog.csdn.net/lovelion/article/details/17517213
koa实战项目教程 https://github.com/ikcamp/koa2-tutorial
博客工具
git book http://www.chengweiyang.cn/gitbook/index.html
vuepress https://www.vuepress.cn/

《CSS选择器》作者 张鑫旭:https://www.zhangxinxu.com/

木易杨前端进阶 https://muyiy.cn/blog/

冴羽 https://github.com/mqyqingfeng/Blog

cesium介绍 http://cesium.marsgis.cn/go.html?id=cesium-started


Vue 相关源码地址:

vue2.0         https://github.com/vuejs/vue

Vue3.0         https://github.com/vuejs/vue-next

Vuex            https://github.com/vuejs/vuex

Vue-Router  https://github.com/vuejs/vue-router

Nuxt             https://github.com/nuxt

LRU缓存机制:

介绍:https://baike.baidu.com/item/LRU

LeetCode:  https://leetcode-cn.com/problems/lru-cache/solution/lru-huan-cun-ji-zhi-by-leetcode/

最佳实践: https://github.com/isaacs/node-lru-cache

Canvas学习 https://827652549.github.io/CanvasStudy/