Meqn / store

转载 && 收藏 && 乱七八糟 :clap:
64 stars 9 forks source link

【Vue 2.X】学习笔记 #7

Open Meqn opened 6 years ago

Meqn commented 6 years ago

Vue

Meqn commented 6 years ago

vue-router

Meqn commented 6 years ago

vuex

Meqn commented 6 years ago

精选文章


Meqn commented 5 years ago

vue 经验分享

Meqn commented 5 years ago

vue-router精选

vue-router实现原理 (muwoo)

Meqn commented 5 years ago

Vue 开发规范

[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

组件规范

组件选项顺序

<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-ifv-for 在一起

<ul v-if="users.length > 0">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

命名规范

官方文档推荐及使用遵循规则:

PascalCase (单词首字母大写命名)是最通用的声明约定 kebab-case (短横线分隔命名) 是最通用的使用约定

单文件组件命名

单文件组件的文件名应该要么始终是单词大写开头 (PascalCase),要么始终是横线连接 (kebab-case)。

且组件名紧密耦合

components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue

components/
|- todo-list.vue
|- todo-list-item.vue
|- todo-list-item-button.vue

组件name

组件名始终多个单词,且PascalCase命名

export default {
  name: 'TodoItem'
}

组件 component名

<template>
  <todo-item>Todo</todo-item>
</template>

<script>
import TodoItem from '@/components/TodoItem.vue'
export default {
  components: {
    TodoItem
  }
}
</script>

组件Props

1. 组件Props 命名

在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板中应该始终使用 kebab-case

<!-- 命名时 -->
<script>
props: {
  greetingText: String
}
</script>

<!-- 使用时 -->
<welcome-message greeting-text="hi"></welcome-message>

2. 组件Props 顺序

标签的 Props 应该有统一的顺序,依次为指令、属性和事件。

<my-component
  v-if="if"
  v-show="show"
  v-model="value"
  ref="ref"
  :key="key"
  :text="text"
  @input="onInput"
  @change="onChange"
/>

3. 组件Props 换行

超过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 () {
      // ...
    }
  }
}

method 命名规范

附: 函数方法常用的动词

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 聚集
Meqn commented 4 years ago

路由动态过渡

<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>
Meqn commented 4 years ago

组件中注册动态vuex模块

参考:

// 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')
    }
  }
}