Vue Jsx Render开发规范

Vue开发规范

1. Vue render页面格式

import xx from "../xxx";

export default {
  name: "xxx", //名称
  inject: ["xxx"],//注入
  mixins: [xxx], //混入
  props: {  //接入参数
    propsXx: {
      type: [Object...],
      default: null,
      require: true,
      validator: t => {
      ....
      }
    }
  },
  data: () => ({ //属性
    xx: null
  }),
  computed: { //计算属性
    computedXx() {
    ...
    }
  },
  watch: { //监听
    xxx: {
      immediate: false,
      handler: (nv, ov) => {
      ...
      }
    }
  },
  methods: { //方法
    renderXx(h) {
    ...
    }
  },
  mounted() { //生命周期勾子
  ...
  },
  render(h) { //render入口
  ...
  }
}

2. 命名规范

  1. 文件夹名称,多个单词时,使用-连接,如:app-base-config
  2. Vue可复用组件文件名,前缀:Comp,如:CompAppBaseInfoCard
  3. Vue基础组件文件名,前缀:BaseComp,如:BaseCompErrorCard
  4. Vue页面入口文件名,后缀:index,如:AppBaseInfoIndex
  5. Vue api接口方法名,前缀:ajax,如:ajaxGetAppBaseinfo
  6. Vue props属性名,前缀:props,如:propsAppId
  7. Vue computed计算属性名,前缀:computed,如:computedAppId
  8. Vue emit事件名,前缀:emit,如:emitInput

2.1 Vue组件命名

2.1.1 一般组件

组件名应该始终是多个单词的,根组件 App 除外。

正例:

export default {
  name: 'CompTodoItem',
  // ...
}

反例:

export default {
  name: 'CompTodo',
  // ...
}

单文件组件的文件名应该始终是单词大写开头 (PascalCase)

正例:

components/
|- CompMyComponent.js

反例:

components/
|- myComponent.js
|- mycomponent.js

组件名应该倾向于完整单词而不是缩写。

正例:

components/
|- CompStudentDashboardSettings.js
|- CompUserProfileOptions.js
复制代码

反例:

components/
|- SdSettings.js
|- UProfOpts.js
2.1.2 基础组件

【强烈建议】应用特定样式和约定的基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V。

正例:

components/
|- BaseCompButton.js
|- BaseCompTable.js
|- BaseCompIcon.js

反例:

components/
|- MyButton.js
|- VueTable.js
|- Icon.js
2.1.3 单例组件

【强烈建议】只应该拥有单个活跃实例的组件应该以 The 前缀命名,以示其唯一性。
这不意味着组件只可用于一个单页面,而是每个页面只使用一次。这些组件永远不接受任何 prop,因为它们是为你的应用定制的,而不是它们在你的应用中的上下文。如果你发现有必要添加 prop,那就表明这实际上是一个可复用的组件,只是目前在每个页面里只使用一次。

正例:

components/
|- TheHeading.js
|- TheSidebar.js

反例:

components/
|- Heading.js
|- MySidebar.js
2.1.4 紧密耦合的组件名

【强烈建议】和父组件紧密耦合的子组件应该以父组件名作为前缀命名。
如果一个组件只在某个父组件的场景下有意义,这层关系应该体现在其名字上。因为编辑器通常会按字母顺序组织文件,所以这样做可以把相关联的文件排在一起。

正例:

components/
|- CompTodoList.js
|- CompTodoListItem.js
|- CompTodoListItemButton.js
components/
|- CompSearchSidebar.js
|- CompSearchSidebarNavigation.js
复制代码

反例:

components/
|- SearchSidebar.js
|- NavigationForSearchSidebar.js

2.2 javascript变量、方法命名

【强制】语义化、功能化。常量全大写,用下划线连接

// 普通变量      
let arrayIndex = 0;
// 常量      
const HOURS_PER_DAY = 24; 
/**
 * 同步id获取ddl详情
 *
 * @param id
 * @returns {object}
 */
ajaxGetDdlOptionsById(id) {
   return ddl;
}

文件命名参照项目命名规则

正例:DateFormaUtils.js

2.3 枚举

枚举定义在单独的文件中,例如:ProgrammingLanguageTypeEnum.js

// good
export const ProgrammingLanguageTypeEnum = {
  Java: {
    label: 'Java',
    value: 1,
    icon: 'mdi-language-java',
    bgColor: 'bg-primary'
  },
  NodeJS: {
    label: 'Node.js',
    value: 2,
    icon: 'mdi-nodejs',
    bgColor: 'bg-secondary'
  },
  Static: {
    label: 'Static',
    value: 3,
    icon: 'mdi-language-html5',
    bgColor: 'bg-positive'
  }
}

export const ProgrammingLanguageTypeEnumForNumber = {
  1: ProgrammingLanguageTypeEnum.Java,
  2: ProgrammingLanguageTypeEnum.NodeJS,
  3: ProgrammingLanguageTypeEnum.Static,
}

