2021/12/16(更新) 此项目停止更新,新项目计划 https://github.com/2v-design/2v-start-kit
- 使用TypeScript + JSX + vue-class-component的组合方式。
- 实现 class 风格 tsx 格式组件文件输出。
- 支持Vue Templeat模板语.vue文件输出。
- 支持Sass。
- 仅提供学习与参考。
- 多语言
- 主题更换
- 右键菜单
- 防拍水印
- 图片绘制
- 富文本编辑器
- 离线百度地图
- 视频播放器
- 视频录制
- live2d (看板娘)
- Vue + Vue-Cli3 + Vuex + ES6/ES7 + TypeScript + JSX + Sass + ElementUI
bin // 命令
src
/assets // 静态资源
/components // 公共组件
/directive // 指令注册
/plugins // 第三方库
/locale // 语言
/store // Vuex store
/themes // 样式主题
/types // 类型
/utils // 工具
/views // 业务
/router // 路由
/global.ts // 引用声明
/app.tsx
/main.tsx
tsconfig.json // TypeScript配置
package.json // 依赖配置
vue.config.js // vue-cli3配置文件
基础环境规范
基础规范采用 airbnb 的 javascript style guide,在 vscode 下的配置方法如下:
全局安装 tslint 和 typescript:npm install -g tslint typescript
安装 vscode 的 tslint 插件:https://marketplace.visualstudio.com/items?itemName=eg2.tslint
BEM规范
@include b(button) {
@include e(demo) {
@include m(loading) {}
}
}
编译之后
.vtx-button__demo--loading {}
- 通用基础index.tsx组件模板介绍 (使用 npm run new ... 生成组件文件)
// 在components文件夹内生成一个ComponentName文件夹 包含index.tsx和style.scss
npm run new ComponentName
// 生成的index.tsx
import { Component, Vue } from 'vue-property-decorator';
import './style.scss';
@Component<ComponentName>({
props: {},
computed: {},
methods: {},
watch: {},
})
export default class ComponentName extends Vue {
render() { // jsx语法中的render函数,渲染dom结构.
return (
<div></div>
);
}
created() {} // 组件生命周期函数
mounted() {}
destroyed() {}
}
- 基础组件实例参考
- render函数
import { Component, Vue } from 'vue-property-decorator';
import SubComponent from './SubComponent';
@Component<ComponentName>({
components: {
'sub-component': SubComponent,
}
})
export default class ComponentName extends Vue {
list = [1,2,3]
render() {
return (
<ul>
{
this.list.map((i) => {
return this.renderListItem()
})
}
{
this.list.map((i) => {
return (
<sub-component />
)
})
}
</ul>
);
}
// 可以嵌套多个render函数 (推荐以拆分子组件形式 代替render嵌套)
// 必须Dom且只有一个父节点
// 写在render(h)之后 生命周期之前
renderListItem() {
return (
<li>
<span> {i} </span>
</li>
);
}
}
- 属性定义/泛型定义
import { Component, Vue } from 'vue-property-decorator';
@Component<ComponentName>({})
// 定义泛型 问号代表可以没有项属性
interface IlistItem = {
name: string,
total: number,
remark: string,
children?: Ichildren[], // 嵌套另一个泛型
}
interface Ichildren {
name: string,
tile: string,
}
export default class ComponentName extends Vue {
// 类似于Vue写法中的data 有多种方式
list = [] // 1.直接赋值空数组
visible: boolean = false; // 2.加类型再赋值
obj: any = {} // 3.加类型再赋值 any实际为不限内部类型
list: any[] = [] // 4.加类型再赋值 any实际为不限内部类型
tslist: IlistItem[] = [] // 5.加泛型再赋值 结构与类型与泛型保持一致 通常用来校验服务数据/或组件通信
render() {
return (
<div></div>
);
}
mounted() {
this.tslist = [1,2,3]; // 错误 与泛型不一致
this.tslist = [ // 正确 与泛型一致
{
name: 'haha',
total: 2,
remark:'asd',
},
{
name: 'haha',
total: 2,
remark:'asd',
children:[
{
name: 'children1',
tile: 'children1',
},
{
name: 'children2',
tile: 'children2',
},
],
},
]
}
}
- 事件绑定 (function写在生命周期之后)
import { Component, Vue } from 'vue-property-decorator';
@Component<ComponentName>({})
export default class ComponentName extends Vue {
render() {
return (
// 事件绑定
<div
// onClick={(e) => {this.handleClick('string',e:any);}} // 使用箭头函数 一般用于需要接收参数
onClick={this.emitClick} // 无需接收参数时的绑定方式
>
dom结构
</div>
);
}
// 事件绑定 定义function
handleClick(str,e?) {} //问号表示参数为非必传 如多个参数中含非必传 非必传放后面,
}
- 组件通信
import { Component, Vue } from 'vue-property-decorator';
import SubComponent from '../SubComponent' // 引入子组件
@Component<ComponentName>({
components: {
'sub-component': SubComponent,
},
props:{
visibleFromProps: { // 接收父组件传递属性
type: Boolean, // 定义接收类型
require: false, // 是否为必须
default: false // 定义默认值
},
},
})
export default class ComponentName extends Vue {
readonly visibleFromProps!: boolean; // 组件定义this指向的实体属性(如无需更改则添加属性readonly)
visible = false;
render(h) {
return (
<div onClick={(e:any) => {this.emitClick('hi',e:any)}}>
<sub-component
onSubmit={this.submitClick} // 将某个方法 传给子组件以on开头的驼峰格式传入
visible={this.visible} // 属性传递
/>
</div>
);
}
// emit执行父组件传入的方法 注意问号参数代表非必传 顺序靠后
emitClick(type:any,e?) {
this.$emit('visibleClick',type);
}
// 定义某个方法 传给子组件
submitClick() {}
}
- 通过refs操作dom
import { Component, Vue } from 'vue-property-decorator';
import SubComponent from '../SubComponent';
@Component<ComponentName>({
components: {
'sub-component': SubComponent,
}
})
export default class ComponentName extends Vue {
$refs: {
subcomponent!: any, // 如果是组件 则为any
};
render(h) {
return (
<div>
<sub-component ref="subcomponent" /> // 绑定refs
</div>
);
}
mounted() {
this.$nextTick(() => { // 一些组件需等全部渲染完之后再获取
})
}
}
yarn
yarn dev
yarn build
yarn test
yarn lint