vue常用技巧
配置開發環境
"scripts": {
"serve": "vue-cli-service serve --mode development",
"serve:test": "vue-cli-service serve --mode test",
"serve:pre": "vue-cli-service serve --mode preproduction",
"build": "vue-cli-service build --mode production",
},
vue-cli-service serve
命令會啟動一個開發伺服器, --mode
development
, test
和 production
在根目錄建立個.env.xx
的配置檔案
NODE_ENV ='development' VUE_APP_URL=http://192.168.203.173:9120 //問答api地址 VUE_APP_WEB_URL=http://192.168.203.173:8082 //測評小程式後臺 api地址 VUE_APP_CP_URL=http://192.168.203.173:8380 //保費試算 登入地址 VUE_APP_LOGIN=http://192.168.203.173:8082/user/authLogin 返回地址 VUE_APP_CALLBACK=http://192.168.203.43:8085/main
專案中通過process.env.xxx
來使用比如:process.env.VUE_APP_URL
require.context()
如果頁面需要匯入多個元件,原始寫法
import one from '@/components/one '
import two from '@/components/two'
import three from '@/components/three'
...
components:{one,two,three, ...}
這樣寫了很多重複程式碼。利用require.context
可以寫成
const path = require('path') const filre = require.context('@/components',true /\.vue$/) const moudles = {} filre.keys().map( key => { const name = path.basename(key,'.vue') moudles[name] = filre(key).default||filre(key) }) components: moudles
這樣不管頁面引入多少元件,都可以使用這個方法
require.context
這是個webpack
的方法,vue
工程一般基於webpack
require.context(directory,useSubdirectories,regExp)
directory
要檢索的目錄
useSubdirectories
是否檢索子目錄
regExp
匹配檔案的正則表示式,一般是檔名
watch
可以直接利用watch
的immediate
和handler
栗子
watch:{
value:{
handler: function(){
},
immediate: true
}
},
- 深度監聽
data () {
return {
value:{
name:'xx',
has:{
car:'xx'
},
}
}
},
watch:{
value:{
handler: function(){
},
deep: true
}
},
常見的元件通訊
props
值可以是陣列或物件
//陣列:不推薦使用
props:[]
//物件
props:{
inputVal:{
type: String,//傳入值限定型別
required: true,//是否必填
default: 'a',//預設值 物件或陣列預設值必須從一個工廠函式獲取如 default:()=>[]
validator:(value)=>{
// 這個值必須匹配下列字串中的一個
return ['a','b','c'].includes(value)
}
}
}
- $emit
非常常見,觸發子元件觸發父元件給自己繫結的事件,其實就是子傳父的方法
// 父元件 <home @title="title"> // 子元件 this.$emit('title',[{title:'這是title'}])
- vuex
一個狀態管理器
適合資料共享多的專案裡面,因為如果只是簡單的通訊,使用起來會比較重
state //定義存貯資料的倉庫 ,可通過this.$store.state 或mapState訪問
getter //獲取 store 值,可認為是store的計算屬性,可通過this.$store.getter 或mapGetters訪問
mutation //同步改變 store 值,為什麼會設計成同步,因為mutation是直接改變 store 值,vue 對操作進行了記錄,如果是非同步無法追蹤改變.可通過mapMutations呼叫
action //非同步呼叫函式執行mutation,進而改變store值,可通過this.$dispatch或mapActions訪問
modules:模組,如果狀態過多,可以拆分成模組
- attrs 和 listeners
attrs
:如果父傳子有很多值,那麼在子元件要定義很多props,attrs
就是獲取在子元件未定義的props,栗子
// 父元件 <chlidren title="這是標題" width="80" height="80" /> // 子元件 mounted() { console.log(this.$attrs) //{title: "這是標題", width: "80", height: "80"} }, //如果子元件定義了props,則剔除定義的屬性 // 父元件 <chlidren title="這是標題" width="80" height="80" /> // 子元件 props: { title: { type: String, default: '' } } mounted() { console.log(this.$attrs) //{ width: "80", height: "80"} },
listeners
當子元件需要呼叫父元件的方法時,父元件可以通過v-on='listeners'
傳入元件內部
// 父元件 <chlidren @getList="getList" /> // 子元件 mounted() { this.$listeners.getList //呼叫父元件裡面的getList方法 },
parent
和children
//父元件 mounted(){ console.log(this.$children) //可以拿到 一級子元件的屬性和方法 //所以就可以直接改變 data,或者呼叫 methods 方法 } //子元件 mounted(){ console.log(this.$parent) //可以拿到 parent 的屬性和方法 }
$refs
// 父元件 <chlidren ref="chlidren"/> mounted(){ console.log(this.$refs.chlidren) //可以拿到子元件的例項,就可以直接操作 data 和 methods }
Vue.nextTick
在下次 DOM 更新迴圈結束之後執行延遲迴調。在修改資料之後立即使用這個方法,獲取更新後的 DOM。
<button @click="testClick()" ref="button">{{testMsg}}</button> methods:{ testClick:function(){ this.testMsg="修改後的值"; console.log(this.$refs.button.innerText); //this.$refs.button,輸出:原始值 } } methods:{ testClick:function(){ let that=this; this.testMsg="修改後的值"; this.$nextTick(()=>{ console.log(this.$refs.button.innerText); //輸出:修改後的值 }); } }
directive
官方給我們提供了很多指令,但是我們如果想將文字變成指定的顏色定義成指令使用,這個時候就需要用到Vue.directive
// 全域性定義 Vue.directive("change-color",function(el,binding,vnode){ el.style["color"]= binding.value; }) // 使用 <template> <div v-change-color="color">{{message}}</div> </template> <script> export default{ data(){ return{ color:'green' } } } </script> // el : 指令所繫結的元素,可以用來直接操作DOM // binding: 一個物件,包含指令的很多資訊 // vnode: VUE編譯生成的虛擬節點
Vue.filter
過濾器,比如時間戳轉時間格式
// 用法
{{xxxx| time}}
// 全域性註冊
Vue.filter('time', (value) =>{
// 處理邏輯
})
//區域性處理
filters: {
time: (value)=> {
// 處理邏輯
}
}
v-pre
不編譯,原樣輸出
<span v-pre>{{msg}}</span> //{{msg}} // 即使data裡定義了msg這裡仍然是顯示的{{msg}}
v-cloak
解決頁面載入閃爍問題
v-once
只渲染一次
有些 template 中的靜態 dom 沒有改變,這時就只需要渲染一次,可以降低效能開銷
事件修飾符
.stop //阻止冒泡
.prevent //阻止預設行為
.self //僅繫結元素自身觸發
.once //只觸發一次
.passive // 滾動事件的預設行為(即滾動行為)將會立即觸發,不能和.prevent 一起使用
路由
- 快取
keep-alive
<transition name="fade" mode="out-in"> <keep-alive> <router-view v-if="$route.meta.keepAlive" /> </keep-alive> </transition> <transition name="fade" mode="out-in" > <router-view v-if="!$route.meta.keepAlive"/> </transition>
keep-alive
的生命週期初次進入時:
created
> mounted
> activated
;退出後觸發deactivated
再次進入:會觸發
activated
;事件掛載的方法等,只執行一次的放在mounted
中;元件每次進去執行的方法放在 activated
中
- 路由鉤子
router.beforeEach
router.beforeEach((to, from, next) => {
//一般登入攔截用這個,也叫導航鉤子守衛
routers.beforeEach((to, from, next) => {
const { isLogin } = store.state
if (to.name === 'login' || isLogin) {
next()
} else {
routers.push({ name: 'login' })
}
})
Vue.$router
this.$router.push() //跳轉到不同的url,但這個方法迴向history棧新增一個記錄,點選後退會返回到上一個頁面
this.$router.replace()//不會有記錄
this.$router.go(n)//n可為正數可為負數。正數返回上一個頁面,類似 window.history.go(n)
router-view
的key
由於 Vue
會複用相同元件, 即 /page/1 => /page/2 或者 /page?id=1 => /page?id=2 這類連結跳轉時, 將不在執行created
,mounted
之類的鉤子
<router-view :key="$route.fullpath"></router-view> //這樣元件的 created 和 mounted 就都會執行