为了账号安全,请及时绑定邮箱和手机立即绑定

vue项目技术小记

标签:
Vue.js

最近做的项目快要结尾了,本项目用前后端分离的,然后前端是用vue开发的,为什么选vue呢?一来公司要求效率要高些的,那就应该用到三大流行的框架之一,然后项目的内容不太复杂的,觉得用vue更合适的。二来正好应该要“炒熟”vue了哈。其中陷入了不少坑,一个一个爬过来的,总结下入坑的原因,另外会给出官方文档的对应内容,以便加深理解的。如有不足之处,请提出来哈~

  • 异步加载组件

    const Index=()=>import('@/page/Index');const Home=()=>import('@/page/Home');const router=new Router({    routes:[
        {        path:'/index',        component:Index
        },
        {        path:'/home',        component:Home
        }
        ]
    })

    然后你会发现js被分开的,这就是所谓的异步加载~

    • 我们都知道vue一般都是单页面的,也就意味着一开始就要加载全部的组件,这太不友好的,加载时间会慢些。这时候我们就用到异步组件~

  • 页面后退时,保持之前的状态,不刷新

    <keep-alive><router-view v-if="$route.meta.keepAlive"></router-view></keep-alive><router-view v-if="!$route.meta.keepAlive"/>
    const router = new Router({
      routes: [
        {
          path: '/index',
          components:Index,
          meta:{
            keepAlive:false
          }
        },
        {
            path:'/goods',
            component:Goods,
            meta:{
              keepAlive:true
            }
        },
    }

    用meta中的keepAlive来判断需不需要缓存,keep-alive就是保存缓存的组件。

    • 在router.js中

    • 在app.vue文件中

  • 在相同路由的情况下,再次点击导航栏上的本路由,再次刷新

    在vue中,路由地址相同的情况下,是不会再次刷新的,即使点击本路由的导航文字上。一开始我没想到解决的方案,后来寻求大佬商量,大佬说可以用事件传递的。然后他告诉我一句话的,

    vue.js一定不会阻碍传统方法实现的。

    这话说得我惭愧,我意识到我太依赖vue.js的框架,没拓展思维的。再次感谢大佬的点拔~

    <router-view :isFresh="isFresh" @tempBtn="tempBtn"/>//datadata(){    return {
            isFresh:false,
        }
    }//事件函数tempbtn(){    this.isFresh=false;
    }
    watch:{
        isFresh(){        //console.log('ShopisFresh:'+this.isFresh);
            if(this.isFresh){            Object.assign(this.$data,this.$options.data());            this.fetchData();
            }
        }
    },//然后加载完后,还要绑定事件,传递到主路由的tempbtn事件this.$emit('tempbtn');

    嗯,在子路由上监听到isFresh为true,表示要刷新的,Object.assign是利用data的初始化数据覆盖,然后重新加载数据。

    • Index.vue

    • 对,是可以用事件传递来实现的。在主路由上绑定isFresh,判断需不需要刷新子路由,然后在子路由上绑定事件,传递到主路由的事件。主路由监听到事件的,就把isFresh变为false,以防下面还会需要到。不设置为false,下面的就不会刷新。看代码如下:

    • App.vue

  • checkbox整体点击

    UI设计师要求能点击checkbox的整体,包括checkbox后面的文字,不是只能点击checkbox的框,这可把我为难了,然后艰难的爬出坑了。

    <div class="group_item" @click="selfChecked = !selfChecked">
        <input type="checkbox" v-bind:checked="selfChecked">
        <label>点我呀</label>    data(){        return {
                tempChecked:null
            }
        },
        props:['checked'],
        watch:{        checked(){
                this.tmpChecked=this.checked
            }
        },
        computed: {
            selfChecked: {
                get: function(val){                return this.tmpChecked;
                },            set: function(newVal){
                    this.tmpChecked = newVal
                    this.$emit('input', newVal)
                }
            }
        },
    </div>

    然后在父组件上用v-model即可。用selfChecked来判断是不是要点击,至于为什么要watch,是判断checked为真还是假,比如说在父组件上,提交后,表单要清空的,这时候要监听到checked为假的,然后传递到selfChecked的值。这样就能清空checkbox。

  • setInterval的问题

    用了setInterval之后,切换路由的时候发现还在计时,不得了,真的会影响性能唉,就吓的赶紧啃官方文档,找到了~

    beforeDestroy(){
        clearInterval(this.interId);
    }

    beforeDestroy是毁路由之前的函数,就是说毁路由之前就清除setInterval

    • 参考vue的生命周期

  • 在v-for循环中进行v-model数据绑定

    <div v-for="(item,index) in list">
        <textarea type="text" v-model="list[index]['content']"></textarea></div>

