創建一個完整的vue移動端項目配置


vue的安裝及創建一個新項目前一篇文章已經介紹過了,有需要的請看之前的文章

移動端項目

一、關於移動端的一些ui框架
1.Voinc 一個基於 vue.js 和 ionic 樣式的 UI 框架(https://wangdahoo.github.io/vonic-documents/#/?id=%E4%BB%8B%E7%BB%8D)
2.Vux 基於WeUI和Vue(2.x)開發的移動端UI組件庫 (https://vux.li/#/?id=%E7%AE%80%E4%BB%8B)
3. NutUI 京東輕量級移動端Vue組件庫(https://nutui.jd.com/#/index)
4. .Mint UI 由餓了么前端團隊推出的 Mint UI (http://mint-ui.github.io/docs/#/zh-cn2)
5. Vant是有贊前端團隊基於有贊統一的規范實現的 Vue 組件庫(https://github.com/youzan/zent)
6. Cube UI 滴滴 WebApp實現的移動端組件庫(https://didi.github.io/cube-ui/#/zh-CN/docs/quick-start)

二、移動端適配

方案:lib-flexible會自動在html的head中添加一個meta name="viewport"的標簽,同時會自動設置html的font-size為屏幕寬度除以10,也就是1rem等於html根節點的font-size。使用postcss-px2rem-exclude自動將css中的px轉成rem

步驟:1.項目中引入lib-flexible npm install lib-flexible --save
2.在項目的入口main.js文件中引入lib-flexible import ‘lib-flexible/flexible.js’
3.安裝postcss-px2rem-exclude npm install postcss-px2rem-exclude --save
4.在項目的根目錄下找到文件.postcssrc.js,在里面添加如下代碼

"postcss-px2rem-exclude": { remUnit: 75, exclude: /node_modules|folder_name/i // 忽略node_modules目錄下的文件(引入的第三方ui的樣式不會隨之改變) } 
  • 1
  • 2
  • 3
  • 4
  • 5

5.在依賴文件node_modules中找到postcss-px2rem-exclude文件中的lib下的index.js添加以下代碼(引入的第三方ui的樣式不會隨之改變)

try { var flag = options.exclude.includes('/') if (flag) { var arr = options.exclude.split('/') options.exclude = new RegExp(arr[1], arr[2]) } } catch (error) {} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在這里插入圖片描述

二.一 安裝sass-loader(如果使用到了sass編譯再安裝,不使用無需安裝)

npm install --save-dev sass-loader //sass-loader依賴於node-sass ,所以繼續安裝node-sass npm install --save-dev node-sass //注意1.安裝node-sass會報錯的原因,一般是因為網慢,所以安裝node-sass的時候可以使用cnpm安裝 //注意2.sass-loader安裝了但是編譯還是報錯,原因可能是sass-loader版本的問題(8.0.0),在package.json中把sass-loader的版本改成7.3.1,然后刪除依賴項,重新安裝依賴 
  • 1
  • 2
  • 3
  • 4
  • 5

三、給IDE裝vue插件(我現在使用的是vscode,就以vscode為例)
1.在vscode擴展里搜索Vetur
在這里插入圖片描述
2.安裝完成進行配置
文件–>首選項–>用戶代碼片段–>點擊新建代碼片段–取名vue.json 確定
3.刪除多余代碼
4.粘貼下邊的代碼vue模板 (如果使用css預編譯,則style的類型是scss,如不使用改為css)

{ "Print to console": { "prefix": "vue", "body": [ "<!-- $1 -->", "<template>", "<div class='$2'>$5</div>", "</template>", "", "<script>", "//這里可以導入其他文件(比如:組件,工具js,第三方插件js,json文件,圖片文件等等)", "//例如:import 《組件名稱》 from '《組件路徑》';", "", "export default {", "//import引入的組件需要注入到對象中才能使用", "components: {},", "data() {", "//這里存放數據", "return {", "", "};", "},", "//監聽屬性 類似於data概念", "computed: {},", "//監控data中的數據變化", "watch: {},", "//方法集合", "methods: {", "", "},", "//生命周期 - 創建完成(可以訪問當前this實例)", "created() {", "", "},", "//生命周期 - 掛載完成(可以訪問DOM元素)", "mounted() {", "", "},", "beforeCreate() {}, //生命周期 - 創建之前", "beforeMount() {}, //生命周期 - 掛載之前", "beforeUpdate() {}, //生命周期 - 更新之前", "updated() {}, //生命周期 - 更新之后", "beforeDestroy() {}, //生命周期 - 銷毀之前", "destroyed() {}, //生命周期 - 銷毀完成", "activated() {}, //如果頁面有keep-alive緩存功能,這個函數會觸發", "}", "</script>", "<style lang='scss' scoped>", "//@import url($3); 引入公共css類", "$4", "</style>" ], "description": "Log output to console" } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

6.上面代碼中的 “prefix”: “vue”, 就是快捷鍵;保存好之后新建.vue結尾的文件試試(輸入vue 按tab鍵就可以)

在這里插入圖片描述
四、vue路由
1.定義組件,剛剛已經用模板定義了一個組件
2.在router index.js文件里引入剛剛寫好的組件
在這里插入圖片描述
我在這里是用的vue-router提供的按模塊加載方式
下面2行代碼,沒有指定webpackChunkName,每個組件打包成一個js文件。

const ImportFuncDemo1 = () => import('../components/ImportFuncDemo1')
const ImportFuncDemo2 = () => import('../components/ImportFuncDemo2')
  • 1
  • 2

下面2行代碼,指定了相同的webpackChunkName,會合並打包成一個js文件。

// const ImportFuncDemo = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '../components/ImportFuncDemo')
// const ImportFuncDemo2 = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '../components/ImportFuncDemo2')
  • 1
  • 2

3.配置


import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter) // 按模塊加載... const HelloWorld= () => import('../components/HelloWorld') const routes=[{ path: '/', redirect: '/HelloWorld', name:'HelloWorld' },{ path:'/HelloWorld', component: HelloWorld, name:'HelloWorld' } ] const router = new VueRouter({ routes, mode: 'history', // vuex的嚴格模式 strict: process.env.NODE_ENV !== 'production', // 這個整體做的是:在路由的history模式下,一些列表頁利用緩存模式來記錄位置(一般是返回不刷新,前進刷新),一般用了scrollBehavior, //同時還用keep-alive(緩存),activated(緩存下觸發的鈎子)配合做列表頁的返回記錄位置。緩存模式也有坑,就是何時清除緩存,一般是從新進入頁面就清除。 //回到主題,滾動行為就是:例如一個列表頁,滑動了很多,點進去、再返回記錄剛剛的位置 scrollBehavior (to, from, savedPosition) { if (savedPosition) { return savedPosition } else { if (from.meta.keepAlive) { from.meta.savedPosition = document.body.scrollTop; } return { x: 0, y: to.meta.savedPosition ||0} } } }) export default router 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

4.路由文件注入到main.js文件中

import Vue from 'vue'; import router from './router/index'; import 'lib-flexible/flexible.js'; import App from './App' new Vue({ el: '#app', router, components: { App }, template: '<App/>' }) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

5.在 app.vue里配置router-view

<template> <div id="app"> <router-view></router-view> </div> </template> 
  • 1
  • 2
  • 3
  • 4
  • 5

6.路由跳轉及傳參方式

 1.$router為VueRouter實例,想要導航到不同URL,則使用$router.push方法
 2.$route為當前router跳轉對象,里面可以獲取name、path、query、params等


(1)設置動態路由
        {
    		path:'/shopDetails/:id',
   	 		component: shopDetails,
   			 name:'shopDetails'
         }
        跳轉this.$router.push('/shopDetails/'+id)
        獲取id通過   this.$route.params.id
       
(2)通過params攜帶參數 ,路由屬性中的name來匹配路由    
        
         {
    	 	path:'/shopDetails',
		   	 component: shopDetails,
		   	 name:'shopDetails'
         }
         跳轉 this.$router.push({name:'shopDetails',params:{id:id}})  
         獲取  this.$route.params.id
(3)通過path匹配路由,query攜帶參數 這種情況下 query傳遞的參數會顯示在url后面?id=?
         {
	    	 path:'/shopDetails',
		   	 component: shopDetails,
		   	 name:'shopDetails'
         }
         跳轉 this.$router.push({path:'/shopDetails',query:{id:id}})  
         獲取  this.$route.query.id
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

7.query和params的區別

1.動態路由和query屬性傳值 頁面刷新參數不會丟失, params會丟失 2.動態路由一般用來傳一個參數時居多(如詳情頁的id), query、params可以傳遞一個也可以傳遞多個參數 。
2.直白的來說query相當於get請求,頁面跳轉的時候,可以在地址欄看到請求參數,而params相當於post請求,參數不會再地址欄中顯示

8.路由的模式

五、axios請求

axios文檔上的教程在這里就不重復敘述了,需要的看文檔,我在這里貼下我的使用教程
axios文檔地址:https://www.npmjs.com/package/axios

1.安裝 npm install axios
2.在utils下新建一個axios文件用來配置axios

import axios from 'axios'; const qs = require('qs'); const service=axios.create({ baseURL: process.env.BASE_API, //請求公共地址,baseURL`將被添加到`url`,所以后邊請求只需api的方式即可 timeout: 5000, //請求響應時間 }) // 是否攜帶cookie信息,默認為false,根據項目需求設置 service.defaults.withCredentials = true; // 添加一個請求攔截器 service.interceptors.request.use(function (config) { // 對請求數據做些事 if(config.method === 'post'){ //post傳參序列化 config.data = qs.stringify(config.data); } return config; }, function (error) { return Promise.reject(error); }); // 添加一個響應攔截器 service.interceptors.response.use(function (response) { // 對響應數據做些事 return response; }, function (error) { console.log(error) // Do something with response error return Promise.reject(error); }); export default service; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

3.新建一個api文件,這里邊存放所有的請求函數,方便查找管理

import axios from '../utils/axios'; // 首頁banner export function banner(){ return axios({ url:'/wxchat/xxx.action', //請求的地址 method:'POST' }) } // post請求帶參數 export function qiang(activityStatusType){ return axios({ url:'/wxchat/xxx.action', method:'POST', data:{activityStatusType:activityStatusType} }) } // get請求 export function moneys(){ return axios({ url: '/sd-web/xxx', method: 'get' }); } // get請求帶參數 export function moneys(ids){ return axios({ url: '/sd-web/xxx', method: 'get', params:{id:ids} }); } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

4.頁面實際應用

 import {banner} from '../../api/api'; //在頁面上引入需要的請求函數 //在生命周期函數或者需要的方法里運用 mounted() { banner().then(response => { this.banner=response.data.data.SlAdvertisTabList }).catch(err=>{ console.log(err) }); }, 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

5.跨域配置

(1)在config文件夾寫的index.js里配置跨域
在這里插入圖片描述

proxyTable: { '/wxchat': { target: 'xxx', //目標接口域名 changeOrigin: true, //是否跨域 secure: false, //target默認情況下,不接受運行在HTTPS上,且使用了無效證書的后端服務器。如果你想要接受, 則需設置該項為false // pathRewrite: { // 如果接口本身沒有/wxchat需要通過pathRewrite來重寫了地址 重寫接口 // '^/wxchat: ' ' // } } }, 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

注:我寫的這個項目里,本身存在/wechat通用前綴,所以我沒有用pathRewrite重寫,如果你們接口里沒有通用前綴的話,是要進行重寫的

上面配置中,’^/wxchat’ 其實是一個正則表達式

‘^/wxchat’ 應該拆分成 ‘^’ 和 ‘/wxchat’ 兩個字符串,其中 ‘^’ 匹配的是字符串最開始的位置。

‘/wxchat’: {}, 就是告訴node, 我接口只要是’/wxchat’開頭的才用代理.所以你的接口就要這么寫/wxchat/xx/xx. 最后代理的路徑就是 http://xxx.xx.com/wxchat/xx/xx.
可是不對啊, 我正確的接口路徑里面沒有/wxchat啊. 所以就需要 pathRewrite,用’’^/wxchat’’:’’, 把’/wxchat’去掉, 這樣既能有正確標識, 又能在請求接口的時候去掉wxchat

接口沒有通用前綴的開發環境的配置

'use strict' const merge = require('webpack-merge') const prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"', BASE_API: '"/wechat"', //在跨域里配置的//wechat,接口里就不用寫通用前綴了,就按照正常接口寫就可以了 }) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

接口有通用前綴的開發環境配置

'use strict' const merge = require('webpack-merge') const prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"', BASE_API: '""', //這里為空就好了,通用前綴就寫在接口里 }) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

六、vuex的使用

關於vuex的使用 ,什么時候該使用vuex? 當你覺得需要全局的狀態,但是通過別的方式又太麻煩的時候,你就需要了,比如說我現在做的一個app項目,header組件是一個公共組件,那么header組件里邊的標題怎么能隨着頁面的跳轉而改變呢,vuex就可以做到 (個人理解,有不同理解的可以評論)
缺點:vuex頁面重新刷新,數據會丟失 解決方法:存本地,state數據可以從本地獲取

1.vuex中,有默認的五種基本的對象:

  • state 全局要訪問的值
  • getters 實時監聽state值的變化,對數據獲取之前的再次編譯,可以理解為state的計算屬性。
  • mutations 改變state里的初始值 同步的
  • actions 異步觸發mutations里面的方法
  • modules:store的子模塊,為了開發大型項目,方便狀態管理而使用的。這里我們就不解釋了,用起來和上面的一樣。

2.下載安裝vuex npm install vuex --save
3.在src下新建一個store文件夾創建一個index.js 用來配置.
4.引入vue,vuex,使用use全局注入插件

import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store=new Vuex.Store({ // 設置全局要訪問的state值 state:{ title:'測試標題', //頭部標題 } }) export default store; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

5.在main.js里引入store,並全局注入

import Vue from 'vue'; import router from './router/index'; import store from './store'; import 'lib-flexible/flexible.js'; import App from './App' new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' }) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

6.在任意組件內測試剛剛寫的標題

<template> <div class='orderDetails'> {{$store.state.title}} </div> </template> 
  • 1
  • 2
  • 3
  • 4
  • 5

7.如圖所示,剛剛的標題已經設置成功了
在這里插入圖片描述
8.上圖所示已經成功設置了標題,那怎么讓它的標題改變呢,就要用到mutations對象了,我們在mutations對象里定義一個改變標題的方法,mutations里面的參數,第一個默認為state,接下來的為自定義參數。

 // 改變state里的初始值 同步的 mutations :{ TITLE(state,title){ return state.title=title }, }, 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

9.看下測試結
在這里插入圖片描述在這里插入圖片描述
9.從圖上可以看出這個已經實現了,接下來看異步操作

 // 異步觸發mutations里面的方法 在外部組件里進行全局執行actions里面方法的時候,你只需要用執行this.$store.dispatch('title',132) 這樣就可以全局改變改變標題的值了 actions:{ title({commit},title){ commit('TITLE',title) }, } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

就不上圖了,跟之前同步操作是一樣的結果

10.vuex同步和異步的區別

1、當點發送過快,頁面中渲染的內容與state中的數據不一致,vuex里面的state變得慢,且不持續更新
2、action中是可以做到頁面中state中數據保持一致
3、當你的操作行為中含有異步操作,比如向后台發送請求獲取數據,就需要使用action的dispatch去完成了。其他使用commit即可。

七、打包上線
1.

執行  npm run build 命令
  • 1

2.執行完成后,你會發現你的目錄下多了一個dist的文件夾,這個就是打包的數據

3.打包之后出現頁面空白的原因
3.1 css,js路徑引用錯誤的問題

解決:到config文件夾中打開index.js文件。
文件里面有兩個assetsPublicPath屬性,更改第一個,也就是更改build里面的assetsPublicPath屬性:
assetsPublicPath屬性作用是指定編譯發布的根目錄,‘/’指的是項目的根目錄 ,’./’指的是當前目錄。
在這里插入圖片描述

3.2 設置路由history模式

解決:改為hash或者直接把模式配置刪除,讓它默認的就行 。如果非要使用history模式的話,需要你在服務端加一個覆蓋所有的情況的候選資源:如果URL匹配不到任何靜態資源,則應該返回一個index.html,這個頁面就是你app依賴頁面。

3.3 在css中引入的背景圖片的路徑問題

解決:到build文件夾中打開util.js文件,添加路徑代碼

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM