人的差異其實很小:一,你在猶豫,他在做,所以他比你成功機會多;二,你在找藉口,他在解決問題,所以他比你事業有成;三,你在消費,他在理財,所以他比你更富足;四,你在算計自己的利益,他在考慮對方的利益,所以他比你更加有人脈。成功沒有奇蹟,只有軌跡!
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"></span>
 是一種圖標的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"></span>
</div>
<div class="wenzi">競猜</div>
</router-link>
<router-link tag='div' to='/my' class="hangqing">
<div class="ico">
<span class="iconfont"> </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真的很大才用,不然反而多了文件請求