18年年末,就一個字,忙,貌似一到年末哪一個公司都在衝業績,包括咱們本身開發本身公司的項目也同樣得加把勁。自從18年年初立了個flag17年年終總結——走過2017,迎來2018Flag到如今又一年了。想一想當時立的flag仍是不少沒有完成到,說的第一點就沒有完成了(ps:這確實不能怪我,真的忙),健身也是落下了,而node.js的呢還在進程中,說不定稍後會出了系列的文章(ps:固然不會像以前那幾篇那樣,感受寫得有點雲裏霧裏的)。固然,今天的重點不是說這些,而是我在vue項目上實踐的一些小彙總和踩坑指南。另,結尾有福利喔~~~css
這一年前先後後大概作了有四個vue相關的項目(ps:vue-cli腳手架搭建),其中包括兩個移動端和兩個管理後臺的(ps:有一個管理端還在進行中),其中難免遇到了很多坑,還有很多的總結。html
├── App.vue
├── main.js
├── permission.js
├── router
│ └── index.js
├── api
│ └── index.js
│ └── xx.js
├── assets
│ ├── images
│ ├── flexible.js
│ └── common
│ └── common.less
│ └── mixin.less
├── components
├── utils
├── store
│ ├── index.js
│ └── xxStore.js
└── views
├── index.vue
└── xx.vue
對vue-cli有了解的應該知道通常咱們的源碼就寫在src文件夾下面。其中App.vue就是根組件,其餘的組件咱們就能夠經過App.vue的前端
<router-view/>渲染;main.js就是入口文件,通常用於引入通用組件,UI框架,router,axios,store掛載等;permission.js則用於在路由渲染前後須要設置的權限之類的;components則爲通用組件的封裝;utils則爲通用的方法的封裝;api則爲通用api的封裝調用等。vue
例如:main.jsjava
import 'babel-polyfill' import Vue from 'vue' import Es6Promise from 'es6-promise' require('es6-promise').polyfill() Es6Promise.polyfill() import App from './App' import './assets/flexible' import axios from 'axios' import router from './router' import store from './store' import './permission' import {WechatPlugin,LoadingPlugin,ToastPlugin,AlertPlugin,ConfirmPlugin } from 'vux' import VueLazyload from 'vue-lazyload' //掛載axios Vue.prototype.axios=axios //配置微信jssdk,經過Vue.wechat直接訪問wx Vue.config.productionTip = false Vue.use(WechatPlugin) Vue.use(LoadingPlugin) Vue.use(ToastPlugin) Vue.use(AlertPlugin) Vue.use(ConfirmPlugin) Vue.use(VueLazyload,{ error:require('./assets/images/activity_default_loading.png'), loading:require('./assets/images/activity_default_loading.png') }) /* eslint-disable no-new */ new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' })
如今的vue-cli開發,通常都是使用axios進行接口請求,其中一大好處就是能夠進行請求和響應的攔截,進而進行一些通用的配置,因此能很好的作到了接口的封裝。node
例如:request.jswebpack
import axios from 'axios' import { AlertModule } from 'vux' // 建立axios實例 const service = axios.create({ //baseURL: process.env.ENV_CONFIG=='dev'?'/api':'', // api的base_url baseURL: process.env.ENV_CONFIG=='dev'?'/api':process.env.BASE_API, //timeout: 10000, // 請求超時時間 headers:{ } }) // request攔截器 service.interceptors.request.use( config => { if( config.method === 'post' ){ config.data.http_headers={ } } return config }, error => { // Do something with request error // for debug console.log(error) Promise.reject(error) } ) // respone攔截器 service.interceptors.response.use( response => { if (response.data.result && response.data.result==='failed') { AlertModule.show({ title:'提示', content:response.data.text, /*onHide () { router.push({ name:'index' }) }*/ }) return } else{ return response.data } }, error => { console.log('err' + error) // for debug /*AlertModule.show({ title:'斑馬提示', content:'連接超時,請從新嘗試', })*/ return Promise.reject(error) } ) export default service
以後,咱們就能夠經過api目錄暴露封裝的接口調用ios
import request from '@/utils/request' export function doXx(data) { return request({ url:'/xx', method:'post', data }) }
看axios文檔咱們能夠了解到,axios的其中一個特色就是將數據轉換成json格式,可是有些接口因爲歷史等緣由後臺不方便調整的話,就須要前端作些處理了。es6
例如,以formdata格式提交參數則能夠經過axios內置的qs模塊進行data的格式轉換,而後設置請求頭便可web
export function XXRequest(data) { return request({ transformRequest: [function(data) { //在請求以前對data傳參進行格式轉換 data = qs.stringify(data) return data }], url:'/xx.do', method:'post', data, headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } }) }
又例如,後臺返回一個form表單,須要前端提交form表單,則須要,經過路由的resolve對象,this.$router.resolve解析接口回調參數而且打開空白頁面並提交form表單
// res爲回調參數 let routerData = this.$router.resolve({name:'apply',query:{htmls:res}}) window.open(routerData.href,'_ blank') const div = document.createElement('div') div.innerHTML = res document.body.appendChild(div) document.forms [0] .submit() apply.vue作法 <template> <div v-html ="apply"> {{apply}} </div> </template> <script> export default { name:'apply', data(){ return { apply:'' } }, mounted(){ let form = this.$route.query.htmls this.apply = form this.$nextTick(()=> { document.forms [0].submit() }) } } </script>
npm install less less-loader --save 修改webpack.base.conf.js rules { test: /\.less$/, loader: "style-loader!css-loader!less-loader", }
部分低版本的手機或者IE下是不兼容es6中的promise的,若是用到了promise語法的話,就須要進行es6編譯es5,因此作法須要引入
es6-promise而且在main.js中引入
npm install es6-promise --save main.js中引入 import Es6Promise from 'es6-promise' require('es6-promise').polyfill() Es6Promise.polyfill()
通常的ico都是設置在項目根目錄下,而後調整build webpack.dev.conf.js和webpack.prod.conf.js中的new HtmlWebpackPlugin設置參數
favicon:path.resolve(__dirname,'xx.ico')便可。
通常經常使用的vue組件的引入,例如vue-lazyload、vue-scroller等通常能夠上npm查看相關是使用方法便可。
通常項目都會部署到端口的某個文件夾下面,因此須要修改config index.js的assetsPublicPath路徑
index: path.resolve(__dirname, '../文件夾名/index.html'), assetsRoot: path.resolve(__dirname, '../文件夾名'), assetsSubDirectory: 'static', assetsPublicPath: './', // ./爲相對文件夾路徑,不然/爲根目錄
因爲打包完後的是靜態文件,因此咱們能夠直接部署到Nginx上面,接口經過Nginx代理便可。可是刷新會丟失404,因此須要作個重定向便可。
location /{ root dist; index index.html; try_files $uri $uri/ /dist/index.html; }
部署到Tomcat上的話,同樣存在刷新丟失的狀況,我看有人提出配置web.xml進行404重定向,這個我司也是有實踐了下
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>xxx</display-name>
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
</web-app>
可是,這樣部署的話實際上是第一次刷新ok的,可是再次刷新則仍是404丟失。(ps:在移動設備上會,有知道的大佬能夠留言喔~)
其中,有了解過vue-cli開發的話,其實用vue開發在業務邏輯上是沒有太大的問題的,由於不少大佬已經開發出各類組件供咱們調用了,我呢,就在部署上面卡了好久,由於最初的想法是部署到Tomcat上的,因此一直嘗試都沒有成功,最初的緣由的就是使用了es6的promise,而後呢又瞭解到了須要配置重定向xml。最後覺得大功告成,仍是存在二次刷新丟失的問題。因此部署到了Nginx上,而後設置從新定這樣子解決。
另,其中還有不少可能沒有總結到位,到時有補充的會補充在這裏~
再另,附福利
winter大大,前手機淘寶前端負責人在極客時間上發了《重學前端》的課程,掃個人二維碼報名的話能夠找我分獎勵喔,另外經過我二維碼報名的加我wx:UEMtQWFyb24= (ps:base64轉碼)可得vue教程一套。嘻嘻