004--自找麻煩之 vue2.0

人的差異其實很小:一,你在猶豫,他在做,所以他比你成功機會多;二,你在找藉口,他在解決問題,所以他比你事業有成;三,你在消費,他在理財,所以他比你更富足;四,你在算計自己的利益,他在考慮對方的利益,所以他比你更加有人脈。成功沒有奇蹟,只有軌跡!

1. Vuex:用於各個組件的數據共享

2. Nuxt.js : 基於vue的服務端渲染應用框架

3. 任何一門框架的學習最好的資料就是官方文檔     

4. vue 不支持IE8以下的瀏覽器(記住)

5. 要在外面取vue實例app裏面的data要用: app.$data

6. 學習vue只需要操作數據,不會再涉及到DOM的操作

7. vue的雙向數據綁定原理(面試會問,重要,以後補充

8. vue註冊全局組件用 component ;子組件接收父組件的數據要用 props           

Vue.component("TodoItem",{
   props:['content'],
   template:"<li>{{content}}</li>"
})
<todo-item v-bind:content="item" v-for="item in list"></todo-item>

9. 子組件傳遞數據給父組件

10. 生命週期函數就是vue實例在某一個時間點會自動執行的函數

        beforeCreate(vue實例進行部分初始化之後會執行);created(完全初始化之後執行);

        beforeMount(模板結合vue實例的DOM元素掛載到頁面之前執行),mounted(頁面掛載之後 執行);

        beforeDestroy(組件被銷燬之前執行,在控制檯調用 vm.$destroy() 時這個函數就執行),destroyed(組件被完全銷燬之後執行);

        beforeUpdate(當數據發生還沒重新渲染之前執行),updated(當數據發生改變重新渲染之後執行)

11. vue指令裏面的值不再是字符串,而是js表達式

12. v-text 和 v-html有點類似,區別在於v-text="name"(和 {{name}} 的用法一模一樣)做了轉義,完整輸出內容,而v-html 可以識別html表達式

13. 計算屬性 computed(非常重要的特點:內置緩存)的寫法(寫成函數,返回這個值)   

new Vue({
  ...
  computed:{
    fullName:function(){
      return this.fname + this.lname
    }
  }
})
<div id="app">{{fullName}}</div>

14. computed 的 get (獲取值時執行)和 set(設置值時執行)

new Vue({
  ...
  computed:{
    fullName:{
       get:function(){
         return this.fname + this.lname
       },
       set:function(value){
         var arr = value.split(" ");
         this.fname = arr[0];
         this.lname = arr[1];
       }
    }
  }
})

15. div綁定某個類名用 :class="{activated: isActivated}" 取決於isActivated是true還是false

     :class="[activated]" 這樣寫activated代表一個變量,變量的內容即是一個類名

16. Vue.set()不光能修改數據,還能添加數據,彌補了Vue數組變異方法的不足; Vue.set()在methods中也可以寫成this.$set()

17. vue-cli 的使用

        npm i -g vue-cli

        vue init webpack Travel      (Travel 表示項目放在哪個文件夾下)

        基本回車操作,除了一些沒見過的選項你不想安裝就選擇no   

        cd Travel

        npm run dev     

18. vue-cli 生成的項目文件分析

           package-lock.json  package的鎖文件(幫助我們確定你安裝的第三方包的版本,保持團隊編程的統一)

           .eslintrc.js   配置了一些代碼的規範

           .eslintignore     忽略某些文件的檢測

           .editorconfig     配置了編輯器的語法       

           static目錄       圖片,json數據等靜態資源

           src目錄     整個項目的源代碼

           config目錄     項目的配置文件

    vue-cli生成的項目中, @ 符號代表 src 目錄(這是在build目錄中webpack.base.conf.js中幫我們設置好的)

19. 路由就是根據網址的不同,返回不同的內容給用戶

20.  <router-view></router-view>   顯示當前路由地址所對應的內容

21. 單頁應用通過js感知url的變化,動態刪除再渲染新的DOM結構,把組件內容掛載到頁面上,這時候路由是由前端來做的。

22. 單頁應用首屏時間慢且SEO差(搜索引擎只認識HTMl當中的內容),多頁應用首屏時間快且SEO好

23. 做移動端的頁面可以寫以下的語句防止用戶用手縮放網頁

<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">

24. reset.css 文件:對基礎樣式的修飾,保證所有瀏覽器顯示的效果基本一致

     border.css文件: 爲了解決多倍屏1像素邊框會被顯示成多元素的問題 (1像素邊框的解決方案)

     npm i fastclick -S  :   fastclick用來解決移動端click時間300毫秒點擊延遲的問題

25. iconfont 阿里巴巴矢量圖標庫: http://www.iconfont.cn/   (進入圖標管理--我的項目--新建項目圖標庫)

26. 使用stylus:  npm i stylus -s  ;   npm i stylus-loader -s

27. 只對當前組件的樣式有效 scoped

<style scoped>  
</style>

28. iconfont的使用:選擇需要圖標加入購物車,添加至項目,下載到本地,再把iconfont.css 和四個字體文件(.eot,.svg,.ttf,.woff)提取出來,將iconfont.css文件中引用字體文件的路徑改好就可以用了,

 

// icon圖標庫使用 在main.js 中引入 iconfont.css

import 'styles/iconfont.css'

@font-face {font-family: "iconfont"; //這個是iconfont.css文件,修改這裏的路徑

src: url('./iconfont/iconfont.eot?t=1527149033233'); /* IE9*/

src: url('./iconfont/iconfont.eot?t=1527149033233#iefix') format('embedded-opentype'), /* IE6-IE8 */

url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),

url('./iconfont/iconfont.ttf?t=1527149033233') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/

url('./iconfont/iconfont.svg?t=1527149033233#iconfont') format('svg'); /* iOS 4.1- */

}

