vue常見開發問題整理

1.(webpack)vue-cli構建的項目如何設置每一個頁面的title

在路由裏每一個都添加一個metajavascript

[{
    path:'/login', meta: { title: '登陸頁面' }, component:'login' }]

鉤子函數:php

在main.js中添加以下代碼css

router.beforeEach((to, from, next) => { window.document.title = to.meta.title; next() })

2.vue項目中使用axios上傳圖片等文件

首先安裝axios:
1.利用npm安裝npm install axios –save
2.利用bower安裝bower install axios –save
3.直接利用cdn引入html

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

通常狀況上傳照片有兩種方式:前端

  • 1.本地圖片轉換成base64,而後經過普通的post請求發送到服務端。

  操做簡單,適合小圖,以及若是想兼容低版本的ie沒辦法用此方法vue

  • 2.經過form表單提交。

  form表單提交圖片會刷新頁面,也能夠時form綁定到一個隱藏的iframe上,能夠實現無刷新提交數據。html5

這裏只講解一下第二種方式:
html代碼:java

<input name="file" type="file" accept="image/png,image/gif,image/jpeg" @change="update"/>

js代碼:node

import axios from 'axios' // 添加請求頭 update (e) { // 上傳照片 var self = this let file = e.target.files[0] /* eslint-disable no-undef */ let param = new FormData() // 建立form對象 param.append('file', file) // 經過append向form對象添加數據 param.append('chunk', '0') // 添加form表單中其餘數據 console.log(param.get('file')) // FormData私有類對象,訪問不到,能夠經過get判斷值是否傳進去 let config = { headers: {'Content-Type': 'multipart/form-data'} } // 添加請求頭 axios.post('http://172.19.26.60:8081/rest/user/headurl', param, config) .then(response => { if (response.data.code === 0) { self.ImgUrl = response.data.data } console.log(response.data) }) }

3.qs.stringify() 和JSON.stringify()的區別以及在vux中使用post提交表單數據須要qs庫序列化

qs庫的npm地址:https://www.npmjs.com/package/qsreact

功能雖然都是序列化。假設我要提交的數據以下

var a = {name:'hehe',age:10};

qs.stringify序列化結果以下
name=hehe&age=10

而JSON.stringify序列化結果以下:
"{"a":"hehe","age":10}"

vux中使用post提交表單數據:

this.$http.post(this.$sign.config.url.loginUrl,this.$qs.stringify({ "phone":this.phoneNumber, "vCode":this.loginCode, "smsCode":this.phoneCode }) ) .then(response=>{ console.log(response.data); if(response.data.httpCode == 200){ }else{ } }) 

在firebug中能夠看到傳遞的參數:
phone=15210275239&vCode=8vsd&smsCode=1534

在vue中使用axios:

this.$axios.post(loginUrl, { "email": this.email, "password": this.password }, { transformRequest: (data) => { return this.$qs.stringify(data) }, }).then(res => { if(res.data.resultCode == RESULT_CODE_SUCCESS){ console.log('登陸成功'); this.$router.push({name:"home"}) }else{ console.log('登陸失敗'); } }).catch(err => { console.log('登登陸出現錯誤'); })

4.vue中實現全局的setCookie,getCookie以及delCookie方法筆記

import Vue from 'vue' import Vuex from 'vuex' import VueRouter from 'vue-router' import App from '../component/App.vue' import Login from '../component/Login.vue' import UserInfo from '../component/UserInfo.vue' //狀態管理 Vue.use(Vuex) //路由 Vue.use(VueRouter) //路由配置 //若是須要加菜單,就在這裏添加路由,並在UserMenu.vue添加入口router-link const router = new VueRouter({ routes: [{ path: '/login', component: Login }, { path: '/user_info', component: UserInfo }] }) //Vuex配置 const store = new Vuex.Store({ state: { domain:'http://test.example.com', //保存後臺請求的地址,修改時方便(比方說從測試服改爲正式服域名) userInfo: { //保存用戶信息 nick: null, ulevel: null, uid: null, portrait: null } }, mutations: { //更新用戶信息 updateUserInfo(state, newUserInfo) { state.userInfo = newUserInfo; } } }) //設置cookie,增長到vue實例方便全局調用 Vue.prototype.setCookie = (c_name, value, expiredays) => { var exdate = new Date();     exdate.setDate(exdate.getDate() + expiredays);     document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString()); } //獲取cookie Vue.prototype.getCookie = (name) => { var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); if (arr = document.cookie.match(reg)) return (arr[2]); else return null; } //刪除cookie Vue.prototype.delCookie =(name) => { var exp = new Date(); exp.setTime(exp.getTime() - 1); var cval = this.getCookie(name); if (cval != null) document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString(); } //vue實例 var app = new Vue({ data: {}, el: '#app', render: h => h(App), router, store, watch:{ "$route" : 'checkLogin' }, created() { this.checkLogin(); }, methods:{ checkLogin(){ //檢查是否存在session if(!this.getCookie('session')){ this.$router.push('/login'); }else{ this.$router.push('/user_info'); } } } })