下面说说和vue没关系的问题

  • 上线时去掉console

    我们一般都会用console来打印,以便检查的,万一console写多了,上线时总不能打印出console吧,要注释掉,但太费时间吧,这时候webpack神器上场(本人用webpack3)

    new UglifyJsPlugin({  uglifyOptions: {
        compress: {
          warnings: false,
          drop_debugger: true,
          drop_console: true
        }
      },  sourceMap: config.build.productionSourceMap,  parallel: true}),

    这prod是生产环境的,然后drop_console为true,是去掉console

    • 在webpack.prod.config.js中

  • 兼容ie的问题

    部署到生产环境后,测试ie11时发现空白屏的,我慌了,不是说可以兼容到ie9吗?还是说没配置好的,然后google查,ie还没支持js新的api,比如promise,所以需要babel-polyfill来转换的。真是蛋疼的ie,还能怎么办呢?当然是加babel-polyfill插件的。

    npm install babel-polyfill --save//然后在webpack.base.config.js中引用这插件module.exports=require('babel-polyfill');module.export={
        ...
        entry:{
            app:['babel-polyfill','./src/main.js']
        }
    }
  • 打包第三方库

    打包时把第三方库合并成vendor.js,但是这个vendor.js有hash,这就意味着每次打包时vendor.js的hash会变化的,然后在浏览器会重新加载。vendor.js的代码本来就很少被改变的,重新加载就影响加载时间的。从目前搜索的解决方案,比较好的方案有两种:
    1、 第一种用dll来打包的,webpoack自带的

    const webpack=require('webpack')const path=require('path')module.export={    entry:{        vendors:['vue.js','axios','vue-router','vuex','vue/dist/vue.esm.js']   //加入要打包的第三方库
        },    output:{        filename:'[name].dll.js',  //输入的文件名
            path:'path.join(__direname,'../static')',   //输入的路径
            library:'[name]'
        },    plugin:[  //为了和第三方库的dll.js对应,build时不会把这个打包进去,就是说能减少build构建的时间
            new webpack.DllPlugin({            path:path.join(__direname,'../','[name]-mainfest.json'),  //输入的mainfest文件的路径
                name:'[name]'
            })
        ]
    }
    //在package.json添加一行"dll":"webpack --config build/webpack.dll.config.js"

    然后npm run dll,就生成vendor-mainfest.json

    //添加一行const mainfest=require('../vendors-mainfest.json')  ////在module.exports添加配置module.exports={
        ...
        plugins:[        new webpack.DllReferencePlugin({
                mainfest
            })
        ],
        ...
    }

    然后把CommonsChunkPlugin的这块注释掉,不然要重复打包。

    <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./static/vendors.dll.js"></script>
    2、 第二种方案就是用bootcdn
    • 最后在index.html加上一行

    • 然后还要在webpack.base.conf.js配置,改变构建的配置

    • 然后命令生成vendor-mainfest.json

    • 首先在build里新建一个文件,命名为webpack-dll.config.js



作者:Empty莫晓邪
链接:https://www.jianshu.com/p/454600e7aba9


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消