vue-develop-template
vue-develop-template copied to clipboard
有ts 版本的吗
@nailfar 还没呢 着急的话可以先自己重写下 应该花不了多久
主要是ts 下有些问题 无法解决 。没有找到一些合适的方案;
比如在vue ts中使用 mixins 怎么做类型检测。 通过 @Component()
在 组件中使用时没有类型检测;
import Vue from "vue";
import { IResponseList } from "@/api/model/response";
/*与后端约定的数据接口*/
export interface IPage<M> {
list: M[];
size: number;
total: number;
}
export default abstract class Pagination< M, T extends IResponseList<M> = IResponseList<M>> extends Vue {
public total: number = 0;
public page: number = 1;
public size: number = 20;
get pageParam(): { size: number; page: number } {
return {
page: this.page - 1,
size: this.size,
};
}
public onSizeChange(size: number) {
console.info(`当前每页${size}条`);
this.size = size;
this.page = 1;
this.getPage();
}
public onPageChange(page: number) {
console.info(`当前第${page}页`);
this.page = page;
this.getPage();
}
public firstPage() {
this.page = 1;
this.refreshPage();
}
public goPage(page: number) {
this.page = page;
}
public refreshPage() {
this.getPage();
}
abstract handlePage(pageParam: { page: number; size: number }): Promise<T>;
private getPage() {
this.handlePage(this.pageParam).then((resp) => {
this.total = resp.total;
this.size = resp.size;
});
}
}
@Component({
mixins: [Pagination],
})
export default class Coupon extends Vue {
couponList:Coupon[]=[];
/*覆盖 pagination 抽象方法 获取数据*/
handlePage(param):Promise<IPage<Coupon>>{
return API.getCoupons(param).then(resp=>{ this.couponList=resp.list; return resp})
}
render(h){
return <div>
<table data={this.couponList}></table>
<el-pager page= {this.page} size={this.size}
onPageChange={this.onPageChange /*这里的page size onPageChange是没有类型检测的。因为在minins里 ts编译器无法探测到这个属性方法*/ } ></el-pager></div>
}
mounted() {
}
}
官网给出的方案是
declare module 'vue/types/vue' {
interface Vue {
page: any,
size: any,
...
}
}
这样解决只能暂时解决,当minxins 和模块数量增加以后 挂载在vue 的属性声明越来越多就难免会冲突。这种解决方式不是很完美,对小型项目还适用。 也尝试过直接 继承 Pagination 类 但是ts只能单继承,多个minixn 的情况就无法适用。若果使用implements 可以多实现 但是就无法隐藏一些实现细节,显然这不是我想要的。大佬可有解决方案
@nailfar 抱歉现在才来回你,mixins 就是有这样的问题,如果要这么使用,暂时也没什么好的解决方式
不过抽离很多不同功能的 mixins,或者大量 mixins 我觉得可能有些不太妥:
- 就如你说的,当minxins 和模块数量增加以后 挂载在vue 的属性声明越来越多就难免会冲突,每个组件的“性能”自然也会不好,即便是你做命名空间,但这又何尝不是增大了工作量,降低了代码可读性。
- 一个业务中可能就用到就 5 个 mixins 的 5个方法,肯定会有冗余,而且会随着业务增长而增长。
- 后期维护起来是比较困难的,就怕有交叉。
是否可以尝试换种思路,不要用 mixins。
@PerseveranceZ 没事,我也是闲暇才回复。
可能之前用 es6 编码时 滥用了很多mixins ,觉得它确实能复用不少代码,还能组合不同功能到一个新组件上。同时也感受到它的弊端: 我在某个方法中使用了 一个 mixins中的方法 ,别人完全不知道这个方法哪里来的,在阅读代码的时候确实挺痛苦的。现在转了ts 以后 希望类型推导能完美解决 这个痛点。
虽然ts官网也给出了一些minixs的解决方案 ,但是不是很友好 ,过程繁琐,目前正在使用此方案。
// Mixin
class Disposable {
isDisposed: boolean;
dispose() {
this.isDisposed = true;
}
}
// Mixin
class Activatable {
isActive: boolean;
activate() {
this.isActive = true;
}
deactivate() {
this.isActive = false;
}
}
// 使用的vscode 自动implements 代码量不是很多 但是繁琐
class SmartObject implements Disposable, Activatable extends Vue {
isDisposed: boolean;
isActive: boolean;
dispose(): void {
throw new Error("Method not implemented.");
}
activate(): void {
throw new Error("Method not implemented.");
}
deactivate(): void {
throw new Error("Method not implemented.");
}
interact() {
this.activate();
}
}
applyMixins(SmartObject, [Disposable, Activatable])
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
})
});
}
class myComponent extend SmartObject {
this.dispose()
}
就目前来看 class A extends MixinsA 能等同 vue.extends ,而且完美契合。唯有extends不能多继承。
@nailfar 这方案非常好啊~,你可以 fork 一份项目 pr 一下你这套规范呢
等项目框架稳定了我再pr 吧 最近比较忙 今天发现个更简单的方法 @Component({ mixins:[Disposable , Activatable ] }) class SmartObject extends Vue< Disposable & Activatable > { constructor(){ // } }
@nailfar 最近在写 ts 版本的了,这边使用 vue-class-component
是可以进行类型检测的
<script lang="ts">
import { Provide, Watch, Vue } from 'vue-property-decorator'
import Component, { mixins } from 'vue-class-component'
import { test1Mixin, test2Mixin } from '@/mixins/mix-test.ts'
import HelloWorld from '@/components/HelloWorld.vue' // @ is an alias to /src
interface Person {
name: string
age: number
}
@Component({components: { HelloWorld }})
export default class Home extends mixins(test1Mixin, test2Mixin) {
@Provide() test: string = 'hahhahaha'
@Provide() person: Person = {
name: 'ddddddddd',
age: 123
}
@Provide() timeout: number = 3000
@Provide() hellowMsg: string = 'hahah'
@Provide() inputValue: string = '123'
@Watch('inputValue')
onInputValueChanged (val: string, oldVal: string) {
console.log(val)
}
changeTest () : void {
setTimeout(() => {
this.test = 'xxx'
}, this.timeout)
}
mounted () {
// this.mixin2Value = 123
this.changeTest()
}
}
</script>
@PerseveranceZ 最近项目赶进度暂时没时间写 vue-class-component 出的 mixins 挺好用。我已经在项目里使用了。 vue-cli 3.0 版本对ts 也支持的。减少了很多ts 方面的配置。tsx 还是需要自己配置。