https://github.com/weivea/vue3-class-mode-dev
本项目是基于 vue3 以自定义 class的模式来开发的尝试(并非使用vue-class-component);
https://github.com/weivea/vue3-class-mode-dev
Last synced: 12 days ago
JSON representation
本项目是基于 vue3 以自定义 class的模式来开发的尝试(并非使用vue-class-component);
- Host: GitHub
- URL: https://github.com/weivea/vue3-class-mode-dev
- Owner: weivea
- Created: 2020-12-14T07:35:19.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-12-14T07:56:28.000Z (over 5 years ago)
- Last Synced: 2025-01-16T15:22:06.395Z (over 1 year ago)
- Language: TypeScript
- Size: 195 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# vue3-class-mode-dev
本项目是基于 vue3 以自定义 class的模式来开发的尝试(并非使用vue-class-component);
使用typescript + tsx 开发
感觉不错
## sample
```typescript
import { defineComponent, DebuggerEvent, watch } from 'vue';
import {
Base,
Ref,
Reactive,
Mounted,
Updated,
RenderTriggered,
} from './vueClass';
import { State } from '@/store/index';
import { useStore } from 'vuex';
import { useRouter, useRoute } from 'vue-router';
const props = {
message: {
type: String,
default: function() {
return 'Default string';
},
},
};
export class Test extends Base {
@Ref
private data1 = 2;
@Reactive
private dataObj = {
bbcnt: 12,
};
$store = useStore();
$router = useRouter();
$route = useRoute();
constructor(...args: any[]) {
super(...args);
// onMounted(this.handleM1.bind(this));
watch(
() => {
return this.dataObj.bbcnt;
},
(newval, oldVal) => {
console.log('bbcnt change', newval);
},
);
}
clickHander() {
console.log('1233');
this.data1++;
}
clickHander2() {
console.log('bbcnt');
this.dataObj.bbcnt++;
}
@RenderTriggered
@Mounted
handleM1(e?: DebuggerEvent) {
this.handleM2();
console.log('handleM1', e);
}
@Updated
handleM2() {
console.log('handleM2', this.$props.message);
}
handleM3() {
console.log('handleM3', this.$props.message);
}
render() {
return (
213134{this.$props.message}1324134
store: {this.$store.state.key1}
data1:{this.data1}
dataObj.bbcnt:{this.dataObj.bbcnt}
);
}
}
const TestTsx = defineComponent({
props,
setup(props, ctx) {
const r = new Test(props, ctx);
return r.render.bind(r);
},
});
export default TestTsx;
```
```typescript
// vueClass.ts
import {
SetupContext,
ExtractPropTypes,
reactive,
ref,
getCurrentInstance,
onMounted,
onBeforeMount,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
onErrorCaptured,
onRenderTracked,
onRenderTriggered,
} from 'vue';
const hookMethodKey = Symbol('m');
/**
* 推导props类型
*/
export type InferPropsType
= Readonly>;
function runBind(
fn: any,
_this: any,
bindFun: (hook: () => any) => false | Function | undefined,
) {
if (typeof fn === 'function') {
bindFun(fn.bind(_this));
}
}
/**
* 基类
*/
export class Base
{
declare $props: InferPropsType
;
declare $ctx: SetupContext>;
declare [hookMethodKey]: [
keyof this,
(hook: () => any) => false | Function | undefined,
][];
constructor(...args: any[]) {
Object.defineProperty(this, '$props', {
enumerable: false,
configurable: false,
get() {
return args[0];
},
});
Object.defineProperty(this, '$ctx', {
enumerable: false,
configurable: false,
get() {
return args[1];
},
});
const hooks = this[hookMethodKey];
hooks.forEach(([methodName, bindFun]) =>
runBind(this[methodName], this, bindFun),
);
const v = getCurrentInstance();
(v as any).__proto__ = this;
}
}
Base.prototype[hookMethodKey] = [];
/**ref装饰器
* @param target
* @param name
*/
export function Ref(target: any, name: string | number | symbol): any {
const key = Symbol(name.toString());
const descriptor: PropertyDescriptor = {
enumerable: true,
get() {
return (this as any)[key].value;
},
set(val: any) {
const _ref = (this as any)[key];
if (_ref) {
_ref.value = val;
} else {
(this as any)[key] = ref(val);
}
},
};
return descriptor;
}
/**reactive装饰器
* @param target
* @param name
*/
export function Reactive(target: any, name: string | number | symbol): any {
const key = Symbol(name.toString());
const descriptor: PropertyDescriptor = {
enumerable: true,
get() {
return (this as any)[key];
},
set(val: any) {
(this as any)[key] = reactive(val);
},
};
return descriptor;
}
/** onBeforeMount装饰器
* @param target
* @param propertyKey
*/
export function BeforeMount(target: any, propertyKey: keyof any) {
target[hookMethodKey].push([propertyKey, onBeforeMount]);
}
/** onMounnted装饰器
* @param target
* @param propertyKey
*/
export function Mounted(target: any, propertyKey: keyof any) {
target[hookMethodKey]?.push([propertyKey, onMounted]);
}
/** onUpdated装饰器
* @param target
* @param propertyKey
*/
export function Updated(target: any, propertyKey: keyof any) {
target[hookMethodKey]?.push([propertyKey, onUpdated]);
}
/** onBeforeUpdate 装饰器
* @param target
* @param propertyKey
*/
export function BeforeUpdate(target: any, propertyKey: keyof any) {
target[hookMethodKey]?.push([propertyKey, onBeforeUpdate]);
}
/** onBeforeUnmount 装饰器
* @param target
* @param propertyKey
*/
export function BeforeUnmount(target: any, propertyKey: keyof any) {
target[hookMethodKey]?.push([propertyKey, onBeforeUnmount]);
}
/** onUnmounted 装饰器
* @param target
* @param propertyKey
*/
export function Unmounted(target: any, propertyKey: keyof any) {
target[hookMethodKey]?.push([propertyKey, onUnmounted]);
}
/** onErrorCaptured 装饰器
* @param target
* @param propertyKey
*/
export function ErrorCaptured(target: any, propertyKey: keyof any) {
target[hookMethodKey]?.push([propertyKey, onErrorCaptured]);
}
/** onRenderTracked 装饰器
* @param target
* @param propertyKey
*/
export function RenderTracked(target: any, propertyKey: keyof any) {
target[hookMethodKey]?.push([propertyKey, onRenderTracked]);
}
/** onRenderTriggered 装饰器
* @param target
* @param propertyKey
*/
export function RenderTriggered(target: any, propertyKey: keyof any) {
target[hookMethodKey]?.push([propertyKey, onRenderTriggered]);
}
```
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).