例如:

<span class="iconfont">&#xe624;</span>

    &#xe624;  是一種圖標的16進制的字符標識 (可在iconfont的官網查看)

 

// icon圖標庫使用 main文件裏面要引用

import 'styles/iconfont.css'

29. 在項目的build文件夾中的webpack.base.conf.js中爲某些常見的路徑配置變量別名,例如'styles':..

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      'styles': resolve('src/assets/styles'),
    }
  }

    修改後要重啓服務器纔不會報錯

30. 使用vue-awesome-swiper 來快速構建一個輪播 (新版本有點細節bug,採用老的版本 2.6.7)  

        github網址:https://github.com/surmon-china/vue-awesome-swiper

        npm i [email protected] -s   

<template>
    <div class="wrapper">
        <swiper :options="swiperOption" v-if="showSwiper">
            <swiper-slide v-for="item of list" :key="item.id">
                <img class="swiper-img" :src="item.imgUrl" />
            </swiper-slide>
            <div class="swiper-pagination" slot="pagination"></div>
        </swiper>
    </div>
</template>
data () {
        return{
            swiperOption: {
                pagination: '.swiper-pagination',
                loop: true,
                autoplay:fasle
            }
        }
    },

:options="swiperOption"  是 這個vue-awesome-swiper 的配置項,pagination是顯示圓點,loop是循環播,autoplay是自動輪播

31. 當你要在子組件裏面定義一個data的時候,data一定要是一個函數      

32. 最好的防止網速太慢輪播圖圖片沒加載完下面的元素抖動的方案 (用vw的話兼容性差)     

.wrapper
   width: 100%
   height: 0
   overflow: hidden
   padding-bottom: 31.25%
   background-color: #eee

33. style用了scoped後樣式只對本組件生效,但是有時候又想讓某些樣式應用於其他組件,所以可以用 >>>

<style lang="stylus" scoped>
    .wrapper >>> .swiper-pagination-bullet-active
        background: #fff
</style>

34. 谷歌瀏覽器下載一個插件 Vue.js devtools 

35. 對超過div寬度的文字顯示成 ... 的CSS寫法

overflow: hidden
white-space: nowrap
text-overflow: ellipsis      //ellipsis顯示省略符號來代表被修剪的文本顯示省略符號來代表被修剪的文本

36. 提到插槽的概念,不懂,後補

37. 數據請求推薦 axios

        npm i axios -s

 

import axios from 'axios' //在需要請求的.vue文件內

axios.get('/api/index.json')
        .then(this.getHomeInfoSucc)