export const ProgrammingLanguageTypeOptions = Object.keys(ProgrammingLanguageTypeEnumForNumber).map(key => (
  {
    label: ProgrammingLanguageTypeEnumForNumber[key].label,
    value: ProgrammingLanguageTypeEnumForNumber[key].value,
    icon: ProgrammingLanguageTypeEnumForNumber[key].icon,
  }
))

2.3 事件名称

【强烈建议】在派发/监听事件的时候,事件最终会被自动转换为短横线式命名(kebab-case)。在声明时间的时候,命名可以为短横线式,但为增强可读性强烈建议使用带类型的驼峰格式,例如:

// Emitting
this.$emit('emitEvent') // instead of emitEvent
// Listening
on:emitEvent

3.代码规范

3.1 简单的计算属性

【强烈建议】保持计算属性的原子性

正例:

computed: {
  basePrice: function () {
    return this.manufactureCost / (1 - this.profitMargin)
  },
  discount: function () {
    return this.basePrice * (this.discountPercent || 0)
  },
  finalPrice: function () {
    return this.basePrice - this.discount
  }
}

反例:

computed: {
  price: function () {
    var basePrice = this.manufactureCost / (1 - this.profitMargin)
    return (
      basePrice -
      basePrice * (this.discountPercent || 0)
    )
  }
}

3.2 props定义

【强制】Props 定义应该尽量详细,必须需要指定其类型。

【强烈建议】Props原子化:虽然 Vue.js 支持传递复杂的 JavaScript 对象通过 props 属性,但是你应该尽可能的使用原始类型的数据。尽量只使用 JavaScript 原始类型(字符串、数字、布尔值)和函数。尽量避免复杂的对象

正例:

props: {
  status: String
}
// 更好的做法!
props: {
  propsStatus: {
    type: String,
    required: true,
    validator: function (value) {
      return [
        'syncing',
        'synced',
        'versionConflict',
        'error'
      ].indexOf(value) !== -1
    }
  }
}

反例:

// 这样做只有开发原型系统时可以接受
props: ['status']

3.3 为多个子组件设置键值

【强烈建议】总是用 key 配合 .map(v-for)。
在多个重复子组件上必须用 key,以便维护内部组件及其子树的状态。甚至在元素上维护可预测的行为,比如动画中的对象固化 (object constancy),也是一种好的做法。

正例:

filterList.map(db => [
            this.renderDbCatalogItem(h, db),
            h('q-item-separator', {staticClass: 'q-ma-none'})
          ])])

renderDbCatalogItem(h, db) {
      return h('div', {
        staticClass: 'pp-selectable-bg q-pl-sm q-pr-sm flex no-wrap justify-between cursor-pointer',
        key: db.id,
      }, [])
    }

反例:

renderDbCatalogItem(h, db) {
      return h('div', {
        staticClass: 'pp-selectable-bg q-pl-sm q-pr-sm flex no-wrap justify-between cursor-pointer',
      }, [])
    }

3.4 Vue Router 规范

【强烈建议】页面跳转数据传递使用路由参数

页面跳转,例如 A 页面跳转到 B 页面,需要将 A 页面的数据传递到 B 页面,推荐使用 路由参数进行传参,而不是将需要传递的数据保存 vuex,然后在 B 页面取出 vuex 的数据,因为如果在 B 页面刷新会导致 vuex 数据丢失,导致 B 页面无法正常显示数据。

let id = ' 123';
this.$router.push({ path: '/user_center', query: { id: id } });
【强烈建议】使用路由懒加载(延迟加载)机制
    {
        path: '/uploadAttachment',
        name: 'uploadAttachment',
        meta: {
          title: '上传附件'
        },
        component: () => import('@/view/components/uploadAttachment/index.vue')
      },

3.4 括号

【强烈建议】下列关键字后必须有大括号(即使代码块的内容只有一行):

if, else, for, while, do, switch, try, catch, finally

// not good
if (condition)
    doSomething();

// good
if (condition) {
    doSomething();
}

3.5 undefined

【强烈建议】不要直接使用 undefined 进行变量判断;使用 typeof 和字符串’undefined’对变量进行判断。

// not good (person未定义时,以下语句会报错)
if (person === undefined) {
    ...
}

// good
if (typeof person === 'undefined') {
    ...
}

3.6 分号

【建议】语句以分号结束

这个是要引起注意的,比如:

// bad
a = b        // 赋值
(function(){
    //....
})()         // 自执行函数

// good
a = b;        // 赋值
(function(){
    //....
})()         // 自执行函数

未加分号,结果被解析成

a = b(function(){/*...*/})()  //将b()()返回的结果赋值给a

3.7 ===

【强制】值比较使用===, ==执行比较前会做类型转换

3.8 其他

【强制】

缩进:使用IDE默认格式化代码方法进行格式化

switch:逻辑分支必须包含default

4. 注释

【强烈建议】核心、复杂逻辑添加必要注释(单行)

// 获取用户上次选的oaBu
if (localStorage.getItem('oa_bu')) {
  this.model.oaBu = JSON.parse(localStorage.getItem('oa_bu'))
}

