在create-react-app搭建的項(xiàng)目中使用裝飾器
執(zhí)行
yarn eject
命令,暴露出配置項(xiàng)因?yàn)檠b飾器是新的提案,許多瀏覽器和Node環(huán)境并不支持,所以我們需要安裝插件:
@babel/plugin-proposal-decorators
。使用create-react-app
創(chuàng)建的項(xiàng)目自帶這個(gè)插件,不過我們需要配置一下,找到package.json
文件加入一下代碼:
{
"babel": {
"presets": [
"react-app"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{ "legacy": true }
]
]
}
}
另外vscode可能會(huì)提示你需要配置tsconfig
或jsconfig
文件,我們在項(xiàng)目根目錄創(chuàng)建jsconfig.js
,并寫入:
{
"compilerOptions": {
"experimentalDecorators": true
}
}
這樣就能愉快的在項(xiàng)目中使用裝飾器了
裝飾器的使用
使用裝飾器修飾類
//聲明一個(gè)裝飾器
function fn(target){ //這個(gè)函數(shù)的`target`指的就是裝飾器要修飾的類
target.test = false
}
@fn //使用裝飾器
class Person{ //聲明一個(gè)類
}
@fn
class Dog{ //聲明另一個(gè)類
}
console.log(Person.test) //false
console.log(Dog.test) //false
輸出結(jié)果
可以看到Person
類和Dog
類下面多出了一個(gè)test
屬性,這就體現(xiàn)了裝飾器的優(yōu)點(diǎn),無需更改類的內(nèi)部代碼也無需去繼承就可以給類添加新功能
使用裝飾器傳參
@fn
@fn2(5)
class Person{
}
function fn(target){
target.test = false
}
function fn2(value){
return function(target){ //這個(gè)函數(shù)的`target`指的就是裝飾器要修飾的類
target.count = value
}
}
console.log(Person.test)
console.log(Person.count)
聲明一個(gè)裝飾器fn2
,它接收一個(gè)值,并且返回一個(gè)函數(shù),這個(gè)函數(shù)的target
指的就是裝飾器要修飾的類
輸出結(jié)果
使用裝飾器添加實(shí)例屬性
@fn
@fn2(5)
@fn3
class Person{
}
function fn(target){
target.test = false
}
function fn2(value){
return function(target){
target.count = value
}
}
function fn3 (target){
target.prototype.foo = 'hhh' // target指的就是裝飾的類,在類的原型對(duì)象上添加一個(gè)屬性foo
}
const test1 = new Person() // new一個(gè)實(shí)例出來
console.log(test1.foo)
輸出結(jié)果
實(shí)現(xiàn)一個(gè)混入mixins功能
// 實(shí)現(xiàn)一個(gè)mixins功能
export function mixins(...list){
return function (target){
Object.assign(target.prototype,...list)
}
}
import {mixins} from './mixins'
const Test = {
test(){
console.log('這是測試')
}
}
@mixins(Test)
class Myclass{}
const newMyclass = new Myclass()
newMyclass.test() //這是測試
使用裝飾器修飾類的成員
@fn
@fn2(5)
@fn3
class Person{
@readonly message = 'hello'
}
function fn(target){
target.test = false
}
function fn2(value){
return function(target){
target.count = value
}
}
function fn3 (target){
target.prototype.foo = 'hhh'
}
function readonly(target,name,descriptor){
console.log(target) //目標(biāo)類的原型對(duì)象 xxx.prototype
console.log(name) // 被修飾的類的成員名稱
console.log(descriptor)
/*被修飾的類的成員的描述對(duì)象:
configurable: 能否使用delete、能否需改屬性特性、或能否修改訪問器屬性、,false為不可重新定義,默認(rèn)值為true
enumerable: 是否被遍歷,對(duì)象屬性是否可通過for-in循環(huán),flase為不可循環(huán),默認(rèn)值為true
initializer: 對(duì)象屬性的默認(rèn)值,默認(rèn)值為undefined
writable: 對(duì)象屬性是否可修改,flase為不可修改,默認(rèn)值為true
*/
descriptor.writable=false
}
const test1 = new Person()
test1.message = '你好'
它接收三個(gè)參數(shù),具體看以上代碼注釋
輸出結(jié)果