methods: {
        getDetailinfo () {
            axios.get('/api/detail.json?',{
                params: {
                    id: this.$route.params.id      // this.$route.params 可以取到當前路由上定義的id參數的值,發get請求帶參數就可以這樣
                }
            }).then(this.handleGetDataSucc)
        },

38. vue-cli 生成的整個項目只有static目錄裏面的內容可以被外部訪問到

39. vue-cli 生成的項目目錄中 配置config文件夾下的index.js文件中的 module.exports    

dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
      '/api':{
        target: 'http://localhost:8080',
        pathRewrite: {
          '^/api':'/static/mock/'
        }
      }
    },

看 proxyTable 配置項,按如上配置 開發環境下的時候請求路徑即使寫的是 './api' ,它也會幫我們代理到 '/staic/mock'

這個功能是 webpack-dev-server 這個工具提供的

40. 父組件給子組件傳值

<home-header :city="city"></home-header>
<script>
export default {
  name: 'HomeHeader',
  props: {
    city: String
  }
}
</script>
<div class="header-right">
   {{this.city}}
   <span class="iconfont arrow-icon"></span>
</div>

41. 頁面跳轉用   <router-link to='/city'></router-link>

42. 原生app的上下拉動頁面效果的插件(到頂部和底部還有彈性的效果) better-scroll 的使用: 

        https://github.com/ustbhuangyi/better-scroll

        npm i better-scroll -s   

<div ref="wrapper">     //要類似這種DOM結構,父div裏面一個子div,子div裏面再寫頁面的東西
  <ul class="content">
    <li>...</li>
    <li>...</li>
    ...
  </ul>
  <!-- you can put some other DOMs here, it won't affect the scrolling -->
</div>
import Bscroll from 'better-scroll'  
export default {
    name: 'CityList',
    mounted () {
        this.scroll = new Bscroll(this.$refs.wrapper)    //把DOM元素丟進去實例化
    }
}
</script>
this.scroll.scrollToElement(element)    //這個方法是用來將頁面滾動到某個DOM元素的區域的

43. vue2 用 ref 來獲取 DOM        

<div class="touchscroll" ref='wrapper'></div>
this.$refs.wrapper

44. 兄弟組件之間的傳值(兄傳值給父,父再傳給弟)

methods: {       //兄
        handleLetterClick (e) {
            this.$emit('change',e.target.innerText)
        }
    }
<city-list :cities="cities" :hot="hotCities" :letter="letter"></city-list>       //父
<city-alphabet :cities="cities" @change="handleLetterChange"></city-alphabet>
        handleLetterChange (letter) {    //父
            this.letter = letter
        }
props: {        //弟
        hot: Array,
        cities: Object,
        letter: String
    },
watch: {   //弟    注意這一步要在watch裏面處理這個傳過來的數據
        letter () {
            if (this.letter) {
                const element = this.$refs[this.letter][0]
                this.scroll.scrollToElement(element)
            }  
        }
    }

45. vue中html元素中不要有邏輯的部分,例如

<li class="search-item border-bottom" v-show="!list.length">沒有找到匹配數據</li>    //v-show 這裏要改在computed 裏面
 computed: {             //改成這樣
        hasNoData() {
            return !this.list.length
        }
}
<li class="search-item border-bottom" v-show="hasNoData">沒有找到匹配數據</li>    // 改成這樣

46. Vuex 數據層框架的使用: 就是類似一個倉庫,組件共用的數據存放在State裏面,外面的組件要改變這個共用數據要通過dispatch方法來調用actions的異步代碼調用commit方法來調用Mutations(轉變)的同步代碼最終mutate(變化)到state裏面的數據,外面的組件也可以直接通過Mutations來改變state裏面的數據

        整個流程: 組件調用action,action調用mutations,Mutations去改變我們的數據

        npm i vuex -s

        vue-cli生成的項目中在src目錄新建一個store文件夾/index.js文件

import Vue from 'vue'     // index文件內容
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        city: '北京'
    }
})
import store from './store'    //mian文件內容
...
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})
<div class="header-right">
        {{this.$store.state.city}}        // 任何組件使用這個store上的共用數據的方法
        <span class="iconfont arrow-icon"></span>
      </div>

        以下是改變共享數據的過程;

methods: {     //組件執行這個函數 dispatch方法去調用actions
        handerCityClick (city) {
            this.$store.dispatch('changeCity',city)
        }
    },
import Vue from 'vue'       //這是store/index文件  actions觸發Mutations最終改變state裏面的city數據
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        city: '北京'
    },
    actions: {
        changeCity (ctx, city) {
            // console.log(city)
            ctx.commit('changeCity',city)
        }
    },
    mutations: {
        changeCity (state, city) {
            state.city = city
        }
    }
})

