vue項目中遇到的那些事。

前言

  有好幾天沒更新文章了。這段實際忙着作了一個vue的項目,從 19 天前開始,到今天恰好 20 天,獨立完成。css

  作vue項目作這個項目一方面能爲工做作一些準備,一方面也精進一下技術。html

  技術棧:vue2 + vuex + vue-router + webpack + ES6/7 + element-ui + vue-baidu-map + i18n + vue-awesome-swipervue

  作項目時老是有一些思考和踩過的坑,對之後有必定的幫助,今天就來寫寫作vue項目遇到的那些事。webpack

  假如你正準備作項目或正在作項目必定看看,說不定對你有所幫助。git

正文

 照例放上一些項目中用到的權威的官網github

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

    vue資源精選:http://vue.awesometiny.com/vue-router

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

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

    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;width: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;width: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="{width: -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樣式實例)

相關文章
相關標籤/搜索