【强烈建议】方法注释参考JAVA规范, 以/**开头(多行)

/**
 * 获取两个时间戳的可读差值
 *
 * @param startTime
 * @param endTime
 * @returns {string}
 */
export const getTimeDiff = (startTime, endTime) => {
  let dateBegin = new Date(startTime.replace(/-/g, "/"))
  let dateEnd = endTime === null ? new Date() : new Date(endTime.replace(/-/g, "/"))

  let time = dateEnd.getTime() - dateBegin.getTime()
  let duration = (time / (60 * 60 * 1000)).toFixed(2)
  let display = duration < 24 ? `${duration} 小时` : `${(duration / 24).toFixed(2)} 天`
  return display
}

5. 基于模块开发

【强烈建议】始终基于模块的方式来构建你的工程,每一个子模块只做一件事情。

Vue.js 的设计初衷就是帮助开发者更好的开发界面模块。一个模块是应用程序中独立的一个部分。

每一个 Vue 组件(等同于模块)首先必须专注于解决一个单一的问题独立的可复用的微小的可测试的

如果你的组件做了太多的事或是变得臃肿,请将其拆分成更小的组件并保持单一的原则。一般来说,尽量保证每一个文件的代码行数不要超过 500 行。也请保证组件可独立的运行。比较好的做法是增加一个单独的 demo 示例。

6. 使用Mixin(待定,目前不推荐使用)

使用场景:组件的行为和属性类似,例如:模态框

【强制】基础文件命名,例如:MixinBaseModal.js

【强制】mixin组件必须实现的方法前缀必须是abstract,例如:abstractRenderContents()

【强制】为了将Mixin的属性与组件的属性相区分,我们使用$_,原因如下:

  1. 这是Vuejs传统风格
  2. _在Vuejs中表示私有属性
  3. $属于Vue的保留字

风格指南可以看到官方推荐的Mixin命名:

  data: () => ({
    $_myMixin_updateUser: false,
  }),
  methods: {
      $_hide() {
      this.loading = false;
      this.hide()
    },    
  }

使用注意事项:

避免写新的MixinBase

尽量避免同时mixin多个对象

引入单独的功能性方法,尽量使用import而不是mixin

Mixin注意事项:

合并:当混合对象与组件包含同名选项时,这些选项将以适当的策略合并。例如,同名钩子函数被并入一个数组,因而都会被调用。另外,混合的钩子将在组件自己的钩子之前调用。

冲突:值为对象的选项,如 methods, components 和 directives 将合并到同一个对象内。如果键冲突则组件的选项优先。

7. 前后端交互

【强烈建议】服务端发生错误时,返回给前端的响应信息必须包含 HTTP 状态码,errorCode、 errorMessage、用户提示信息四个部分。

【强烈建议】在前后端交互的 JSON 格式数据中,所有的 key 必须为小写字母开始的 lowerCamelCase 风格,符合英文表达习惯,且表意完整。

正例:errorCode / errorMessage / assetStatus / menuList / orderList / configFlag

反例:ERRORCODE / ERROR_CODE / error_message / error-message / errormessage / ErrorMessage / msg

【强烈建议】对于需要使用超大整数的场景,服务端一律使用 String 字符串类型返回,禁止使用 Long 类型。

说明:Java 服务端如果直接返回 Long 整型数据给前端,JS 会自动转换为 Number 类型(注:此类型为双 精度浮点数,表示原理与取值范围等同于 Java 中的 Double)。Long 类型能表示的最大值是 2 的 63 次方 -1,在取值范围之内,超过 2 的 53 次方 (9007199254740992)的数值转化为 JS 的 Number 时,有些数 值会有精度损失。扩展说明,在 Long 取值范围内,任何 2 的指数次整数都是绝对不会存在精度损失的,所 以说精度损失是一个概率问题。若浮点数尾数位与指数位空间不限,则可以精确表示任何整数,但很不幸, 双精度浮点数的尾数位只有 52 位。 反例:通常在订单号或交易号大于等于 16 位,大概率会出现前后端单据不一致的情况,比如,“orderId”: 362909601374617692,前端拿到的值却是: 362909601374617660。

【强制】HTTP 请求通过 URL 传递参数时,不能超过 2048 字节。

说明:不同浏览器对于 URL 的最大长度限制略有不同,并且对超出最大长度的处理逻辑也有差异,2048 字节是取所有浏览器的最小值。 Java 开发手册 27/59 反例:某业务将退货的商品 id 列表放在 URL 中作为参数传递,当一次退货商品数量过多时,URL 参数超长, 传递到后端的参数被截断,导致部分商品未能正确退货。

【强制】HTTP 请求通过 body 传递内容时,必须控制长度,超出最大长度后,后端解析会出错。

说明:nginx 默认限制是 1MB,tomcat 默认限制为 2MB,当确实有业务需要传较大内容时,可以通过调 大服务器端的限制。

8. 规范插件

ESLint - 支持jsx

参考规范附录

Vue官方风格指南

前端规范指南(鹅厂)

Vue.js 最佳实践

Java开发手册(阿里嵩山版)

前端规范

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值