• vue项目中遇到的那些事。


    前言

      有好几天没更新文章了。这段实际忙着做了一个vue的项目,从 19 天前开始,到今天刚好 20 天,独立完成。

      做vue项目做这个项目一方面能为工作做一些准备,一方面也精进一下技术。

      技术栈:vue2 + vuex + vue-router + webpack + ES6/7 + element-ui + vue-baidu-map + i18n + vue-awesome-swiper

      做项目时总是有一些思考和踩过的坑,对以后有一定的帮助,今天就来写写做vue项目遇到的那些事。

      假如你正准备做项目或正在做项目一定看看,说不定对你有所帮助。

    正文

     照例放上一些项目中用到的权威的官网

        vue 官方api:https://cn.vuejs.org/

        vue资源精选:http://vue.awesometiny.com/

        vue GitHub地址:https://github.com/vuejs/vue

        element-ui 官方中文api:http://element-cn.eleme.io/#/zh-CN/component/dropdown

        vue-awesome-swiper GitHub地址: https://surmon-china.github.io/vue-awesome-swiper/

      

    1.阅读vue的风格指南再开始你的项目(最重要)

      

    2.vue项目中data可以视为一个函数

    <script>
    export default {
      data () {
        // 可以在这里写很多的前置数据操作
        return {}
      }
    }
    </script>

    例如:

    <script>
    export default {
      data () {
        // 可以在这里写很多的前置数据操作
      // 不在首页时隐藏切换语言
      let showLanguageList
      if (
        this.$route.path === '/Home' ||
        this.$route.path === '/' ||
       ) {
        showLanguageList = true
       } else {
        showLanguageList = false
      }
        return {
       
    showLanguageList: showLanguageList
      }
      }
    }
    </script>

    3.路由带参

    路由带参:点击查看官网说明

    • 我们可以在路由切换时绑定参数

    在App.vue文件中监听路由绑定参数

    watch: {
        $route (to, from) {
          // 在路由上绑定语言和公司编号
          this.$router.replace({
            path: this.$router.path,
            query: {
              languageCode: '中文',
              companyCode: '阿里巴巴'
            }
          })
        }
      }
    • 函数query传参可以和路由绑定id一起使用

    路由绑定ID:

    const User = {
      template: '<div>User {{ $route.params.id }}</div>'
    }
    const router = new VueRouter({
      routes: [
        { path: '/user/:id', component: User }
      ]
    })

    效果:

      

     

    4.解决整个项目的数据刷新问题

    需求:在项目中经常会用到点击某个按钮或者更新某个参数时,整个项目的后台数据都从新请求一遍或者刷新整个页面。

    • 类似F5刷新

    this.$router.go(0);
    location.reload() 
    //这两种方式都相当于f5刷新,页面会有卡顿,白屏的情况,用户体验极差
    • 通过v-if的显示,消失,刷新数据

      适用于整个项目的数据刷新,当然也可以用于刷新部分页面

     页面刷新相对流畅,比较推荐的一种方法

     在App.vue中:

    <template>
      <div id="app">
        <router-view v-if="isRouterAlive" />
      </div>
    </template>
    
    <script>
    export default {
      name: 'App',
      provide () {
        return {
          reload: this.reload
        }
      },
      data () {
        return {
          isRouterAlive: true
        }
      },
      methods: {
        reload () {
          this.isRouterAlive = false
          this.$nextTick(function () {
            this.isRouterAlive = true
          })
        }
      }
    }
    </script>
    <style>
    </style>

    在子组件中,当我们需要刷新数据时:

    <template>
      <div @click="onSubmit_name"></div>
    </template>
    
    <script>
    export default {
      data () {
        return {}
      },
      inject: ['reload'], //引入方法
      methods: {
      onSubmit_name() {this.reload()} //需要刷新数据的时候调用reload方法
    }
    </script>
    <style>
    </style>
    • 利用路由的replace方法

      这种方式是进入一个空白页,在空白页里面跳转回原来的页面,这种方式页面刷新相对流畅

    // 需要刷新数据的页面,
    refresh () {
      this.$router.replace({
        path: '/refresh',
        query: {
          t: Date.now() //携带必要的路由参数
        }
      })
    }
    
    // refresh.vue页面中里有路由钩子,直接返回前一个页面
    <script>
    export default {
      beforeRouteEnter(to, from, next) {
        next(vm => {
          vm.$router.replace(from.path)
        })
      }
    }
    </script>

     

    5.element-ui导航栏与路由

    • 激活导航跳转对应路由

    在element-ui的导航中,官方让我们能和vue的router无缝对接,实现绑定路由,同样可以根据路由实现对应导航栏高亮。

    router    是否使用 vue-router 的模式,启用该模式会在激活导航时以 index 作为 path 进行路由跳转    boolean    —    false

    请看图中标红的位置,添加router以后,每次激活导航时以 index 作为 path 进行路由跳转

    <el-menu router :default-active="activeIndex" class="el-menu-vertical-demo hidden-sm-and-up" mode="vertical" :collapse="isCollapse" style="height:62px;float:right;100%;border:0;z-index:100"
                background-color="#222" text-color="#fff" active-text-color="#e42828">
                <el-submenu index="1">
                  <template slot="title">
                    <i class="el-icon-menu"></i>
                    <span slot="title">{{$t('home.home')}}</span>
                  </template>
                  <el-menu-item-group>
                    <el-menu-item index="/Pages">{{$t('home.home')}}</el-menu-item>
                    <el-menu-item index="/PagesAbout">{{$t('home.about')}}</el-menu-item>
                    <el-menu-item index="/PagesProductList">{{$t('home.product')}}</el-menu-item>
                    <el-menu-item index="/PagesService">{{$t('home.service')}}</el-menu-item>
                    <el-menu-item index="/PagesNewsList">{{$t('home.news')}}</el-menu-item>
                    <el-menu-item index="/PagesRecruitmentList">{{$t('home.recruitment')}}</el-menu-item>
                    <el-menu-item index="/PagesContact">{{$t('home.contact')}}</el-menu-item>
                    <el-menu-item index="/PagesDownload">{{$t('home.download')}}</el-menu-item>
                  </el-menu-item-group>
                </el-submenu>
              </el-menu>
    • 根据对应路由实现对应导航高亮

    请看如下代码,重点关注红色部分

    <el-menu router :default-active="activeIndex" class="el-menu-demo hidden-xs-only" mode="horizontal" style="height:62px;float:right;100%;border:0;z-index:100"
                background-color="#222" text-color="#fff" active-text-color="#e42828">
                <el-menu-item index="/Pages">{{$t('home.home')}}</el-menu-item>
                <el-menu-item index="/PagesAbout">{{$t('home.about')}}</el-menu-item>
                <el-menu-item index="/PagesProductList">{{$t('home.product')}}</el-menu-item>
                <el-menu-item index="/PagesService">{{$t('home.service')}}</el-menu-item>
                <el-menu-item index="/PagesNewsList">{{$t('home.news')}}</el-menu-item>
                <el-menu-item index="/PagesRecruitmentList">{{$t('home.recruitment')}}</el-menu-item>
                <el-menu-item index="/PagesContact">{{$t('home.contact')}}</el-menu-item>
                <el-menu-item index="/PagesDownload">{{$t('home.download')}}</el-menu-item>
              </el-menu>

    我们可以利用vue的特性,动态的改变default-active的值来改变导航栏的高亮,当然我们也可以通过截取的方式,

    只要路由中有一部分路由和index相同则激活。

    default-active    当前激活菜单的 index    string

    代码如下:

    URL:http://localhost:8080/#/PagesNewsList/4dd8136dec5c48bcb223e9ef1fa5714f?languageCode=zh-CN&companyCode=0000    let pathss = this.$route.path.split('/')
     let pathss = this.$route.path.split('/')  //截取路由
    data () {
        return {
          activeIndex: '/' + pathss[1]   //将路由中红色的地方设置为对应导航高亮。不可忘记‘/’,注意下标越界。
        }
      }

     

    6.如何实现单页面的title设置?

    网上也有很多方法,但我这里强烈推荐一个插件,方便又实用。

    vue-wechat-title

    • 下载安装插件依赖

    npm install vue-wechat-title --save
    • 在main.js中引入插件

    import VueWechatTitle from 'vue-wechat-title'
    Vue.use(VueWechatTitle)
    • 路由定义(只截取一部分)

    // ...
    const routes = [
      {
        name: 'Home',
        path: '/home',
        meta: {
          title: '首页'
        },
        component: require('../views/Home.vue')
      },
      {
        name: 'Order',
        path: '/order',
        meta: {
          title: '订单'
        },
        component: require('../views/Order.vue')
      },
      {
        name: 'UCenter',
        path: '/ucenter',
        meta: {
          title: '用户中心'
        },
        component: require('../views/UCenter.vue')
      }
    ]
    // ...
    • App.vue 建议全局只使用一次该指令 标题可用vuex或者router中定义 不要多处使用!!
    <!-- 任意元素中加 v-wechat-title 指令 建议将标题放在 route 对应meta对象的定义中 -->
    <div v-wechat-title="$route.meta.title"></div>
    <!--or-->
    <router-view v-if="isRouterAlive" v-wechat-title='$route.meta.title' />

     

    7.路由加载方式

      路由都有两种加载方式。

    •   一种是懒加载

      只在你点击或者访问的时候加载。建议用于不经常访问的路由。

      路由配置如下:  

    {
          path: '/Home',
          name: 'Home',
          component: () => import('./views/Home.vue'),
          meta: {
            title: '首页'
          }
        }
    •   一种是普通加载

      在项目启动时就渲染好静态页面,建议用于经常访问的路由,增加效率以及提升体验。

    import PagesHome from './pages/home/Home.vue'
    {
        path: '/Pages',
        name: '/Pages',
        component: PagesHome,
        meta: {
          title: '首页'
        }
      }

     

    8.默认路由以及404页面

      直接在router.js页面中填入下面代码 

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

    9.数据持久化

      做vue项目时,为了防止f5以后数据重置,我们想到了数据持久化

    • 巧用vue-cookie插件

      传送门:https://www.npmjs.com/package/vue-cookie

      npm方式安装

      npm install vue-cookie --save

      在main.js/app.js中引用

      

    // Require dependencies
    var Vue = require('vue');
    var VueCookie = require('vue-cookie');
    // Tell Vue to use the plugin
    Vue.use(VueCookie);

    示例:

    // From some method in one of your Vue components
    this.$cookie.set('test', 'Hello world!', 1);
    // This will set a cookie with the name 'test' and the value 'Hello world!' that expires in one day
     
    // To get the value of a cookie use
    this.$cookie.get('test');
     
    // To delete a cookie use
    this.$cookie.delete('test');

    高级示例:   

    // Setting the cookie Domain
    this.$cookie.set('test', 'Random value', {expires: 1, domain: 'localhost'});
     
    // As this cookie is set with a domain then if you wish to delete it you have to provide the domain when calling delete
    this.$cookie.delete('test', {domain: 'localhost'});
     
    // Customizing expires
    var date = new Date;
    date.setDate(date.getDate() + 21);
     
    this.$cookie.set('dateObject', 'A date object', { expires: date });
    this.$cookie.set('dateString', 'A parsable date string', { expires: date.toGMTString() });
    this.$cookie.set('integer', 'Seven days later', { expires: 7 });
    this.$cookie.set('stringSuffixY', 'One year later', { expires: '1Y' });
    this.$cookie.set('stringSuffixM', 'One month later', { expires: '1M' });
    this.$cookie.set('stringSuffixD', 'One day later', { expires: '1D' });
    this.$cookie.set('stringSuffixh', 'One hour later', { expires: '1h' });
    this.$cookie.set('stringSuffixm', 'Ten minutes later', { expires: '10m' });
    this.$cookie.set('stringSuffixs', 'Thirty seconds later', { expires: '30s' });

    (我们也可以在vuex的store中使用)

     

    • 巧用vuex-persistedstate插件

    前提:已经安装并使用vuex。

      

    安装vuex-persistedstate

    npm install vuex-persistedstate

    在vuex的store文件的index.js中引用

    import Vue from 'vue'
    import Vuex from 'vuex'
    import createPersistedState from 'vuex-persistedstate'
    import state from './state'
    import mutations from './mutations'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
    state,
    mutations,
    plugins: [createPersistedState()]
    })

     10.vue项目封装时间格式

    (一)函数封装(将该函数封装成一个文件,或者加入自己项目的函数库)

    export function formatDate (date, fmt) {
      if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
      }
      let o = {
        'M+': date.getMonth() + 1,
        'd+': date.getDate(),
        'h+': date.getHours(),
        'm+': date.getMinutes(),
        's+': date.getSeconds()
      }
      for (let k in o) {
        if (new RegExp(`(${k})`).test(fmt)) {
          let str = o[k] + ''
          fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str))
        }
      }
      return fmt
    };
    
    function padLeftZero (str) {
      return ('00' + str).substr(str.length)
    }

    (二)文件引入(注意:由于是函数,故名字要和函数的名字一致)

    import { formatDate } from '../../unit/index.js'

    (三)添加到过滤器中

    filters: {
        formatDate (time) {
          var date = new Date(time)
          return formatDate(date, 'yyyy-MM-dd')
        }
      },


    (四)使用场景一: 在HTML中使用

    <div class="news-img-text-div">{{job.create_datetime| formatDate}}</div>

    (五)使用场景二: 在提交时候使用

    let nowDate = formatDate(new Date(), 'yyyy-MM-dd hh:mm')

    11.vue官网的推荐资源中,基本能找到我们想要的资源

      

    1. 推荐一个地图插件:vue-baidu-map(百度地图)vue-google-maps(谷歌地图)

     

    文档:https://dafrok.github.io/vue-baidu-map/

      安装

    npm i --save vue-baidu-map

     在main.js中引入

      

    // 引入百度地图插件
    import BaiduMap from 'vue-baidu-map'
    Vue.use(BaiduMap, {
      // ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */
      ak: 'Zgbme5XaLreej7Oribs9yk317sOFG3OP'
    })

    使用示例:

               
               <baidu-map class="map" :center="center" :zoom="zoom" @ready="handler">
                     <bm-geolocation anchor="BMAP_ANCHOR_BOTTOM_RIGHT" :showAddressBar="true" :autoLocation="true"></bm-geolocation>
                     <bm-marker :position="{lng: this.$store.state.companyObject.longitude, lat: this.$store.state.companyObject.latitude}" :dragging="false"animation="BMAP_ANIMATION_BOUNCE">
                         <bm-label :content="this.$store.state.companyObject.transname" :labelStyle="{color: 'red', fontSize : '14px'}" :offset="{ -35, height: 25}" />
                     </bm-marker>
                     <bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
                     <bm-map-type :map-types="['BMAP_NORMAL_MAP', 'BMAP_HYBRID_MAP']" anchor="BMAP_ANCHOR_TOP_LEFT"></bm-map-type>
                </baidu-map>
    export default {
      name: 'Contact',
      components: {
        ContactUs
      },
      data () {
        return {
          center: {
            lng: '26.515515',
            lat:'103.54548841'
          },
          zoom: 15
        }
      },
      methods: {
        handler ({ BMap, map }) {
           this.center.lng ='26.515515'
        this.center.lat = '103.54548841'

        this.zoom = 15 } } }

    2. 推荐一个vue轮播插件:vue-awesome-swiper

    安装

      

    npm install vue-awesome-swiper --save

    引用:

      

    import Vue from 'vue'
    import VueAwesomeSwiper from 'vue-awesome-swiper'
    
    // require styles
    import 'swiper/dist/css/swiper.css'
    
    Vue.use(VueAwesomeSwiper, /* { default global options } */)

    示例:(每个都是vue项目的示例,在右上角都有对应代码的链接)

      https://surmon-china.github.io/vue-awesome-swiper/

    3.推荐一个vue国际化插件:vue-i18n

    文档:http://kazupon.github.io/vue-i18n/

    使用方法请参考文档,非常详尽。element-ui已经兼容 vue-i18n@5.x

    结尾

      vue现在已经相当成熟,能做的事情还有很多,大家在使用过程中如果有什么问题,欢迎交流,一起学习,一起进步。  

      年前就写好了。想着过年大家都没心思看,就拖到现在。

      代码是敲不玩的,这辈子都不可能敲完了,只能不断学习。哈哈

     

    欢迎大家关注公众号,不定时干货,只做有价值的输出

     作者:Dawnzhang 
    出处:https://www.cnblogs.com/clwydjgs/p/10291136.html 
    版权:本文版权归作者
    转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;

    往期文章:

      Visual Studio Code(VS code)你们都在用吗?或许你们需要看一下这篇博文

      你们都在用IntelliJ IDEA吗?或许你们需要看一下这篇博文

      你真的了解博客园的目录么。。

      博客园博客排版(js样式实例)

  • 相关阅读:
    git stash 一个场景 mark
    sendBeacon 使用
    【踩坑笔记】layui之单选和复选框不显示
    wordpress后台管理超时没反应:load-scripts.php载入缓慢出错
    MySQL_Sql_打怪升级_进阶篇_测试: SQL随机生成测试数据
    MySQL_Sql_打怪升级_进阶篇_测试: 游标应用
    MySQL8.0新特性_01_JSON数据格式的支持
    MySQL_Sql_打怪升级_进阶篇_进阶19: 函数
    MySQL_Sql_打怪升级_进阶篇_进阶18: 存储过程
    MySQL_Sql_打怪升级_进阶篇_进阶17: 变量
  • 原文地址:https://www.cnblogs.com/clwydjgs/p/10291136.html
Copyright © 2020-2023  润新知