Vue Typescript Tsx Save

🤓vue typeScript jsx 工程示例

Project README

2021/12/16(更新) 此项目停止更新,新项目计划 https://github.com/2v-design/2v-start-kit

请使用node v8.17


2019/9/22(更新) 基础模板做了一些删减


Vue logo

概要

  • 使用TypeScript + JSX + vue-class-component的组合方式。
  • 实现 class 风格 tsx 格式组件文件输出。
  • 支持Vue Templeat模板语.vue文件输出。
  • 支持Sass。
  • 仅提供学习与参考。

BLOG中集成的小示例

  • 多语言
  • 主题更换
  • 右键菜单
  • 防拍水印
  • 图片绘制
  • 富文本编辑器
  • 离线百度地图
  • 视频播放器
  • 视频录制
  • live2d (看板娘)

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 下的配置方法如下:

  1. 全局安装 tslint 和 typescript:npm install -g tslint typescript

  2. 安装 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(() => {                   // 一些组件需等全部渲染完之后再获取
    }) 
  }
} 

vue-cli3 请使用node v8.17

Project setup

yarn

Compiles and hot-reloads for development

yarn dev

Compiles and minifies for production

yarn build

Run your tests

yarn test

Lints and fixes files

yarn lint

Customize configuration

See Configuration Reference.

Open Source Agenda is not affiliated with "Vue Typescript Tsx" Project. README Source: nextprops/vue-typescript-tsx
Stars
31
Open Issues
15
Last Commit
1 year ago

Open Source Agenda Badge

Open Source Agenda Rating