Vue 2.x 项目开发小技巧总结(持续更新中!!!)

2018-12-01  本文已影响20人  HelloJames

1. 工程目录规划

└─src
    ├─services           # 服务相关
    │    │
    │    ├─ url.js         # 请求地址
    │    │
    │    └─ map.js      # 字段属性名映射(可能不需要)
    |    |
    │    ├─ handler.js   # 数据处理
    │    │
    │    └─ index.js    
    │
    ├─router           # 路由
    │    │
    │    ├─ index.js         # 路由入口
    │    │
    │    ├─ manager.js         # 管理后台模块相关路由
    │    │
    │    └─ user.js      # 用户模块相关路由
    │
    ├─components       # 公用组件
    |      ├─mixins       # 混合
    |      │    │
    |      │    └─ CardMinix.vue # 卡片混合
    │      │
    │      └─ Common1.vue   # 通用组件1
    │      │
    │      └─ Common2.vue   # 通用组件2
    │
    ├─views       # 视图(业务组件)
    |      ├─manager      # 后台管理视图
    |      │    │
    |      │    └─ Index.vue # 首页
    |      │    │
    |      │    └─ Export.vue # 数据查询/导出
    |      ├─user      # 用户信息视图
    |      │    │
    |      │    └─ Profile.vue # 个人简介
    |      │    │
    |      │    └─ Detail.vue # 个人详情
    ├─store       # 状态数据
    |      ├─manager      # 后台管理state
    |      │    │
    |      │    └─ types.js
    |      │    │
    |      │    └─ action.js
    |      │    │
    |      │    └─ mutation.js
    |      │    │
    |      │    └─ state.js
    |      │    │
    |      │    └─ index.js
    |      ├─user      # 用户信息state
    |      │    │
    |      │    └─ types.js
    |      │    │
    |      │    └─ action.js
    |      │    │
    |      │    └─ mutation.js
    |      │    │
    |      │    └─ state.js
    |      │    │
    |      │    └─ index.js
    │
    ├─directives       # 自定义指令
    │
    ├─filters          # 自定义过滤器
    │
    ├─plugins          # 自定义插件
    │
    ├─config           # 放置一些配置文件
    │
    ├─utils             # 放置一些工具函数
    │
    ├─asserts           # 静态资源
    |   │
    |   ├─less           # 放置less
    |   │    │
    |   │    ├─ common.less # 通用less
    |   │    │
    |   │    └─ reset.less  # 页面初始化less
    |   │
    |   ├─fonts            # 放置iconfont字体
    |   ├─imgs            # 放置图片
    ├─App.vue             # 入口组件
    ├─main.js             # 启动配置

其中,

2. 文件引用路径别名设置

有时候项目文件过多,可能经常出现类似 "../../../static/data/xx.json" 这样的引用,写起来很麻烦而且经常容易出错(当然代码编译器能够提示就无所谓了),为了简化路径,我们可以在 build/webpack.base.conf.js 中去配置别名


image.png

这里是通过调用 resolve 方法来达到简化路径的目的,比如可以直接用@来取代src,也可以直接写 "api/xx.js",而不用一层一层的去找

3. 递归组件

在Vue中组件可以在模板内部递归调用自己,需要给组件设置name值,需要注意的是:必须限定条件,不能无限递归,否则会内存溢出(Error in nextTick: "RangeError: Maximum call stack size exceeded")。

场景: 在构建目录树时, 如果用一个组件来完成, 可能会涉及到复杂的数据处理和计算, 然后再渲染成一个目录树结构.
在此场景中, 可以写一个递归函数, 根据数据生成一个目录树节点, 然后渲染出来.
当然, 也可以考虑下使用递归组件来完成这样的工作.如:

// 父组件
<items  :model='model' v-for='model in data'></items>

官方文档里面写的递归组件强调了使用name属性,

// Items.vue
<template>
    <li>
        <div @click='toggle'>
            <i v-if='isFolder' class="fa " :class="[open?'fa-folder-open':'fa-folder']"></i>
            <!--isFolder判断是否存在子级改变图标-->
            <i v-if='!isFolder' class="fa fa-file-text"></i> {{model.data.menuName}}
        </div>
        <ul v-show="open" v-if='isFolder'>
            <items v-for='cel in model.childTreeNode' :model='cel'></items>
        </ul>
    </li>
</template>
<script type="text/javascript">
    export default {
        name: 'items',
        props: ['model'],
        components: {},
        data() {
            return {
                open: false,
                isFolder: true
            }
        },
        computed: {
            isFolder: function() {
                return this.model.childTreeNode && this.model.childTreeNode.length
            }
        },
        methods: {
            toggle: function() {
                if(this.isFolder) {
                    this.open = !this.open
                }
            },
        }
    }
</script>

4. 路由懒加载

// Vue路由文档的写法:
const app = () => import('./app.vue') // 引入组件
const router = new VueRouter({
 routes: [
 { path: '/app', component: app }
 ]
})

// 也要以这么写
const router = new VueRouter({
 routes: [
 { path: '/app', component:  () => import('./app.vue')}
 ]
})

5. 404页面

如果输入的路由不存在应该要跳转到404页面(自定义404页面)

export default new Router({
 routes: [
 {
 path: '/', // 项目启动页
 redirect:'/login' // 重定向到下方声明的路由 
 },
 {
 path: '*', // 404 页面 
 component: () => import('./notFind') 
 },
 ]
})

6. 路由拦截

场景描述:
当用户使用浏览器后退时, 提示用户保存未保存的表单。

//在路由组件中:
mounted(){
},
beforeRouteLeave (to, from, next) {
 if(userInput){
 //出现弹窗提醒保存表单,或者自动后台为其保存
 
 }else{
 next(true);//用户离开
 }

请参考vue文档全局钩子和组件钩子

7. 深度watch与watch立即触发回调

watch很多人都在用,watch中的有两个选项deep、immediate

watch: {
 obj: {
 handler(val, oldVal) {
 console.log('属性发生变化触发这个回调',val, oldVal);
 },
 deep: true // 监听这个对象中的每一个属性变化
 },
 step: { // 属性
 //watch
 handler(val, oldVal) {
 console.log("默认触发一次", val, oldVal);
 },
 immediate: true // 默认触发一次
 },
 },

8. 动态组件

9. 加载远端组件

10. 组件动态传参

11. 组件通信

更多好文:

上一篇下一篇

猜你喜欢

热点阅读