一、 js適配經驗:
我們在寫代碼的時候,很有可能寫到這種代碼:
[1,2,3,4,5].includes(1)
或者是使用promise
等es6的方法,但是我們的需求是在Android4.4上面完美運行。這樣就會出現includes is not undefied等錯誤提示。如果看了我之前談到webpack的文章就會疑問:我們之前不是用了babel插件用來轉成es5
了呢?我當時也疑問了好久,直到我在webpack裏面找到一個插件,具體的使用方法:
import "babel-polyfill"
import es6Promise from 'es6-promise'
es6Promise.polyfill()
require('es6-promise').polyfill()
// webpack配置文件處
entry: {
app: ['babel-polyfill', './src/main.js']
},
二、 全局定義
我們在寫代碼的時候,很有可能會封裝很多庫。如果存在有很多頁面都在使用該庫的情況,很可能會出現下面的代碼:
// vue 1
import utils from "library"
// vue 2
import utils from "library"
...
// vue n
import utils from "library"
就像我封裝的http方法一樣,我一般會這樣處理
import Vue from 'vue'
import http from "http/http"
Vue.prototype.$okhttp = http
// use
this.$okhttp
這樣會節省很多沒有必要的代碼量
三、 自定義目錄
在寫代碼的時候,很多時候都存在這種情況 :
import component1 from "../../../../component"
import component2 from "../../../../../component"
這種代碼是新手很可能出現的,如果一旦出現一個層級目錄出問題了,或者是文件的位置被轉移過了就會出問題。看過之前我寫的webpack文航的都會知道。
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: ['babel-polyfill', './src/main.js']
},
output: {},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
'components': resolve('src/components'),
'pages': resolve('src/pages')
}
},
module: {
},
node: {
},
plugins: [],
}
在resolve->alias裏面可以配置絕對相對路徑,在使用的時候
import component1 from "pages/component"
import component2 from "pages/component"
四、 路由懶加載
我看官方文檔裏面定義路由的時候都有兩步:
import Vue from 'vue'
import Router from 'vue-router'
import xxx from 'xxx'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
component: xxx,
}
]
})
這樣寫雖然沒有錯誤,但是我們在做大型項目的時候 很可能定義很多很多個路由,那樣頁面就會寫的特別多。此時懶加載就會解決這個問題
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
component: () => import("xxx")
}
]
})
當然這個也不是強制要求,個人推薦
五、 樣式污染和樣式覆蓋的問題
在我們新建vue的時候,經常會看到scoped
<style scoped>
</style>
如果我們去掉scoped的時候會發現,在本vue項目內定義的css屬性會影響到其他vue頁面的css屬性。這個就很坑了。所以,我們在使用的時候一定要用scoped
但是在實際的開發中,也會遇到這麼個問題。就拿我們項目來說,我用的是elementUI
,雖然裏面的資源庫很強大,但是裏面的視圖不能完全符合策劃的需求,此時就需要進行微調。
<style lang="stylus" scoped>
.custom-dialog
.el-dialog__header
padding 0
.el-dialog__body
padding 0
</style>
如果此時我們加上scoped標籤的話,我們發現並沒有效果,發現去掉scoped纔會起作用。
六、 mock、mock
很多情況下,後臺還沒有搭建完成之前。可能前端沒辦法進行數據的接入。這種情況可能是一個大問題,這樣會嚴重拖慢項目開發,此時就需要mock
首先在webpack.dev.conf.js
裏面配置express
,別問我爲什麼要在dev裏面配置
const express = require('express')
const app = express()
const appData = require('../static/data/user.json')
const apiRouter = express.Router()
app.use('/api',apiRouter)
然後將接口通過devServer發佈出去:
before(app) {
app.get('/api/user',(req, res) => {
res.json({
data: appData
})
})
}
使用的時候就直接打開http://localhost:8080/api/user
,就可以了。
六、 代理解決跨域
有些時候,在進行本地開發的時候,可能會遇到跨域的問題。爲了解決這個問題呢?主要有兩種方法:
1、 服務器設置
服務端設置很簡單,就是將本地開發的東西加上“Access-Control-Allow-Origin”, “*”,
或者是直接將本地開發的ip直接設置成白名單
,這樣就可以了.
2、 本地代理
首先引入
npm install http-proxy-middleware --save
然後在index.js的標籤下proxyTable使用
'/lesson': {
target: 'http://xxx/v2/webapi/lesson', // 代理的網址
changeOrigin: true, // 允許跨域
pathRewrite: {
'^/lesson': '/'
}
}
使用的時候,就直接使用
axios({
method: 'get',
url:'/lesson' ,
params: qs.stringify(data)
}).then(function (res) {
if (res) {
//...
}
});
}).catch(function (error) {
console.error(error);
})
七、 頁面統一判斷
在開發中經常會遇到權限判斷的問題,我們又不可能在每一個頁面的生命週期中去判斷一下,那樣太消耗時間了,我的處理:
router.beforeEach((to, from, next) => {
myAccess.checkhaveAccess(to.path) === true ? next() : next('/forbid')
})
八、 事件的傳遞:
一般來說事件的傳遞有很多種,比如父子之間傳遞數據就可以直接用props,和emit來做關聯。
父組件給子組件傳遞
// 父組件
<parent>
<child :datas="content"></child>
</parent>
data(){
return {
content:'sichaoyun'
};
}
// 子組件
props:["datas"];
// 或者是
props: {
datas: String
}
子組件給父組件傳遞
// 子組件
<template>
<div @click="open"></div>
</template>
methods: {
open() {
this.$emit('showbox','the msg'); //觸發showbox方法,'the msg'爲向父組件傳遞的數據
}
}
// 父組件
<child @showbox="toshow" :msg="msg"></child> //監聽子組件觸發的showbox事件,然後調用toshow方法
methods: {
toshow(msg) {
this.msg = msg;
}
}
兄弟組件之間的傳遞一般有幾種方式:
1、 註冊全局事件
2、 vuex
3、 localstorage
關於後面兩個,我會專門來講這個的,我主要是講全局事件吧,代碼如下:
let vm = new Vue(); //創建實例
<div @click="ge"></div>
methods: {
ge() {
vm.$emit('click',data); //觸發事件
}
}
<div></div>
created() {
vm.$on('click', (arg) => {
});
}
九、 列表渲染
v-for循環綁定model
:
這個是我在一個微信公衆號上面看到的寫法,很新穎:
// 數據
data() {
return{
obj: {
ob: "OB",
koro1: "Koro1"
},
model: {
ob: "默認ob",
koro1: "默認koro1"
}
}
},
// html模板
<div v-for="(value,key) in obj">
<input type="text" v-model="model[key]">
</div>
// input就跟數據綁定在一起了,那兩個默認數據也會在input中顯示
v-if儘量不要與v-for在同一節點使用:
v-for 的優先級比 v-if 更高,如果它們處於同一節點的話,那麼每一個循環都會運行一遍v-if。
如果你想根據循環中的每一項的數據來判斷是否渲染,那麼你這樣做是對的:
<li v-for="index in datas" v-if="Object.is(index,0)">
{{ index }}
</li>
如果你想要根據某些條件跳過循環,而又跟將要渲染的每一項數據沒有關係的話,你可以將v-if放在v-for的父節點:
// 根據elseData是否爲true 來判斷是否渲染,跟每個元素沒有關係
<ul v-if="condition">
<li v-for="index in datas">
{{ index }}
</li>
</ul>
// 數組是否有數據 跟每個元素沒有關係
<ul v-if="datas.length">
<li v-for="index in datas">
{{ index }}
</li>
</ul>
<p v-else>沒有更多數據</p>
十、 深度watch與watch立即觸發回調
這個是我偶爾在vuejs官網上面發現的,watch有兩個可選參數,但是好像版本有限制,具體請移步官方文檔。查看版本信息
選項:deep
在選項參數中指定 deep: true,可以監聽對象中屬性的變化。
選項:immediate
在選項參數中指定 immediate: true, 將立即以表達式的當前值觸發回調,也就是默認觸發一次。
十一、 路由的項目啓動頁和404頁面
export default new Router({
routes: [
{
path: '/', // 項目啓動頁
redirect:'/login' // 重定向到下方聲明的路由
},
{
path: '*', // 404 頁面
component: () => import('./notfind')
},
]
})
比如你的域名爲:www.baidu.com
項目啓動頁指的是: 當你進入www.baidu.com
,會自動跳轉到login登錄頁。
404頁面指的是: 當進入一個沒有 聲明/沒有匹配 的路由頁面時就會跳轉到404頁面。
比如進入www.baidu.com/testRouter,
就會自動跳轉到notFind頁面。
當你沒有聲明一個404頁面,進入www.baidu.com/testRouter
,顯示的頁面是一片空白。
說在最後
這篇文章了寫了好久了,我已經不知道當初想要寫什麼了。我早上快下班的時候,隨手修改了一下,但是上面的內容確實是我在項目裏面經常會用到的一些小技巧。可能有些瑕疵。但是或多或少也是總結了我一些經驗的。