Open Meqn opened 6 years ago
[TOC]
MyProject // 项目目录
├── build // 构建相关
├── src // 源代码
│ ├── api // 接口,统一管理
│ ├── assets // 主题 字体等静态资源
│ ├── components // 全局公用组件
│ ├── directive // 全局指令
│ ├── filters // 全局过滤器
│ ├── icons // 项目所有 svg icons
│ ├── libs // 引用的库或自己封装的库
│ ├── lang // 国际化 language
│ ├── mock // 项目mock 模拟数据
│ ├── router // 路由,统一管理
│ ├── store // 全局 store管理
│ ├── styles // 全局样式
│ ├── utils // 全局公用方法
│ ├── vendor // 公用vendor
│ ├── views // 视图目录
│ ├── ├── userCenter
│ ├── ├── ├── index.vue // 模块入口页面
│ ├── ├── ├── components // 模块通用组件文件夹
│ ├── ├── ...
│ ├── App.vue // 入口页面
│ ├── main.js // 入口 加载组件 初始化等
│ └── permission.js // 权限管理
├── public // 第三方不打包资源
├── .babelrc // babel-loader 配置
├── .eslintrc.js // eslint 配置项
├── .browserslistrc
├── .gitignore // git 忽略项
├── favicon.ico // favicon图标
└── package.json // package.json
name
components
、 directives
、 filters
mixins
props
、data
、computed
watch
methods
render
<template>
<div>
// 内容
</div>
</template>
<script>
export default {
// 组件名
name: 'MyComponent',
components: {
// 组件
},
directives: {
// 指令
},
filters: {
// 过滤器
},
mixins: [
// 混合
],
props: {
// 属性
},
data: {
// 本地状态
},
computed: {
// 计算属性
},
watch: {
// 侦听器
}
// 生命周期函数
beforeCreate () {
// 创建前
},
created () {
// 创建后
},
beforeMount () {
// 挂载前
},
mounted () {
// 挂载后
},
beforeUpdate () {
// 更新前
},
updated () {
// 更新后
},
activated () {
// 激活时
},
deactivated () {
// 停用时
},
beforeDestroy () {
// 销毁前
},
destroyed () {
// 销毁后
},
methods: {
// 方法
},
render () {
// 渲染
}
}
</script>
<style lang="scss" scoped>
.component {
//
}
</style>
v-if
和v-for
在一起<ul v-if="users.length > 0">
<li
v-for="user in users"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
官方文档推荐及使用遵循规则:
PascalCase
(单词首字母大写命名)是最通用的声明约定kebab-case
(短横线分隔命名) 是最通用的使用约定
组件名应该始终是多个单词的,根组件 App
除外,且是有意义的名词、简短、具有可读性
命名遵循 PascalCase 约定
比如
TodoList
使用遵循 kebab-case 约定
在页面中使用组件需要前后闭合,并以短线分隔,如
<todo-list></todo-list>
导入及注册组件时,遵循 PascalCase 约定
同时还需要注意:必须符合自定义元素规范,切勿使用保留字。
单文件组件的文件名应该要么始终是单词大写开头 (PascalCase),要么始终是横线连接 (kebab-case)。
且组件名紧密耦合
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
components/
|- todo-list.vue
|- todo-list-item.vue
|- todo-list-item-button.vue
组件名始终多个单词,且PascalCase命名
export default {
name: 'TodoItem'
}
<template>
<todo-item>Todo</todo-item>
</template>
<script>
import TodoItem from '@/components/TodoItem.vue'
export default {
components: {
TodoItem
}
}
</script>
在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板中应该始终使用 kebab-case
<!-- 命名时 -->
<script>
props: {
greetingText: String
}
</script>
<!-- 使用时 -->
<welcome-message greeting-text="hi"></welcome-message>
标签的 Props 应该有统一的顺序,依次为指令、属性和事件。
<my-component
v-if="if"
v-show="show"
v-model="value"
ref="ref"
:key="key"
:text="text"
@input="onInput"
@change="onChange"
/>
超过3个 Props 的元素应该分多行撰写,每个 Props 一行,闭合标签单起一行。
<!-- 较少属性 -->
<my-component v-show="isShow" class="comp-example" />
<!-- 多个属性 -->
<my-component
v-if="isShow"
v-model="value"
ref="ref"
:text="text"
@change="onChange">
这里是内容区域...
</my-component>
在插件、混入等扩展中始终为自定义的私有属性使用
$_
前缀。并附带一个命名空间以回避和其它作者的冲突 (比如$_yourPluginName_
)。
var myGreatMixin = {
// ...
methods: {
$_myGreatMixin_update: function () {
// ...
}
}
}
驼峰式命名,统一使用动词或者动词+名词形式
handleClickTodo、openTodoInfoDialog
请求数据方法,以 data 结尾
getTodoListData、postFormData
附: 函数方法常用的动词
get 获取/set 设置,
add 增加/remove 删除
create 创建/destory 移除
start 启动/stop 停止
open 打开/close 关闭,
read 读取/write 写入
load 载入/save 保存,
create 创建/destroy 销毁
begin 开始/end 结束,
backup 备份/restore 恢复
import 导入/export 导出,
split 分割/merge 合并
inject 注入/extract 提取,
attach 附着/detach 脱离
bind 绑定/separate 分离,
view 查看/browse 浏览
edit 编辑/modify 修改,
select 选取/mark 标记
copy 复制/paste 粘贴,
undo 撤销/redo 重做
insert 插入/delete 移除,
add 加入/append 添加
clean 清理/clear 清除,
index 索引/sort 排序
find 查找/search 搜索,
increase 增加/decrease 减少
play 播放/pause 暂停,
launch 启动/run 运行
compile 编译/execute 执行,
debug 调试/trace 跟踪
observe 观察/listen 监听,
build 构建/publish 发布
input 输入/output 输出,
encode 编码/decode 解码
encrypt 加密/decrypt 解密,
compress 压缩/decompress 解压缩
pack 打包/unpack 解包,
parse 解析/emit 生成
connect 连接/disconnect 断开,
send 发送/receive 接收
download 下载/upload 上传,
refresh 刷新/synchronize 同步
update 更新/revert 复原,
lock 锁定/unlock 解锁
check out 签出/check in 签入,
submit 提交/commit 交付
push 推/pull 拉,
expand 展开/collapse 折叠
begin 起始/end 结束,
start 开始/finish 完成
enter 进入/exit 退出,
abort 放弃/quit 离开
obsolete 废弃/depreciate 废旧,
collect 收集/aggregate 聚集
<template>
<transition :name="transitionName">
<router-view class="root-router-view" />
</transition>
</template>
<script>
export default {
name: 'app',
data() {
return {
transitionName: 'route-left'
}
},
beforeRouteEnter(to, from, next) {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
const transitionName = toDepth < fromDepth ? 'route-right' : 'route-left'
next(vm => {
vm.transitionName = transitionName
})
}
}
</script>
<style>
.root-router-view{
position: fixed !important;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.route-left-enter,
.route-right-leave-active {
transform: translate3d(100%, 0, 0);
}
.route-left-leave-active,
.route-right-enter {
transform: translate3d(-100%, 0, 0);
}
.route-left-enter-active,
.route-left-leave-active,
.route-right-enter-active,
.route-right-leave-active {
transition: transform 0.4s ease;
}
</style>
参考:
// user store.js
export const NAMESPACE = '__USER'
const store = {
namespaced: true,
state: {
user: null
},
getters: {
name(state) {
return (state.user && state.user.name) || ''
}
},
mutations: {
SET_USER(state, value) {
state.user = value
}
},
actions: {
async queryUser({ commit }) {
const res = await fetch('/api/users/110')
commit('SET_USER', res.data)
return res
}
}
}
export default {
install(ctx) {
if (ctx.$store.state[NAMESPACE]) {
return console.log(`${NAMESPACE} has been installed`)
}
ctx.$store.registerModule(NAMESPACE, store)
},
uninstall(ctx) {
if (ctx.$store.state[NAMESPACE]) {
ctx.$store.unregisterModule(NAMESPACE)
}
}
}
例子
// user.vue
import Store, { NAMESPACE } from './store'
export default {
computed: {
user() {
return this.$store.state[NAMESPACE].user
},
username() {
return this.$store.getters[NAMESPACE].name
}
},
beforeCreate() {
Store.install(this)
this.$once('hook:beforeDestroy', () => {
Store.uninstall(this)
})
},
methods: {
getUser() {
this.$store.dispatch(NAMESPACE + '/queryUser')
}
}
}
Vue