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;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當前啟用選單的 indexstring
程式碼如下:
URL:http://localhost:8080/#/PagesNewsList/4dd8136dec5c48bcb223e9ef1fa5714f?languageCode=zh-CN&companyCode=0000let pathss = this.$route.path.split('/')
let pathss = this.$route.path.split('/') //擷取路由 data () { return { activeIndex: '/' + pathss[1] //將路由中紅色的地方設定為對應導航高亮。不可忘記‘/’,注意下標越界。 } }
6.如何實現單頁面的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官網的推薦資源中,基本能找到我們想要的資源
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 已經 相容 [email protected]
結尾
vue現在已經相當成熟,能做的事情還有很多,大家在使用過程中如果有什麼問題,歡迎交流,一起學習,一起進步。
年前就寫好了。想著過年大家都沒心思看,就拖到現在。
程式碼是敲不玩的,這輩子都不可能敲完了,只能不斷學習。哈哈