Vue 3 用类的形式编写组件,面向对象(OOP)编程,并提供了常用的装饰器,可以自定义装饰器
用类的形式编写组件,面向对象(OOP)编程,并提供了常用的装饰器,还可以自定义装饰器
不依赖 vue-class-component项目
觉得它的实现方式,跟正常的Class 的用法不一致,所以直接重写了。
vue-class-component 的用法,如果子类也写有生命周期的hook,那实际是所有父类的hook 和 子类的 hook 都会执行一次。
此项目,子类重写父类方法后,如果不显式调用super.xxx 的话,是不会执行父类的hook 的。这跟正常的类的继承、重写保持一致
演示项目地址:https://gitee.com/gowiny/uni-example
npm install @gowiny/vue-class
`
$3
* main.ts
`javascript
import vueClass from '@gowiny/vue-class'
import { createSSRApp } from "vue";
import App from "./App.vue";export function createApp() {
const app = createSSRApp(App);
//如果是 Vue Router 项目,则添加 Vue Router 独有的生命周期钩子
app.use(vueClass,{
hooks:['beforeRouteEnter','beforeRouteUpdate','beforeRouteLeave']
})
//如果是uniapp 项目,则添加uniapp独有的生命周期钩子
/*
app.use(vueClass,{
hooks:['onInit','onLoad','onShow','onReady','onHide','onUnload','onResize','onPullDownRefresh','onReachBottom','onTabItemTap','onShareAppMessage','onPageScroll','onNavigationBarButtonTap',
'onBackPress','onNavigationBarSearchInputChanged','onNavigationBarSearchInputConfirmed','onNavigationBarSearchInputClicked','onShareTimeline','onAddToFavorites']
})
*/
return {
app,
};
}
`
$3
单独使用 $3
`
提供灵活的自定义装饰器的方法:createDecorator
具体使用方法,请参考源码中已有的装饰器的定义方式
createDecorator方法里的参数:ctx : OptionsContextctx.dataFactory
可以通过设置 、ctx.beforeHandle 、ctx.afterHandle 来修改默认实现
javascript
@Options
@Prop
@State
@Action
@Mutation
@Getter
@Provide
@Inject
@Watch
`
$3
`javascript
export default class App extends Vue {
@Prop
declare readonly title:string
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
props:['title']
})
`
------------
`javascript
export default class App extends Vue {
@Prop({
default:'hello gowiny!'
})
declare readonly title:string
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
props:{
title:{
default:'hello gowiny!'
}
}
})
`
------------
$3
`javascript
export default class App extends Vue {
@State
declare readonly appName:string
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
computed:{
appName(){
this.$store.state.appName
}
}
})
`
------------
`javascript
export default class App extends Vue {
@State("app.version")
declare readonly appVersion:string
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
computed:{
appVersion(){
this.$store.state.app.version
}
}
})
`
$3
`javascript
export default class App extends Vue {
@Action
saveScreenSize!:(screenSize:any)=>Promise
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
methods:{
saveScreenSize(screenSize:any):Promise{
return this.$store.dispatch("saveScreenSize",screenSize)
}
}
})
`
------------
`javascript
export default class App extends Vue {
@Action("app/saveScreenSize")
saveScreenSize!:(screenSize:any)=>Promise
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
methods:{
saveScreenSize(screenSize:any):Promise{
return this.$store.dispatch("app/saveScreenSize",screenSize)
}
}
})
`
$3
`javascript
export default class App extends Vue {
@Inject
getScreenSize!:()=>any
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
inject: ['getScreenSize']
})
`
------------
`javascript
export default class App extends Vue {
@Inject
getScreenSize(){
return {width:800,height:600}
}
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
inject: {'getScreenSize':{
default:function(){
return {width:800,height:600}
}
}}
})
`
------------
`javascript
export default class App extends Vue {
@Inject("screenWidth")
width:number
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
inject:{
width:{
from:'screenWidth'
}
}
})
`
------------
`javascript
export default class App extends Vue {
@Inject({from:'screenWidth',default:800})
width!:number
}
`
等同于
`javascript
export default defineComponent( {
name: 'App',
inject: {
width:{
from:'screenWidth',
default:800
}
}
})
``