追风

我的前端之路


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 搜索

vue组件通信3-findComponent系列方法

发表于 2019-08-11 | 分类于 Vue

组件的通信 3:找到任意组件实例——findComponents 系列方法

provide / inject 和 dispatch / broadcast。它们有各自的使用场景和局限,比如前者多用于子组件获取父组件的状态,后者常用于父子组件间通过自定义事件通信。

findComponents 系列方法,它并非 Vue.js 内置,而是需要自行实现,以工具函数的形式来使用,它是一系列的函数,可以说是组件通信的终极方案。findComponents 系列方法最终都是返回组件的实例,进而可以读取或调用该组件的数据和方法。

5 个不同的函数:

  • 由一个组件,向上找到最近的指定组件;
  • 由一个组件,向上找到所有的指定组件;
  • 由一个组件,向下找到最近的指定组件;
  • 由一个组件,向下找到所有指定的组件;
  • 由一个组件,找到指定组件的兄弟组件。

实现

5 个函数的原理,都是通过递归、遍历,找到指定组件的 name 选项匹配的组件实例并返回。

向上找到最近的指定组件——findComponentUpward

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// assist.js
// 由一个组件,向上找到最近的指定组件
function findComponentUpward (context, componentName) {
let parent = context.$parent;
let name = parent.$options.name;

while(parent && (!name || [componentName].indexOf(name) < 0){
parent = parent.$parent;
if(parent){
name = parent.$options.name
}
}
return parent
}
export { findComponentUpward }
阅读全文 »

vue组件通信一provide inject

发表于 2019-08-07 | 分类于 Vue

组件的通信 1:provide / inject

vue提供的API,ref 和 $parent / $children 在跨级通信时是有弊端的。为了解决这种跨级通信情况,我们往往会借助Bus和Vuex这些第三方库。但我们还可以借用vue 内置的 provide / inject 接口,实现无依赖的组件通信。

provide / inject

provide / inject 是 Vue.js 2.2.0 版本后新增的 API,在文档中这样介绍 :

https://cn.vuejs.org/v2/api/#provide-inject

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。这与 React 的上下文特性context很相似。
官网提示provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。不过建议归建议,如果你用好了,这个 API 会非常有用。

假设有两个组件: A.vue 和 B.vue,B 是 A 的子组件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// A.vue
export default {
provide: {
name: 'Aresn'
}
}

// B.vue
export defaul {
inject: ['name'],
mounted(){
console.log(this.name) // Aresn
}
}

在 A.vue 里,我们设置了一个 provide: name,值为 Aresn,它的作用就是将 name 这个变量提供给它的所有子组件。而在 B.vue 中,通过 inject 注入了从 A 组件中提供的 name 变量,那么在组件 B 中,就可以直接通过 this.name 访问这个变量了,它的值也是 Aresn。这就是 provide / inject API 最核心的用法。

需要注意的是:

provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,具体参照https://segmentfault.com/a/1190000019836663,那么其对象的属性还是可响应的。

所以,上面 A.vue 的 name 如果改变了,B.vue 的 this.name 是不会改变的,仍然是 Aresn。

阅读全文 »

vue组件三个API:prop、event、slot

发表于 2019-08-04 | 分类于 Vue

基础:Vue.js 组件的三个 API:props、event、slot

我们自己写的vue组件,通常由三部分组成:props、event、slot,这就是我们自己编写组件的API。如果开发一个通用组件,那一定要事先设计好这三部分,因为组件一旦发布,后面再修改 API 就很困难了,使用者都是希望不断新增功能,修复 bug,而不是经常变更接口。如果你阅读别人写的组件,也可以从这三个部分展开,它们可以帮助你快速了解一个组件的所有功能。

属性props

vue 父子组件是通过props进行单向的数据传递,props定义了子组件可配置的属性。写通用组件props最好是使用对象的写法,这样可以针对每个属性设置类型、默认值或自定义校验属性的值。如果直接使用props数组的用法,这样往往不够严谨,下面是一个iView的一个按钮组件<i-button></i-button>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<template>
<button :class="'i-button-size'+size" :disabled="disabled"></button>
</template>
<script>
// 判断参数是否是其中之一
function oneOf(value,validList){
for (let i = 0; i < validList.length; i++) {
if (value === validList[i]) {
return true;
}
}
return false;
}
export default {
props: {
size:{
validator (value){
return oneOf(value, ['small', 'large', 'default']);
},
default: 'default'
},
disabled: {
type: Boolean,
default: false
}
}
}
</script>
<style lang="less" scoped>
.i-button-sizesmall{}
.i-button-sizelarge{}
.i-button-sizedefault{}
</style>

使用组件:

1
2
<i-button size="large"></i-button>
<i-button disabled></i-button>

阅读全文 »

HappyPack构建优化

发表于 2019-08-01 | 分类于 webpack

什么是HappyPack? 作用是什么

​ webpack在构建文件时,比如js,css,图片及字体时,它需要一个一个去解析和编译,不能同时处理多个任务。特别当文件数量变多后,webpack构建慢的问题会显得更为严重。因此HappyPack出现了,它能让webpack同时处理多个任务,它将任务分解给多个子进程去并发执行,子进程处理完成后再将结果发送给主进程中。

​ HappyPack的基本原理:在webpack构建过程中,我们需要使用Loader对js,css,图片,字体等文件做转换操作,并且转换的文件数据量也是非常大的,且这些转换操作不能并发处理文件,而是需要一个个文件进行处理,HappyPack的基本原理是将这部分任务分解到多个子进程中去并行处理,子进程处理完成后把结果发送到主进程中,从而减少总的构建时间。

在配置中使用HappyPack

js/main.js 入口文件代码如下:

1
2
3
4
5
6
7
require('../styles/main.styl');

const $ = require('jquery');
$('#app').html('欢迎你来我的博客');

console.log('这是main.js');
require('./demo1.js');

js/demo1.js 文件如下:

1
2
3
export default function printMe() {
console.log('11111111');
}

styles/main.styl 代码如下:

1
2
3
4
5
6
7
@import "./index.styl"; 
#app
font-size 18px
width 200px
height 200px
display flex
border 1PX solid #ccc
阅读全文 »

Dllplugin

发表于 2019-07-15 | 分类于 webpack

DllPlugin

在平常的项目中,我们要使用到很多的第三方库,如react 、vue 、jquery等。但是他们的内容基本是不变的,版本升级除外。而且这些库每次打包时都要重复的构建,所以我们需要把他们和我们自己写的项目源代码分开。webpack只需要打包我项目本身的文件代码,而不会再去编译第三方库,那么第三方库在第一次打包的时候只打包一次,以后只要我们不升级第三方包的时候,那么webpack就不会对这些库去打包,因此为了解决这个问题,DllPlugin 和DllReferencePlugin插件就产生了。

  • DLLPlugin 这个插件是在一个额外独立的webpack设置中创建一个只有dll的bundle,也就是说我们在项目根目录下除了有webpack.config.js,还会新建一个webpack.dll.config.js文件。webpack.dll.config.js作用是把所有的第三方库依赖打包到一个bundle的dll文件里面,还会生成一个名为 manifest.json文件。该manifest.json的作用是用来让 DllReferencePlugin 映射到相关的依赖上去的。
  • DllReferencePlugin 这个插件是在webpack.config.js中使用的,该插件的作用是把刚刚在webpack.dll.config.js中打包生成的dll文件引用到需要的预编译的依赖上来。

webpack.dll.config.js

在项目根目录下创建一个 `webpack.dll.config.js` 文件。然后配置代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const path = require('path')
const DllPlugin = require('webpack/lib/DllPlugin')

module.exports = {
entry:{
// 项目中用到该两个依赖库文件
react: ['react'],
reactDom: ['react-dom'],
loadsh: ['loadsh']
},
output:{
// 文件名称
filename: '[name].dll.js',
// 将输出的文件放到dist目录下
path: path.resolve(__dirname,'dist/dll'),
/*
存放相关的dll文件的全局变量名称,比如对于jquery来说的话就是 _dll_jquery, 在前面加 _dll
是为了防止全局变量冲突。
*/
library: '_dll_[name]'
},
plugins:[
// 使用插件 DllPlugin
/*
该插件的name属性值需要和 output.library保存一致,该字段值,也就是输出的 manifest.json文件中name字段的值。
比如在jquery.manifest文件中有 name: '_dll_jquery'
*/
new DllPlugin({
name: '_dll_[name]',
/* 生成manifest文件输出的位置和文件名称 */
path: path.join(__dirname, 'dist/dll', '[name].manifest.json')
})

]
}
阅读全文 »
1…456…15
陈虎

陈虎

记录学习,记录生活,记录点滴

74 日志
12 分类
27 标签
RSS
© 2020 陈虎
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.4