你可能不知道vue还能这样写(终结)

192 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

前言

前面我们学习了vue类组件的写法,但是为什么要这么写呢?它内部的工作原理又是怎么样的呢?我们将在这篇文章中深入剖析;

vue-cli自带了对装饰器的支持,我们使用vue-cli初始化一个项目

类组件的本质

类组件的本质就是面向对象的编程思想,基于原型继承了Vue这个构造函数的方法;也就是说我们写的类组件都是Vue的子类;

类组件上有静态方法,静态属性和实例方法、实例属性

静态方法的this指向类本身,

而实例方法的this指向new出来的实例

类组件上的实例方法和静态方法都不会随着render反复创建,这和React函数组件不同,如果在render函数中声明一个函数那么它就会反复创建,同时类组件较少出现闭包问题

装饰器模式

装饰器可以用在类的属性、方法上,是一种特殊的函数;它可以在不侵入代码的情况给函数附加功能,实现了完美的解耦;也是AOP(面向切面编程)思想的一个实践;装饰器分为多个种类:有类的装饰器、方法装饰器、属性装饰器;

类的装饰器

我们前面学习的@Module、@Component属于类的装饰器,我们先把@Component装饰器去掉看一看会出现什么? Error: render function or template not defined in component: anonymous

难道它和render函数有关吗?我们打开src/component.ts看一看: image.png 可以看到Component高阶函数的目的就是:遍历我们定义的class组件上的属性,将hooks、methods、data、computed、render拷贝到options里面去,然后就走options API那一套逻辑了

方法、属性装饰器

方法、属性装饰器 实质上是用 Object.defineProperty实现的,它是一个高阶函数(也就是接受一个函数,经过处理后返回一个新的函数);

这里必须提到另一个概念:高阶组件(HOC):接受一个组件作为参数,返回一个新的组件;其实在Vue的类组件中我们也能够使用HOC

我们使用装饰器返回的函数的参数就是Object.defineProperty的参数“obj,property,descriptor”,需要理解的是这个“obj”就是我们这个class,也就是构造函数;

我们来看Prop装饰器源码: image.png 其实非常简单,就是在我们写的这个组件上,把类中的props提取出来然后添加到组件的options.props中,这样就对齐了optionsAPI

总结一下:类组件其实就是一个语法糖,它只是一个“披着羊皮的狼”,我们用这种写法,最后全部都转化为vue的标准语法了,它并不是vue的一种新语法;装饰器模式在前端中有广泛的运用,甚至面试也会经常考察,我们必须掌握它的原理;