47. 編程式導航(路由通過js代碼來實現頁面路由的跳轉了)

methods: {
        handerCityClick (city) {
            this.$store.commit('changeCity',city)
            this.$router.push('/')      // 這樣就跳轉到首頁了
        }
    },

48. localstorage的用法

export default new Vuex.Store({
    state: {
        city: localStorage.city || '北京'
    },
    mutations: {
        changeCity (state, city) {
            state.city = city
            localStorage.city = city
        }
    }
})

更健壯的兼容瀏覽器的寫法(加入try catch 處理某些瀏覽器關閉本地存儲功能代碼會報錯的問題)

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

let defaultCity = '汕頭'
try {
    if (localStorage.city) {
        defaultCity = localStorage.city
    }
} catch (e) {}

export default new Vuex.Store({
    state: {
        city: defaultCity
    },
    mutations: {
        changeCity (state, city) {
            state.city = city
            try {
                localStorage.city = city
            }catch (e) {}

        }
    }
})

        谷歌瀏覽器,右鍵檢查--選擇 Application  可以找到 local storage 

49. 高級Vuex的api用法

import { mapState } from 'vuex'
export default {
  name: 'HomeHeader',
  computed: {
    ...mapState(['city'])   // 將state中共享數據映射到本組件的city數據身上
  }
}
<div class="header-right">
     {{this.city}}     //雖然這個city是共享數據,但是映射本組件就可以直接這樣用了
</div>

50. 性能優化

<template>     // 這個是App.vue 文件
  <div id="app">
    <keep-alive exclude="Detail">      //用這個標籤在前進後退頁面的時候就不會重複發送ajax請求,會緩存第一次發送的ajax請求
      <router-view/>                   // exclude="Detail"  表示除了Detail組件不會緩存,其他都會緩存
    </keep-alive> 
  </div>
</template>
activated () {     // 重新顯示頁面比如說城市變了就要重新發送ajax請求就可以寫在這個生命週期函數 activated 裏面
    if (this.lastCity !== this.city) {
      this.lastCity = this.city
      this.getHomeInfo()
    }
  }

51. vue中的 <router-link></router-link> 類似 a 標籤,但想表示其他標籤也可以

<router-link tag='div' to="/" class="header-abs">       // 加上 tag="div" 就可以表示 div 了,同樣加上其他就可以表示其他標籤
     <div class="iconfont header-abs-back"></div>
</router-link>

52. 獲取當前頁面滾動條的縱座標位置: 

document.documentElement.scrollTop;

53. 對全局事件的解綁

    activated () {    // 頁面展示時執行
        window.addEventListener('scroll',this.handleScroll)
    },
    deactivated () {   // 頁面切換掉後執行
        window.removeEventListener('scroll',this.handleScroll)
    }

54. 遞歸組件的實現(vue中比較難的部分)(組件自己調用自己)
    

<template>
    <div>
        <div class="item" v-for="(item,index) of list" :key="index">
            <div class="item-title border-bottom">
                <span class="item-title-icon"></span>
                {{item.title}}
            </div>
            <div v-if="item.children" class="item-children">    // v-if  與 加上自己子項的類名區分
                <detail-list :list="item.children"></detail-list>   //用自己的組件名
            </div>
        </div>
    </div>
</template>
<script>
export default {
    name: 'DetailList',   //組件名
    props: {
        list: Array
    }
}

55. ajax請求要放在 mounted 這個鉤子函數裏面中請求

56. 解決切換頁面時頁面滾動到上一個頁面的位置的問題(查看官網 -- 滾動行爲)

import Vue from 'vue'        // 這是router文件夾裏面的 index.js 文件
import Router from 'vue-router'
import Home from '@/pages/home/Home'
import City from '@/pages/city/City'
import Detail from '@/pages/detail/Detail'

Vue.use(Router)

export default new Router({
  routes: [{
    path: '/',
    name: 'Home',
    component: Home
  },{
    path: '/city',
    name: 'City',
    component: City
  },
  {
    path: '/detail/:id',
    name: 'Detail',
    component: Detail
  }],
  scrollBehavior (to, from, savedPosition) {    //加上這段代碼就可以解決
    return { x: 0, y: 0}
  }
})

