Vue 大型 SPA 项目的最佳实践 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
1340641314
V2EX    分享创造

Vue 大型 SPA 项目的最佳实践

  •  2
     
  •   134064114
    lzxb 2017-03-14 00:28:06 +08:00 10299 次点击
    这是一个创建于 3164 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    从去年 10 月份之后 Vue 2.0 发布了正式版,便将 React 全线转到了 Vue 上开发,陆陆续续开发了四五个项目,多多少少积累了一些心得,现在拿出来和大家分享一下和探讨一下。本人英语水平太 low ,如有错误,还望指正。

    现代前端的标配

    这两年前端发展迅速,日新月异,各种框架层出不穷,这是一个坏时代,也是一个最好的时代,有幸的是能够身处在这个时代去亲眼见证它、实践它。

    • 前端框架: Vue 、 React 、 Angular
    • 打包工具: Webpack 、 Gulp 、 Rollup
    • 语法效验: Eslint
    • css 预处理器: Less 、 Sass 、 PostCSS
    • 语法编译器: Babel 、 TypeScript ...... 一个 web 技术新时代的来临,如滚滚洪流般推动着历史的发展。

    多项目统一的打包配置

    Vue 官方虽然提供了 vue-cli 的脚手架,供我们得以快速开发,但是如果有多个项目,每个项目都生成一套打包配置,很容易造成各个项目都进行一些定制,进而造成项目之间的一些偏离,然而这些都不是我们想要的,所以有必要单独提取出来一套内部的打包配置,创建一个单独的 git 包,然后让其他项目依赖这个 git 包即可。

    1

    Vuex 应该如何使用?

    很抱歉,在我的项目中, Vuex 仅仅是用来存储用户信息等一些全局通用的数据,我不建议将每一个页面的数据存储到 Store 中,那样会导致程序极其的复杂,让我每新增一个页面,都感觉到倍增压力。

    统一 Mixin 处理页面数据请求

    在 SPA 应用中,最离不开的就是如何方便快捷的获取页面的数据,统一处理路由的变化去更新数据,为页面进行数据缓存,实现列表、详情、编辑、新增共用一个 model ,而且有的时候列表的字段不如详情的字段多,所以还要增加一个字段补全的机制。 2

     // 一个简单的例子 export default function MixinPagesGet () { const opt = { list: [] // 各种配置的参数等等 } Object.assign(opt, arguments[0]) return { list: { // 列表的 mixin 各种逻辑 }, detail: { // 详情、修改、新增的 mixin 各种逻辑 } } } 

    统一的处理 Methods 的错误

    为了避免回调地狱, Promise 简直就是一个神器,一旦遇上,便恨初见晚,不管是 Fetch 还是第三方的请求模块,都普遍支持了 Promise ,我们可以使用 vue-methods-promise 模块对各种错误进行统一处理

    更好的 Vue 组件开发规范

    在 JS 中, object 对象的 key 值是没有顺序之分的,但是人的阅读顺序是有顺序的,按照钩子的执行顺序来书写可以让别人更好的读懂你的代码,如果不是钩子则放到最后。如:

    export default { mixins: [], data () { return {} }, mounted () { }, destroyed () { }, watch: { }, methods: { } } 

    如何打一个标准包

    在日常开发中,我们有开发环境、测试环境、正式环境等等,我们需要打出一个标准包,让运维进行配置不同环境的。 我们可以在入口的 html 文件中设置

     <% if (process.env.NODE_ENV == 'production') { %> <script src="<%=webpack.publicPath %>configs.js?v=<%=new Date().getTime()%>"></script> <% } %> 

    在 config 的 JS 中设置

     let cOnfigs= {} if (process.env.NODE_ENV === 'production') { cOnfigs= window.__configs // 在 config.js 中设置的 } export default configs 
    25 条回复    2017-06-12 08:21:12 +08:00
    loading
        1
    loading  
       2017-03-14 07:44:50 +08:00 via Android
    还在看官方文档,看完熟悉后再看您这个。
    taowen
        2
    taowen  
       2017-03-14 08:55:11 +08:00
    更关心你为啥要弃坑 react
    wensonsmith
        3
    wensonsmith  
       2017-03-14 09:13:35 +08:00
    感谢! 正在准备构建一个大型应用,学习学习
    1340641314
        4
    1340641314  
    OP
       2017-03-14 09:15:32 +08:00
    @taowen 因为 React 只有我自己会, vue 可以推荐同事在页面中先直接引入使用, React 就不行了,所以后来 vue2.0 的时候直接就上了,这是有铺垫基础的。
    1340641314
        5
    1340641314  
    OP
       2017-03-14 09:18:37 +08:00
    @wensonsmith 写得比较匆忙,很多具体的细节没有写到,就好比统一处理页面请求数据的 mixin 这一块,其实还可以使用数据库进行存储数据,这样用户刷新页面也能快速渲染,因为我公司内部用的,都是针对公司的需求定制化开发,对 api 的规范要求比较严格。
    1340641314
        6
    1340641314  
    OP
       2017-03-14 09:18:44 +08:00
    @loading 666
    1990andy
        7
    1990andy  
       2017-03-14 09:20:28 +08:00 via iPhone
    从掘金上复制粘贴有意思吗?
    https://gold.xitu.io/entry/58c6c6d32f301e006bcc1260
    flybears
        8
    flybears  
       2017-03-14 09:23:37 +08:00
    @1990andy 你没发现头像是一样的?
    Lucius
        9
    Lucius  
       2017-03-14 09:56:00 +08:00
    @1990andy #7
    @flybears #8

    哈哈,确实是一样的头像。
    popo233
        10
    popo233  
       2017-03-14 10:22:42 +08:00
    @1990andy 说你什么好
    weeai
        11
    weeai  
       2017-03-14 10:25:56 +08:00
    不错,非常棒
    elvba
        12
    elvba  
       2017-03-14 10:42:37 +08:00
    "实现列表、详情、编辑、新增共用一个 model"
    这个不错,学到了,谢谢分享!!
    待会儿就去实践下
    elvba
        13
    elvba  
       2017-03-14 10:46:56 +08:00
    @1340641314
    "就好比统一处理页面请求数据的 mixin 这一块,其实还可以使用数据库进行存储数据"
    数据库是指?没太明白,是指浏览器的本地存储么?
    1340641314
        14
    1340641314  
    OP
       2017-03-14 10:55:23 +08:00
    @elvba 是的。这些只是更高级的特性,除此之外还可以增加指令,存储当前页面用户查看的滚动条位置,等用户从详情返回回来之后,能还原到指定的位置。这一切都需要一个统一的 mixin 来处理这些行为,其他人就可以专心负责用户行为上的开发,这一块比较复杂,有时间单独拿出来分享
    tedd
        15
    tedd  
       2017-03-14 10:55:39 +08:00
    感谢分享,我才接触 vue ,写了个购物车试了下手,直接上的 2.0 ,虽然 app 很小,但也硬上了 vuex ,之前都没有用过单项数据流,所以想尝尝鲜,用了后感觉很不错,所有数据变动的操作都集中在一个地方,貌似这是双向绑定后又一个非常值得借鉴的模式。但由于没有大型项目实际使用的经验,现阶段的理解也很浅薄,很想听听 lz 具体说说 “不建议将每一个页面的数据存储到 Store 中,那样会导致程序极其的复杂”。我的理解是 Store 也可以根据模块分拆开来,这样 componenent 对应个字的 store , map 其中的方法即可,这样也会增加程序复杂度吗?如果不用的话那用什么呢?
    1340641314
        16
    1340641314  
    OP
       2017-03-14 10:58:37 +08:00
    @tedd 上面已经提到了啊,专门写一个 mixin 来负责管理页面的数据虽然无法想 vuex 那样可以追踪用户的行为,但是你应该保存这个 mixin 应该是可靠的。
    strwei
        17
    strwei  
       2017-03-14 12:58:08 +08:00
    贝爷现在在哪上班
    meathill
        18
    meathill  
       2017-03-14 15:29:16 +08:00
    我的经验,列表读取的时候可以直接返回全部数据,通过模板控制,有些不显示就可以。这样在编辑和详情的时候,可以少取一次。

    Vuex 要求所有的修改通过 `mutation` 进行,会影响表单元素使用 `v-model` 进行双向数据绑定,不知道楼主怎么处理的?我目前试过两个做法, 1. 按照 Vuex 文档对每个属性写 getter/setter (很麻烦); 2. 增加一个中间对象,操作针对中间对象,在关闭弹窗 /切换路由的时候再一次性 `commit()`。目前我比较倾向后者。
    1340641314
        19
    1340641314  
    OP
       2017-03-14 15:32:17 +08:00
    @meathill 那样只能监听 change 事件了,我是另开一个 mixin 统一处理页面的数据,不涉及 vuex
    1340641314
        20
    1340641314  
    OP
       2017-03-14 15:32:29 +08:00
    @strwei 大神带我飞
    zhuangtongfa
        21
    zhuangtongfa  
       2017-03-17 14:30:33 +08:00
    @meathill
    监听 chage 事件,然后加上 debounce
    meathill
        22
    meathill  
       2017-03-17 15:06:51 +08:00
    @zhuangtongfa 这个跟 debounce 没有关系
    zhuangtongfa
        23
    zhuangtongfa  
       2017-03-17 15:58:04 +08:00
    @meathill 如果监听了 change 事件,不做处理持续发 mutation 太耗资源
    meathill
        24
    meathill  
       2017-03-17 16:05:06 +08:00
    @zhuangtongfa 这里的问题不是持续发 mutation ……是 Vuex 严格模式禁止直接修改对象,使得表单里的双向数据绑定失效,需要多写很多代码,损失了使用 Vue 带来的好处。所以我在想有没有什么好办法可以解决。
    1340641314
        25
    1340641314  
    OP
       2017-06-12 08:21:12 +08:00
    @meathill 最近搞了一个 vuet 出来,专门管理 Vue.js 应用程序的状态 https://github.com/medevicex/vuet
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3034 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 12:48 PVG 20:48 LAX 04:48 JFK 07:48
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86