5.webpack中alias配置中的「@」是什麼意思?

如題所示,build文件夾下的webpack.base.conf.js

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

其中的@的意思是:
只是一個別名而已。這裏設置別名是爲了讓後續引用的地方減小路徑的複雜度。

//例如 src - components - a.vue - router - home - index.vue index.vue 裏,正常引用 A 組件: import A from '../../components/a.vue' 若是設置了 alias 後。 alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src') } 引用的地方路徑就能夠這樣了 import A from '@/components/a.vue' 這裏的 @ 就起到了【resolve('src')】路徑的做用。

6.webpack proxyTable 代理跨域

webpack 開發環境可使用proxyTable 來代理跨域,生產環境的話能夠根據各自的服務器進行配置代理跨域就好了。在咱們的項目config/index.js 文件下能夠看到有一個proxyTable的屬性,咱們對其簡單的改寫

proxyTable: { '/api': { target: 'http://api.douban.com/v2', changeOrigin: true, pathRewrite: { '^/api': '' } } }

這樣當咱們訪問localhost:8080/api/movie的時候 其實咱們訪問的是http://api.douban.com/v2/movi...

固然咱們也能夠根據具體的接口的後綴來匹配代理,如後綴爲.shtml,代碼以下:

proxyTable: { '**/*.shtml': { target: 'http://192.168.198.111:8080/abc', changeOrigin: true } }

可參考地址:
webpack 先後端分離開發接口調試解決方案,proxyTable解決方案
http-proxy-middleware

7.如何在 vue 項目里正確地引用 jquery 和 jquery-ui的插件

使用vue-cli構建的vue項目,webpack的配置文件是分散在不少地方的,而咱們須要修改的是build/webpack.base.conf.js,修改兩處的代碼

// 在開頭引入webpack,後面的plugins那裏須要 var webpack = require('webpack') // resolve module.exports = { // 其餘代碼... resolve: { extensions: ['', '.js', '.vue'], fallback: [path.join(__dirname, '../node_modules')], alias: { 'src': path.resolve(__dirname, '../src'), 'assets': path.resolve(__dirname, '../src/assets'), 'components': path.resolve(__dirname, '../src/components'), // webpack 使用 jQuery,若是是自行下載的 // 'jquery': path.resolve(__dirname, '../src/assets/libs/jquery/jquery.min'), // 若是使用NPM安裝的jQuery 'jquery': 'jquery' } }, // 增長一個plugins plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ], // 其餘代碼... }

這樣就能夠正確的使用jQuery了,好比我要引入Bootstrap,咱們在vue的入口js文件src/main.js開頭加入

// 使用Bootstrap import './assets/libs/bootstrap/css/bootstrap.min.css' import './assets/libs/bootstrap/js/bootstrap.min'

這樣Bootstrap就正確的被引用並構建。
在好比使用toastr組件,只須要在須要的地方import進來,或者全局引入css在須要的地方引用js,而後直接使用

// 使用toastr import 'assets/libs/toastr/toastr.min.css' import toastr from 'assets/libs/toastr/toastr.min' toastr.success('Hello')

參考:Managing Jquery plugin dependency in webpack

vue-cli webpack全局引入jquery

1.首先在package.json里加入,

dependencies:{ "jquery" : "^2.2.3" }

而後 npm install

2.在webpack.base.conf.js里加入

var webpack = require("webpack")

3.在module.exports的最後加入

plugins: [ new webpack.optimize.CommonsChunkPlugin('common.js'), new webpack.ProvidePlugin({  jQuery: "jquery",  $: "jquery" }) ]

4.而後必定要從新 run dev

5.在main.js 引入就ok了

import $ from 'jquery'

參考: vue-cli怎麼引入jquery

在.vue文件中引入第三方非NPM模塊

var Showbo = require("exports?Showbo!./path/to/showbo.js");

參考: exports-loader

vue-cli引入外部文件

在 webpack.base.conf.js 中添加externals
圖片描述

externals 中 swiper 是鍵,對應的值必定的是插件 swiper.js 所定義的變量 Swiper :
圖片描述

圖片描述

以後再在根目錄下的index.html文件裏引入文件:<script src="static/lib/swiper.js"></script>
這樣子就能夠在須要用到swiper.js的文件里加入這行代碼:import Swiper from 'swiper',這樣就能正常使用了。
參考: https://segmentfault.com/q/1010000005169531?_ea=806312

8.vue和mintui-Loadmore結合實現下拉刷新,上拉加載 (待優化)

mintui是餓了麼團隊針對vue開發的移動端組件庫,方便實現移動端的一些功能,這裏只用了Loadmore功能實現移動端的上拉分頁刷新,下拉加載數據.
mintui官網:http://mint-ui.github.io/#!/zh-cn

<template> <div class="main-body" :style="{'-webkit-overflow-scrolling': scrollMode}"> <v-loadmore :top-method="loadTop" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" :auto-fill="false" ref="loadmore"> <ul class="list" v-for="(val, key) in pageList"> <li> <div>我是小11</div> <div>我是小11</div> </li> </ul> </v-loadmore> </div> </template> <script> import {Loadmore} from 'mint-ui'; export default { data:function() { return { searchCondition:{ //分頁屬性 pageNo:"1", pageSize:"10" }, pageList:[], allLoaded: false, //是否能夠上拉屬性,false能夠上拉,true爲禁止上拉,就是不讓往上劃加載數據了 scrollMode:"auto" //移動端彈性滾動效果,touch爲彈性滾動,auto是非彈性滾動 } }, components: { 'v-loadmore':Loadmore // 爲組件起別名,vue轉換template標籤時不會區分大小寫,例如:loadMore這種標籤轉換完就會變成loadmore,容易出現一些匹配問題 // 推薦應用組件時用a-b形式起名 }, mounted(){ this.loadPageList(); //初次訪問查詢列表 }, methods: { loadTop:function() { //組件提供的下拉觸發方法 //下拉加載 this.loadPageList(); this.$refs.loadmore.onTopLoaded();// 固定方法,查詢完要調用一次,用於從新定位 }, loadBottom:function() { // 上拉加載 this.more();// 上拉觸發的分頁查詢 this.$refs.loadmore.onBottomLoaded();// 固定方法,查詢完要調用一次,用於從新定位 }, loadPageList:function (){ // 查詢數據 this.api.PageList(this.searchCondition).then(data =>{ // 是否還有下一頁,加個方法判斷,沒有下一頁要禁止上拉 this.isHaveMore(data.result.haveMore); this.pageList = data.result.pageList; this.$nextTick(function () { // 原意是DOM更新循環結束時調用延遲迴調函數,大意就是DOM元素在由於某些緣由要進行修改就在這裏寫,要在修改某些數據後才能寫, // 這裏之因此加是由於有個坑,iphone在使用-webkit-overflow-scrolling屬性,就是移動端彈性滾動效果時會屏蔽loadmore的上拉加載效果, // 花了很久才解決這個問題,就是用這個函數,意思就是先設置屬性爲auto,正常滑動,加載完數據後改爲彈性滑動,安卓沒有這個問題,移動端彈性滑動體驗會更好 this.scrollMode = "touch"; }); }); }, more:function (){ // 分頁查詢 this.searchCondition.pageNo = parseInt(this.searchCondition.pageNo) + 1; this.api.loadPageList(this.searchCondition).then(data=>{ this.pageList = this.pageList.concat(data.result.pageList); this.isHaveMore(data.result.haveMore); }); }, isHaveMore:function(isHaveMore){ // 是否還有下一頁,若是沒有就禁止上拉刷新 this.allLoaded = true; //true是禁止上拉加載 if(isHaveMore){ this.allLoaded = false; } } } } </script> 

PS:有個坑必定要注意就是註釋裏說的iPhone裏loadmore和-webkit-overflow-scrolling屬性衝突沒法上拉問題

可參考另一個插件,沒有使用過,《簡單靈活且強大的Vue下拉刷新組件:vue-pull-to》

9.在vue+webpack實際開發中出現兩個或多個菜單公用一個組件的解決方案

在vue的實際開發中每每會遇到公用一個組件的問題,好比有一個菜單中的兩個按鈕,點擊每一個按鈕調用的是同一個組件,其內容是根據路由的參數的不一樣來請求不一樣的內容。

第一步,首先新建一個vue+webpack+vuecli的demo,以下操做:
全局安裝vue-clivue-cil是vue的腳手架工具,安裝命令:

npm install -g vue-cli

第二步,進入到工程目錄中,建立一個vuedemo的文件夾工程,以下兩步操做:

cd vue_test_project //進入vue_test_project目錄下 vue init webpack vuedemo //在vue_test_project目錄下建立一個vuedemo工程

輸入這個命令以後,會出現一些提示,是什麼不用管,一直按回車便可。

第三步,以下操做:

cd vuedemo npm install

執行npm install須要一點時間,由於會從服務器上下載代碼啦之類的。而且在執行過程當中會有一些警告信息。不用管,等着就是了。若是長時間沒有響應,就ctrl+c中止掉,而後再執行一次便可。

最後一步,操做以下:

npm run dev

在運行了npm run dev以後,會自動打開一個瀏覽器窗口,就能夠看到實際的效果了。這個demo就建立好了。如今就在這個demo中添加一些內容,修改爲以下:
圖片描述

修改HelloWorld.vue的內容爲以下:

<template> <div class="hello"> <h1>{{ msg }}</h1> <h2>Essential Links</h2> <div class="btn"> <router-link :to="{name:'content',params:{differId:'con1'}}">內容按鈕1</router-link> <router-link :to="{name:'content',params:{differId:'con2'}}">內容按鈕2</router-link> </div> <router-view></router-view> </div> </template> <script> export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } } } </script> <style scoped> h1, h2 { font-weight: normal; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } </style>

路由router下的index.html的修改成以下:

import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import content from '@/components/conDetail' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld, children:[ {name:'content',path:'content/:differId',component:content} ] } ] })

如今建立一個conDetail.vue了,以下:

<template> <div class="same"> 這個是相同的內容 <div class="conlist"> <template v-for="item in items"> <p>{{item.con}}</p> </template> </div> </div> </template> <script> export default { name: 'conDetail', data () { return { msg: '', differIdType:'', conlist:[ {'con':'這是第一個內容按鈕的內容1'}, {'con':'這是第一個內容按鈕的內容2'} ], items:[], } }, mounted(){ this.differIdType = this.$route.params.differId == 'con1' ? '0' : '1'; if(this.differIdType == 0){ this.items = this.conlist; }else{ this.items = []; } }, watch:{ $route:function(to,from){ this.differIdType = to.params.differId == 'con1' ? '0' : '1'; if(this.differIdType == 0){ this.items = this.conlist; }else{ this.items = []; } } } } </script> <style> </style>

結果就是,當點擊內容按鈕1,出現了對象的內容,點擊內容按鈕2,出現相應的內容。固然我這兒寫的是點擊按鈕2的時候,其items的內容爲空數組。這兒也使用了$route的監聽。

複用組件時,想對路由參數的變化做出響應的話,你能夠簡單地 watch(監測變化) $route 對象:

const User = { template: '...', watch: { '$route' (to, from) { // 對路由變化做出響應... } } }

或者使用 2.2 中引入的 beforeRouteUpdate 守衛:

const User = { template: '...', beforeRouteUpdate (to, from, next) { // react to route changes... // don't forget to call next() } }

詳細瞭解路由相關的內容,查看官網:https://router.vuejs.org/zh-cn/

10.vue2.x父子組件以及非父子組件之間的通訊

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

父組件數據如何傳遞給子組件呢?能夠經過props屬性來實現

父組件:

<parent> <child :child-msg="msg"></child>//這裏必需要用 - 代替駝峯 </parent> data(){ return {  msg: [1,2,3] }; }

子組件經過props來接收數據:

方式1:

props: ['childMsg']

方式2 :

props: { childMsg: Array //這樣能夠指定傳入的類型,若是類型不對,會警告 }

方式3:

props: {  childMsg: {  type: Array,  default: [0,0,0] //這樣能夠指定默認的值 } }

這樣呢,就實現了父組件向子組件傳遞數據.

2.子組件與父組件通訊

子組件:

<template> <div @click="up"></div> </template> methods: { up() { this.$emit('fun','這是一段內容'); //主動觸發fun方法,'這是一段內容'爲向父組件傳遞的數據 } }

父組件:

<div> <child @fun="change" :msg="msg"></child> //監聽子組件觸發的fun事件,而後調用change方法 </div> methods: { change(msg) { this.msg = msg; } }

3.非父子組件通訊

若是2個組件不是父子組件那麼如何通訊呢?這時能夠經過eventHub來實現通訊.
所謂eventHub就是建立一個事件中心,至關於中轉站,能夠用它來傳遞事件和接收事件.

let Hub = new Vue(); //建立事件中心

組件1觸發:

<div @click="eve"></div> methods: { eve() { Hub.$emit('change','hehe'); //Hub觸發事件 } }

組件2接收:

<div></div>
created() {
    Hub.$on('change', () => { //Hub接收事件 this.msg = 'hehe'; }); }

可參考:vue非父子組件怎麼進行通訊

11.vue項目中在使用vue-router切換頁面的時候滾動條怎樣自動滾動到頂部?

有時候咱們須要頁面滾動條滾動到某一固定的位置,通常使用Window scrollTo() 方法。

語法就是:scrollTo(xpos,ypos)

xpos:必需。要在窗口文檔顯示區左上角顯示的文檔的 x 座標。

ypos:必需。要在窗口文檔顯示區左上角顯示的文檔的 y 座標。

例如滾動內容的座標位置100,500:

window.scrollTo(100,500);

好了,這個scrollTop這兒只是簡單介紹一下,下面咱們介紹下veu-router中的滾動行爲。

使用前端路由,當切換到新路由時,想要頁面滾到頂部,或者是保持原先的滾動位置,就像從新加載頁面那樣。 vue-router能作到,並且更好,它讓你能夠自定義路由切換時頁面如何滾動。

注意: 這個功能只在  HTML5 history 模式下可用。

當建立一個 Router 實例,你能夠提供一個 scrollBehavior 方法:

const router = new VueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 指望滾動到哪一個的位置 } })

scrollBehavior 方法接收 to 和 from 路由對象。第三個參數 savedPosition 當且僅當 popstate 導航 (經過瀏覽器的 前進/後退 按鈕觸發) 時纔可用。

這個方法返回滾動位置的對象信息,長這樣:

  • { x: number, y: number }
  • { selector: string, offset? : { x: number, y: number }} (offset 只在 2.6.0+ 支持)

若是返回一個 falsy (譯者注:falsy 不是 false參考這裏)的值,或者是一個空對象,那麼不會發生滾動。

舉例:

scrollBehavior (to, from, savedPosition) {  return { x: 0, y: 0 } }

對於全部路由導航,簡單地讓頁面滾動到頂部。

返回 savedPosition,在按下 後退/前進 按鈕時,就會像瀏覽器的原生表現那樣:

scrollBehavior (to, from, savedPosition) { if (savedPosition) {  return savedPosition } else {  return { x: 0, y: 0 } } }

若是你要模擬『滾動到錨點』的行爲:

scrollBehavior (to, from, savedPosition) { if (to.hash) {  return { selector: to.hash } } }

咱們還能夠利用路由元信息更細顆粒度地控制滾動。

 routes: [ { path: '/', component: Home, meta: { scrollToTop: true }}, { path: '/foo', component: Foo }, { path: '/bar', component: Bar, meta: { scrollToTop: true }} ]

完整的例子:

import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const Home = { template: '<div>home</div>' } const Foo = { template: '<div>foo</div>' } const Bar = { template: ` <div> bar <div style="height:500px"></div> <p id="anchor">Anchor</p> </div> ` } // scrollBehavior: // - only available in html5 history mode // - defaults to no scroll behavior // - return false to prevent scroll const scrollBehavior = (to, from, savedPosition) => { if (savedPosition) { // savedPosition is only available for popstate navigations. return savedPosition } else { const position = {} // new navigation. // scroll to anchor by returning the selector if (to.hash) { position.selector = to.hash } // check if any matched route config has meta that requires scrolling to top if (to.matched.some(m => m.meta.scrollToTop)) { // cords will be used if no selector is provided, // or if the selector didn't match any element. position.x = 0 position.y = 0 } // if the returned position is falsy or an empty object, // will retain current scroll position. return position } } const router = new VueRouter({ mode: 'history', base: __dirname, scrollBehavior, routes: [ { path: '/', component: Home, meta: { scrollToTop: true }}, { path: '/foo', component: Foo }, { path: '/bar', component: Bar, meta: { scrollToTop: true }} ] }) new Vue({ router, template: ` <div id="app"> <h1>Scroll Behavior</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/foo">/foo</router-link></li> <li><router-link to="/bar">/bar</router-link></li> <li><router-link to="/bar#anchor">/bar#anchor</router-link></li> </ul> <router-view class="view"></router-view> </div> ` }).$mount('#app')

在網上查了一下,網友說還能夠試試在main.js入口文件配合vue-router寫這個

router.afterEach((to,from,next) => { window.scrollTo(0,0); });

12.vue自定義全局組件並經過全局方法 Vue.use() 使用該組件

簡介

Vue.use( plugin ):安裝 Vue.js 插件。若是插件是一個對象,必須提供 install 方法。若是插件是一個函數,它會被做爲 install 方法。install 方法將被做爲 Vue 的參數調用。

當 install 方法被同一個插件屢次調用,插件將只會被安裝一次。

Vue.js 的插件應當有一個公開方法 install 。這個方法的第一個參數是 Vue 構造器,第二個參數是一個可選的選項對象:

MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或屬性 Vue.myGlobalMethod = function () { // 邏輯... } // 2. 添加全局資源 Vue.directive('my-directive', { bind (el, binding, vnode, oldVnode) { // 邏輯... } ... }) // 3. 注入組件 Vue.mixin({ created: function () { // 邏輯... } ... }) // 4. 添加實例方法 Vue.prototype.$myMethod = function (methodOptions) { // 邏輯... } }

經過全局方法 Vue.use() 使用插件:

// 調用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)

也能夠傳入一個選項對象:

Vue.use(MyPlugin, { someOption: true })

Vue.use 會自動阻止屢次註冊相同插件,屆時只會註冊一次該插件。

Vue.js 官方提供的一些插件 (例如 vue-router) 在檢測到 Vue 是可訪問的全局變量時會自動調用 Vue.use()。然而在例如 CommonJS 的模塊環境中,你應該始終顯式地調用 Vue.use()

// 用 Browserify 或 webpack 提供的 CommonJS 模塊環境時 var Vue = require('vue') var VueRouter = require('vue-router') // 不要忘了調用此方法 Vue.use(VueRouter)

實例:實現一個children組件

main.js中使用該組件的方法:

import childModule from './components/children' Vue.use(childModule)

組件文件夾的目錄結構以下:

|-components   |-children     |-index.js 導出組件,而且install     |-children.vue (定義本身的組件模板)

children.vue代碼以下:

import childrencomponent from './children.vue' const childrenMo = { install:function(Vue){ Vue.component('childModule',childrencomponent) } } export default childrenMo

這樣就實現了一個經過vue.use調用一個全局組件。

13.IE9報vuex requires a Promise polyfill in this browser問題解決

由於使用了 ES6 中用來傳遞異步消息的的Promise,而IE低版本的瀏覽器不支持。

如圖所示:
圖片描述

解決方法
第一步: 安裝 babel-polyfill 。 babel-polyfill能夠模擬ES6使用的環境,可使用ES6的全部新方法

npm install --save babel-polyfill

第二步: 在 Webpack/Browserify/Node中使用

在webpack.config.js文件中

module.exports = { entry: { app: './src/main.js' } }

替換爲:

module.exports = {
 entry: {  app: ["babel-polyfill", "./src/main.js"] } };

14.經過webpack+vue+vueRouter+vuecli的配置文件package.json建立一個新的項目

若是是簡單經過package.json來建立一個項目,只須要執行npm install

首先,咱們本身得手動建立一個webpack+vue+vueRouter+vuecli工程,執行下面:
如:
新建一個vue項目,建立一個基於"webpack"的項目,項目名爲vuedemo:

$ vue init webpack vuedemo

安裝完成後進入工程名稱再根據原來項目的配置文件初始化

$ cd vuedemo $ npm install

可是因爲在新建的時候對eslint的選擇中選擇了Yes,因此後面根據配置package.json的時候,發現沒有eslint-friendly-formatter 模塊,因爲原來的工程應該沒有配置這個,因此這兒須要安裝下,以下代碼:

npm i -D eslint eslint-friendly-formatter

模塊地址:https://www.npmjs.com/package/eslint-friendly-formatter

安裝後執行:npm run dev 發現運行起來的頁面沒有啓動起來,緣由是仍是這個eslint引發的。

出錯信息爲:

These relative modules were not found:
*/build/dev-client in multi ./build/dev-client ./src/main.js, *./src/main.js in multi ./build/dev-client ./src/main.js

緣由以下:
webpack.base.conf.js裏面,腳手架原本就有 js的編譯模塊,

{
        test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test')] }

咱們須要註釋掉這段代碼:

// { // test: /\.(js|vue)$/, // loader: 'eslint-loader', // enforce: 'pre', // include: [resolve('src'), resolve('test')], // options: { // formatter: require('eslint-friendly-formatter') // } // },

緣由就是致使重複編譯,因此應該就有兩個main.js文件。因此不要重複出現匹配規則就能夠。
而後運行npm run dev能夠了。
類似問題:vue-cli安裝完成以後,命令行npm run dev沒有問題,但webstorm報錯

15.VUE利用webpack 給生產環境和發佈環境配置不一樣的接口地址

第一步,分別設置不一樣的接口地址

首先,咱們分別找到下面的文件:

/config/dev.env.js /config/prod.env.js

其實,這兩個文件就是針對生產環境和發佈環境設置不一樣參數的文件。咱們打開dev.en.js文件。代碼以下:

var merge = require('webpack-merge') var prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"' })

咱們在NODE_ENV下面增長一項,代碼以下:

var merge = require('webpack-merge') var prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"', API_ROOT: '"//192.168.1.8/api"' })

prod.env.js文件修改成:

module.exports = { NODE_ENV: '"production"', API_ROOT: '"//www.baidu.com/api"' }

第二步,在代碼中調用設置好的參數

以咱們以前的演示代碼爲例。你本身的項目請根據你本身的狀況調整。如下文件和代碼僅供參考。
咱們打開src/config/api.js文件,將原來開頭的代碼

// 配置API接口地址 var root = 'https://cnodejs.org/api/v1'

修改成:

// 配置API接口地址 var root = process.env.API_ROOT

而後就完成了咱們的配置工做。最後,重啓項目,就能使新配置的接口地址生效了。

npm run dev npm run build

在main.js區分生產與開發環境

process.env.NODE_ENV == 'production'; //生產環境 process.env.NODE_ENV == 'development'; //開發環境

參考地址:http://blog.csdn.net/fungleo/article/details/54574049

16.vue單頁應用添加百度統計

前言

申請百度統計後,會獲得一段JS代碼,須要插入到每一個網頁中去,在Vue.js項目首先想到的可能就是,把統計代碼插入到index.html入口文件中,這樣就全局插入,每一個頁面就都有了;這樣作就涉及到一個問題,Vue.js項目是單頁應用,每次用戶瀏覽網站時,訪問內頁時頁面是不會刷新的,也就意味着不會觸發百度統計代碼;因此最終在百度統計後臺看到的效果就是隻統計到了網頁入口的流量,卻沒法統計到內頁的訪問流量。

解決方法

main.js文件中調用vue-routerafterEach方法,將統計代碼加入到這個方法裏面,這樣每次router發生改變的時候都會執行一下統計代碼,這樣就達到了目的,代碼以下:

router.afterEach( ( to, from, next ) => { setTimeout(()=>{ var _hmt = _hmt || []; (function() { //每次執行前,先移除上次插入的代碼 document.getElementById('baidu_tj') && document.getElementById('baidu_tj').remove(); var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?xxxx"; hm.id = "baidu_tj" var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); },0); } );
相關文章
相關標籤/搜索