57. 修改vue-cli生成的項目的package.json的啓動配置項

"scripts": {
    "dev": "webpack-dev-server --host 0.0.0.0 --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "lint": "eslint --ext .js,.vue src",
    "build": "node build/build.js"
  },

這樣寫就能通過ip地址訪問webpack-dev啓動的服務

58. vue項目的打包上線(針對vue-cli生成的項目)

        npm run build  打包編譯

        把生成的dist目錄中的東西給後端,扔到後端的根目錄裏面就行了

        如果要運行在其他路徑下

build: {                          // config文件夾下index.js    (vue-cli項目)
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/project/',     //修改這裏就可以使項目運行在後端的project路徑下(當然要重新打包,然後把生成的dist目錄修改成project)

59. 項目要請求其他端口或者域名下的接口數據:

module.exports = {      // config文件夾下index.js    (vue-cli項目)
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
      '/api':{
        target: 'http://localhost:80',        // 前端服務跑在8080端口,後端服務器是80 就改成80就可以了 (其他域名就被整個域名改掉)
        pathRewrite: {
          '^/api':'/static/mock/'   //這裏要根據實際情況來改,如果接口本身就是/api 映射到 /api 那就可以把它去掉
        }
      }
    },

60. 行內設置樣式

<div class="tiao" :style="{ width: item.jingdu}"></div>

61. router-link 標籤上面綁定 @click會失效,要這樣綁定 (只要是其他的組件標籤都要加.native,原生類似 input這種標籤綁定就不用)

<router-link tag="div" to="before" class="wangqi yiyang" @click.native="beforeClick">      // 加上.native
            <div :class="{ 'active': !isBenqi }">往期成績</div>
        </router-link>

另外 router-link 標籤上的 to='before'  就是把當前路由鏈接最後一個改成before,如果加上 to='/before' 就是 跳到 /before 的路徑下

62. 獲取當前頁面的路由url地址用 : this.$route.path

63. vue.js 刷新頁面 自動執行某個點擊事件可以使用vue的生命週期函數,如create或者mounted

64. 在vue中使用 Clipboard.js  (頁面複製文本到剪切板的)   

        git地址: https://github.com/zenorocha/clipboard.js

 

npm install clipboard --save

import Clipboard from 'clipboard'     // 引入

export default {
  name: 'Recharge',
  data () {
    return {
        clipboard:{},
        dizhi: '56565DFlfdgkdflgkdflgkldfgldfgdllfs44544'
    }
  },
  mounted () {
      this.clipboard = new Clipboard('.zi')     // 綁定要點擊的那個按鈕
      this.clipboard.on('success',function(e){        // 複製成功或者失敗的事件
          alert("複製成功")
          e.clearSelection();
      });
      this.clipboard.on('error', function(e) {
        alert("複製失敗!");
    });
  }
destroyed () {
      this.clipboard.destroy()    // 要在這裏銷燬,不然會彈出多次提示
  }
}
</script>

 

<div class="copy">
     <div class="zi" data-clipboard-target=".dizhi">一鍵複製</div>    //點擊這個按鈕,target那個屬性是綁定要文本的目標
</div>
<div class="dizhi">{{dizhi}}</div>      // 要複製的文本的div

65. vue實現消息的無縫向上滾動效果: 參考 http://www.jb51.net/article/129733.htm   (親測可用)

66. destroyed 這個生命週期表示切換頁面後執行,可以在這銷燬一些定時器事件等

destroyed () {
   window.clearInterval(this.timeID);  // 防止切換到其他組件頁面報錯
},

        (setInterval返回值相當於一個Id,每次執行都會產生一個特定的Id,返回值爲數字,從一開始逐次累加,清除就是找到他            的id然後 clearInterval(id)就行了)

 

67. 想要爲div加過渡動畫就要用transition標籤來包裹,vue會自動查看該元素的css來構建動畫流程,name屬性自定義

 

<transition name="fade">   // 如果name屬性等於fade,那麼樣式裏面的樣式名前綴就是.fade-enter,如果不定義name屬性,那麼樣式名前綴就是.v-enter
   <div v-if="show">hello world</div>
</transition>
.fade-enter {     隱藏到顯示
   opacity: 0;
}
.fade-enter-active {
   transition: opacity 1s;
}

        vue會自動爲標籤加上這兩個類名來做動畫,我們只需要定義好類名的樣式內容即可

.fade-leave-to{    顯示到隱藏
   opacity: 0;
}
.fade-leave-active{
   transition: opacity 3s;
}

        如果我們想要顯示到隱藏與隱藏到顯示都有過渡效果,就可以把這些樣式寫在一起

.fade-enter,.fade-leave-to{   
   opacity: 0;
}
.fade-enter-active,.fade-leave-active{
   transition: opacity 3s;
}

68. vue中使用@keyframe這種css3的動畫

@keyframes bounce-in{
   0%{
     transform: scale(0);
   }
   50%{
     transform: scale(1.5);
   }
   100%{
     transform: scale(1);
   }
}
.v-enter-active {
   transform-origin: left center;
   animation: bounce-in 1s;
}
.v-leave-active{
   transform-origin: left center;
   animation: bounce-in 1s reverse;
}

69. 在vue中使用animate.css庫

<link...>  (引入animate.css庫)
<transition 
   name="fade"
   enter-active-class="animated swing"
   leave-active-class="animated shake"   
>
   <div v-if="show">hello world</div>
</transition>

70. 加上 appear 和 appear-active-class 頁面一刷新就有動畫效果產生了(在引入animate庫的前提下)

<transition 
   name="fade"
   appear
   enter-active-class="animated swing"
   leave-active-class="animated shake"   
   appear-active-class="animated swing"
>
   <div v-if="show">hello world</div>
</transition>

71. 插槽的使用(父組件向子組件傳遞DOM結構數據)

<body>
  <div>
    <child>
      <p slot='header'>header</p>   <p slot='footer'>footer</p>
    </child>
  </div>
  <script>
    Vue.component('child',{
      template: `<div>  <slot name='header'></slot>   //用這個來接收父組件傳遞過來的DOM結構
                  <p>hello</p>
                  <slot name='footer'></slot>   //用這個來接收父組件傳遞過來的DOM結構
                </div>`
    })
    ...
  </script>

72. 實現漸隱漸現效果的 vue-cli 中的可複用組件
    

<template>    //例如這個組件名文件名都叫 FadeAnimation
    <transition>
        <slot></slot>    
    </transition>
</template>
<script>
export default {
    name: 'FadeAnimation'
}
</script>
<style lang="stylus" scoped>
    .v-enter,.v-leave-to
        opacity: 0
    .v-enter-active,.v-leave-active
        transition: opacity .5s
</style>

哪個組件要用就引入以上組件然後用組件名包裹要漸隱漸現的元素

<fade-animation>
    <common-gallary :imgs="bannerImgs" v-show="showGallary" @close="handleGallaryClose"></common-gallary>
</fade-animation>

73. 項目完成想要真機調試時,使用localhost可以訪問,使用內網ip地址訪問不了,這是因爲webpack-dev啓動的項目默認不支持通過ip地址訪問

 

 

74. 獲取url上的?後面的參數用 

// 獲取期號
let qi = this.$route.query.qi;
console.log(qi)

75. tab 標籤頁切換時給當前頁面的標籤添加樣式

<router-link tag='div' to='/' class="home" exact> //注意:默認頁即首頁要加上 exact

<div class="ico">

<span class="iconfont">&#xe610;</span>

</div>

<div class="wenzi">競猜</div>

</router-link>

<router-link tag='div' to='/my' class="hangqing">

<div class="ico">

<span class="iconfont"> &#xe619;</span>

</div>

<div class="wenzi">我的</div>

</router-link>

 

在app.vue 中加上

 

<style>

.router-link-active {

color: #fff //在這裏填寫你當前標籤頁的樣式

}

</style>

 

76. Vant庫的使用

 

        npm i vant -S  , npm i babel-plugin-import -D

        在.babelrc中配置

"plugins": [
    "transform-vue-jsx", 
    "transform-runtime",
    ["import",{"libraryName":"vant","style":true}]
  ]

        src/main.js

import { Button } from 'vant'
Vue.use(Button)
有了這段代碼之後,我們就可以在需要的組件頁面中加入Button了.

<van-button type="primary">主要按鈕</van-button>

        如果不在src/main.js里加入代碼,而在需要的頁面單獨引入:

 

<script>
import { Popup } from 'vant'
export default {
  name: 'HomeContent',
  components: {
    [Popup.name]: Popup
  },
<van-popup v-model="show" position="bottom" :overlay="false">
        內容
    </van-popup>

77. vue使用相對路徑打包,可以直接打開(直接本地文件協議可以打開)丟給後臺用:

        首先需要修改config/index.js文件:

build: {

// Template for index.html

index: path.resolve(__dirname, '../dist/index.html'),

 

// Paths

assetsRoot: path.resolve(__dirname, '../dist'),

assetsSubDirectory: 'static',

// assetsPublicPath: '/transaction/',

assetsPublicPath: './', //修改這裏

        然後修改build/utils.js文件

if (options.extract) {

return ExtractTextPlugin.extract({

use: loaders,

fallback: 'vue-style-loader',

publicPath: '../../', //添加這一行

})

} else {

return ['vue-style-loader'].concat(loaders)

}

}

 

// https://vue-loader.vuejs.org/en/configurations/extract-css.html

return {

 

npm run build  即可打包成直接可以訪問的文件了

78. 用vue 做語言切換: npm install vue-i18n

    

import VueI18n from 'vue-i18n' //vue-cli項目的main.js中這麼寫

Vue.use(VueI18n)

import LangEn from '../static/lang/en' // 引入配置的語言包,在static/lang文件夾下

// import LangZhCHS from '../static/lang/zhCHS'

import LangZhCHT from '../static/lang/zhCHT'

import LangYueNan from '../static/lang/yuenan'

 

const i18n = new VueI18n({

//定義默認語言

locale: 'Cn',

messages:{

'En': LangEn,

'Cn': LangZhCHT,

'Vn': LangYueNan

}

})

new Vue({ // 也是main.js 文件, 要掛載到Vue的實例上

el: '#app',

router,

i18n,

components: { App },

template: '<App/>'

})

在根目錄下的static文件夾中新建lang文件夾,作爲語言包
//en.js  語言包文件是這樣的  
module.exports={
  message: {
    hello: 'hello',
    about: 'about',
    welcome: "Welcome"
  }
}
//zhCHS.js
module.exports={
  message: {
    hello: '你好',
    about: '關於',
    welcome: "歡迎"
  }
}

在組件文件裏的html上面是這麼用:{{ $t("message.hello") }}

在組件文件裏的script裡面是這麼用: this.$t("message.welcome")

動態切換語言這樣: this.$i18n.locale='CN'

79. 除了根組件,子組件想定義data必須要把它定義成一個函數

data () {
  return {
    content: "hello"
  }
}

80. vue 顯示base64 的圖片數據在頁面上

 

<img :src="codeImg" class="img3" />

 

this.codeImg = "data:image/jpeg;base64,"+ msg.data.img

圖片文件是什麼格式就這裏就寫什麼格式(png,jpeg等等)

81. vue中異步組件的使用,需要什麼才加載什麼,提高性能:   

 

import Vue from 'vue' //這是router裏面的index.js文件

import Router from 'vue-router'

import Home from '@/pages/home/Home' //這一行刪除掉

import My from '@/pages/my/My' //這一行刪除掉

import Past from '@/pages/past/Past' //這一行刪除掉

 

Vue.use(Router)

 

export default new Router({

routes: [

{

path: '/',

name: 'Home',

component: () => import('@/pages/home/Home') //修改這裏

},

{

path: '/goals',

name: 'My',

component: () => import('@/pages/my/My') //修改這裏

},

{

path: '/winner',

name: 'Past',

component: () => import('@/pages/past/Past') //修改這裏

},

{

path: '/records',

name: 'Shuoming',

component: Shuoming

},

{

path: '/r

異步組件只有在app.js變得特別大(至少超過1mb)的時候才使用,其他情況就不需要考慮使用這種異步組件的形式,但是本人實踐中發現有用還是好,首頁加載快了很多

以上是在路由中使用異步組件,其他地方也可以用這種形式(父組件包含子組件的地方)

<template>

<div class="bg">

<home-shousuo :duizhanList="duizhanList" :yu_e="yu_e"></home-shousuo>

</div>

</template>

 

<script>

import HomeShousuo from './components/Shousuo' //這一行去掉

import axios from 'axios'

 

export default {

name: 'Home',

components: {

HomeShousuo: () => import('./components/Shousuo') //修改這裏

},

 

這個異步組件的方式其實不一定要用,除非app.js真的很大才用,不然反而多了文件請求

 

 

 

 

 

 

        

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章