名稱 | 內容 |
---|---|
$data | 傳入的data內容,修改可引發頁面內容變化 |
$props | 父組件傳入子組件 |
$el | 綁定的html的節點 |
$options | 新建Vue實例對象時穿進去的內容,修改optins的內容不會引發頁面變化,有render方法,在頁面從新渲染時會調用 |
$root | 整個Vue對象的根節點,app.$root === app |
$children | 組件內部的元素 |
$slots | 插槽 |
$scopedSlots | 區域化插槽 |
$refs | 模板的引用 |
$isServer | 服務端渲染時能夠用來判斷 |
$watch | 監聽內容,與寫在實例中效果相同,但經過$watch寫的監聽要返回的unWatch方法結束監聽 |
$on | 監聽事件是否被觸發,能夠獲取emit傳遞的參數 |
$emit | 觸發事件,監聽哪一個對象就要經過哪一個事件觸發,能夠傳值 |
$once | 與on類似,但只被觸發一次 |
$forceUpdate | 強制組件從新渲染 |
$set | 給新值賦值而且頁面會渲染 |
$delete | 刪除值 |
$nextTick | 異步操做 |
生命週期 | 介紹 | 可調用次數 |
---|---|---|
beforeCreate | 還未綁定Dom,不能進行dom操做**(不要放入ajax請求)** | |
created | 還未綁定Dom,不能進行dom操做 | |
beforeMount | el只爲html中寫的節點,還未綁定,說明還未渲染(未調用render方法) | |
mounted | el綁定爲渲染後的節點,說明以前進行了渲染(已調用render方法),實例已經建立完成 | |
beforeUpdate | 更新的對象時模板,須要虛擬DOM的重洗渲染和補丁修改,可是若是更改的數據在模板中沒有使用,就不會進行更新 | |
updated | 數據更改致使虛擬DOM從新渲染和打補丁,注意要避免在這個鉤子函數中操做數據 | |
activated | ||
deactivated | ||
beforeDestory | 實例銷燬以前調用。在這一步,實例仍然徹底可用,this仍能獲取到實例。通常在這一步中進行:銷燬定時器、解綁全局事件、銷燬插件對象等操做 | |
destoryed | Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬 |
指令名 | 指令做用 |
---|---|
v-text | 標籤裏面要顯示的文本內容,內容較多時不建議使用 |
v-html | 將html代碼片斷展現爲html標籤 |
v-show | 根據內容的Boolean值來顯示或不顯示內容,原理是設置display:none; |
v-if | 與v-show不一樣的是若是判斷爲false將不會放在文檔流裏,若是頻繁切換會動態增刪節點,會形成性能問題 搭配指令有 v-else v-else-if |
v-for | 循環,用法爲 v-for="item in arr",item爲數組內的值或對象,arr爲儲存值的數組,若是要拿到順序則寫爲v-for="(item, index) in arr" 遍歷對象可用 v-for="(val, key,index) in obj"的方式,val爲值,key爲對應的鍵,index爲對應的索引值即順序,使用v-for時須要:key=""來綁定一個惟一識別 |
v-on | 監聽事件,能夠監聽到$emit觸發的事件 |
v-model | 雙向綁定數據,可進行實時更改,通常用於input,通常輸入以後會變爲字符串 |
若是想讓值爲數字,在v-model後加.number修飾符 | |
若是想去掉首位的空格,在v-model後加.trim修飾符 | |
若是不想實時更改,而是失焦後更改,在v-model後加.lazy修飾符 | |
v-pre | 不解析內部內容,即內部內容保留源格式 |
v-cloak | 通常直接在頁面引入vue.js代碼時使用,在vue代碼完成以前讓內容隱藏,vue加載完成後再展現 |
v-once | 數據綁定內容只執行一次,通常爲靜態內容使用,節省性能開銷,不會作虛擬DOM對比 |
首先寫一個組件內容javascript
const component = {
templete: '<div>This is compoent</div>'
}
複製代碼
而後咱們用Vue實例的方法引入組件html
import Vue from 'vue'
Vue.component('ComponentName',component); //定義了一個名爲name的組件
//組件名用大寫開頭並用駝峯命名 (類的思想)
複製代碼
使用時:前端
第一種狀況-直接在tempelate內使用:vue
new Vue({
el:'#root',
tempelate:'<component-name></component-name>' //使用時使用小寫,而且單詞之間用-鏈接
})
複製代碼
第二種狀況-從新命名使用:java
new Vue({
el:'#root',
tempelate:'<new-name-component></new-name-component>',
//使用時使用小寫,而且單詞之間用-鏈接
components: {
newNameComponent: component
}
})
複製代碼
const component = {
templete: '<div>{{text}}</div>',
data(){ //必需要使用函數返回值的方式
return{
text:'hello'
}
}
}
複製代碼
使用一個return新對象的方法能夠防止多個組件動態綁定至一個相同的值,例如v-model的場景就會出現相關的問題webpack
const component = {
templete: ` <div> <span v-show="active">see me if active</span> <span>{{propOne}}</span> //prop與data類似都是綁定在this上,能夠直接使用 </div> `
data(){ //必需要使用函數返回值的方式
return{
text:'hello'
}
},
props: {
active: Boolean,//向組件傳遞一個布爾值,key爲active
propOne: String //駝峯式命名
}
}
複製代碼
使用時web
new Vue({
el:'#root',
tempelate:` <new-component :active="true" prop-one="123"></new-component> //須要用v-bind解析傳入的值 <new-component :active="false" prop-one="456"></new-component> //在prop中爲駝峯式的命名在使用時使用小寫而且用-鏈接的方式(非強制,只是規範) `,
//使用時使用小寫,而且單詞之間用-鏈接
components: {
NewComponent: component
}
})
複製代碼
props數據的一些設置ajax
const component = {
props: {
active: {
type: Boolean, //設置爲布爾值
required: true, //這個屬性爲必需屬性
default: true, //設置默認值爲true,若是有了default就不須要required
validator (value) { //可用來檢測輸入的值是否符合要求,可用來自定義檢測
return typeof value === 'Boolean'
}
},
propOne: {
type: Object,
default() { //若是默認值爲一個對象,則應該用函數返回一個對象的形式
return {
}
}
}
},
.....
}
複製代碼
當咱們新建一個Vue實例時,它內部都是一些默認的屬性,若是咱們想使用咱們已經定義過的組件的一些屬性內容咱們能夠用下列代碼:vue-router
... 已建立組件component
const ComponentVue = Vue.extend(component); //前提是component沒有required爲true的props
new ComponentVue({
el: '#root',
})
複製代碼
但若是咱們須要用到props呢?vuex
咱們能夠用下面的方式:
... 已建立組件component
const ComponentVue = Vue.extend(component);
new ComponentVue({
el: '#root',
propsData: { //用propsdata來向原組件的props傳值才能使用
propOne: 'xxx',
}
})
複製代碼
會先執行原組件的mounted,再執行extend實例的mountend
const component = {
props: ['value'],
template: ` <div> <input type="text" @input="handleInput" v-model="value" > </div> `,
methods: {
handleInput(e) {
this.$emit('input', e.target.value); //向父組件觸發input事件
}
}
}
//在Vue實例中
new Vue({
components: {
CompOne: component
},
el: '#root',
data () {
return {
value: '123'
}
}
template: ` <div> <comp-one :value="value" @input="value = arguments[0]"></comp-one> //arguments數組即爲經過$emit後面傳遞的參數 </div> `
})
複製代碼
咱們還能夠經過下面的功能實現
const component = {
model: {
prop: 'value1', //爲要傳的值
event: 'change' //爲觸發的事件
},
props: ['value1'],
template: ` <div> <input type="text" @input="handleInput" v-model="value1"> </div> `,
methods: {
handleInput(e) {
this.$emit('input', e.target.value); //向父組件觸發input事件
}
}
}
//在Vue實例中
new Vue({
components: {
CompOne: component
},
el: '#root',
data () {
return {
value: '123'
}
}
template: ` <div> <comp-one v-model="value"></comp-one> //arguments數組即爲經過$emit後面傳遞的參數 </div> `
})
複製代碼
當咱們在Vue實例調用的組件內部直接寫入html元素時,它是不會顯示的,由於咱們沒有告訴組件要放在哪裏顯示,這時就須要 插槽 了
//組件內
const component = {
template: ` <div> <slot></slot> //爲內容添加插槽位置,沒有聲明插槽位置的元素都會放在這個裏面 </div> `
}
//實例中
new Vue({
components: {
CompOne: component
},
el: '#root',
template: ` <div> <comp-one> <span>我會被放在slot中</soan> </comp-one> </div> `
})
複製代碼
具名插槽
//組件內
const component = {
template: ` <div> <div class="header"> <slot name="header"></slot> </div> <div class="body"> <slot name="body"></slot> </div> </div> `
}
//實例中
new Vue({
components: {
CompOne: component
},
el: '#root',
template: ` <div> <comp-one> <span slot="header">我會被放在slot name爲header的插槽中</soan> <span slot="body">我會被放在slot name爲body的插槽中</soan> </comp-one> </div> `
})
複製代碼
做用域插槽 讓插槽內綁定的數據爲組件的數據
使用方法爲:
//組件內
template: ` <div> <slot value="456" anothervalue="content"></slot> </div> `
//實例中
template:` <div> <comp-one><span slot-scope="props">{{props.value}} {{props.anothervalue}}</span></comp-one> //slot-scope 的對象即爲組件內slot傳遞值的對象 </div> `
複製代碼
或者可使用組件內部data的值,它並不影響本地data的使用:
//組件內
template: ` <div> <slot :value="value" anothervalue="content"></slot> //注意要使用v-bind形式 </div> `,
data() {
return{
value="this is data value"
}
}
//實例中
template:` <div> <comp-one><span slot-scope="props">{{props.value}} {{props.anothervalue}}</span></comp-one> //slot-scope 的對象即爲組件內slot傳遞值的對象 </div> `
複製代碼
如何越級拿到vue組件實例呢?
使用 provide屬性!
//子組件
const ChildComponent = {
template: '<div>child component</div>',
inject: ['grandfather'] //獲取實例向外提供的對象
}
//組件
const component = {
name: 'comp',
component: {
ChildComponent //聲明子組件
},
template: ` <div> <child-component /> //若是爲空組件能夠這樣書寫 </div> `,
}
//實例
new Vue({
components: {
CompOne: component
},
provide (){
return{
grandfather: this //將本身這個實例做爲對象向外提供,僅爲節點下的節點(子節點 & 子節點的子節點 $ ......)
} //使用函數返回值的方式的緣由與data相同
},
...
})
複製代碼
但通常provide只提供一次值,不會實現model模式,若要實現須要給provide的值提供得到方法,方法以下:
provide (){
return{
const data = {} //先設置一個空對象
Object.defineProperty(data,'value',{
get: () => this.value, //沒次使用值時實際上是用了這個get方法
enumerable: true //可讀屬性
})
}
}
複製代碼
這種方法雖然是實現了跨級model,但屬於一種hack方法,官方不建議使用。
render方法是咱們渲染的一個方法,它內部會返回一個createElement方法,這個方法是Vue給咱們提供的建立節點的方法,使用render方法咱們就能夠不使用template
//組件
const component = {
name: 'comp',
props: ['props1'],
render (createElement) {
return createElement('div', {
//data數據 data: this.data形式
},[ //注意要傳遞數組
this.$slots.default //無名爲default,具名slot將default改成名字便可
this.props1 //傳遞prop值
])
}
}
//實例
new Vue({
components: {
CompOne: component
},
render( createElement ) { //不必定爲createElement,能夠用其餘字母表示,但下面的方法名要保持一致
return createElement(
'comp-one',{
ref: 'comp'
},[ //注意節點內在建立節點要傳遞一個數組
createElement(
'span',{
ref: 'span',
slot: 'header' //能夠指定要渲染的slot插槽位置
},this.value)
]) //Vue提供的建立節點的函數
}
})
複製代碼
on形式的監聽,須要實例和組建中都使用on
//組件
const component = {
name: 'comp',
props: ['props1'],
render (createElement) {
return createElement('div', {
on: {
click: () => {this.$emit('click')} //監聽click事件,向父級觸發click事件
}
},[ //注意要傳遞數組
this.$slots.default //無名爲default,具名slot將default改成名字便可
this.props1 //傳遞prop值
])
}
}
//實例
new Vue({
components: {
CompOne: component
},
render( createElement ) { //不必定爲createElement,能夠用其餘字母表示,但下面的方法名要保持一致
return createElement(
'comp-one',{
ref: 'comp',
on: {
click: this.handleClick //點擊組件會受到組件傳遞的click事件,並觸發handleClick方法
}
},[ //注意節點內在建立節點要傳遞一個數組
createElement(
'span',{
ref: 'span'
},this.value)
]) //Vue提供的建立節點的函數
},
methods: {
handleClick() {
//do something....
}
})
複製代碼
nativeOn 有個很大的便捷,那就是咱們只須要在實例中聲明而組件中能夠不用聲明
//組件
const component = {
name: 'comp',
props: ['props1'],
render (createElement) {
return createElement('div', {
},[ //注意要傳遞數組
this.$slots.default //無名爲default,具名slot將default改成名字便可
this.props1 //傳遞prop值
])
}
}
//實例
new Vue({
components: {
CompOne: component
},
render( createElement ) { //不必定爲createElement,能夠用其餘字母表示,但下面的方法名要保持一致
return createElement(
'comp-one',{
ref: 'comp',
nativeOn: {
click: this.handleClick //nativeOn會自動綁定到組件根節點的dom上面
}
},[ //注意節點內在建立節點要傳遞一個數組
createElement(
'span',{
ref: 'span'
},this.value)
]) //Vue提供的建立節點的函數
},
methods: {
handleClick() {
//do something....
}
})
複製代碼
template實際上是render方法的一種編譯方式
router,顧名思義即爲路由,vue框架可讓咱們在前端實現路由功能,這個功能對WebApp這種應用來講是必不可少的。
使用路由以前須要先安裝模塊,npm install vue-router
通常咱們將路由分爲兩個文件,router.js 和 routes.js,一個用來存放路由信息,另外一個用來寫路由邏輯功能
//routes.js
import Todo from '../views/todo/todo.vue' //引入要展現的頁面
import Login from '../views/login/login.vue'
export default [
{
path: '/', //網頁的路徑
component: Todo //指定輸入上方路徑後顯示什麼頁面
},
{
path: '/login',
compoent: Login
}
]
複製代碼
//router.js
import Router from 'vue-router' //引入vue-router模塊
import routes from './routes' //引入咱們寫的路由信息
//每次引入路由文件時會返回一個路由對象
export default () => {
return new Router({
routes
})
}
複製代碼
爲了實現跳轉,咱們還須要用router-view來實現對路由跳轉事後的展現
// app.vue
<template>
<div id="app">
<div id="cover"></div>
<Header></Header>
<router-view></router-view> //這部分來進行跳轉,頁面內容展現在這部分
<!-- <todo></todo> -->
<Footer></Footer>
</div>
</template>
複製代碼
咱們也能夠用路由來實現首頁重定向,在routes.js寫入這部份內容
//routes.js
import Todo from '../views/todo/todo.vue' //引入要展現的頁面
import Login from '../views/login/login.vue'
export default [
{
path: '/',
redirect: '/app' //當輸入默認路徑時重定向到app頁面
},
{
path: '/app', //網頁的路徑
component: Todo //指定輸入上方路徑後顯示什麼頁面
},
{
path: '/login',
compoent: Login
}
]
複製代碼
此時咱們會注意到網頁上的url是 http://localhost:8080/#/app,他默認會傳一個hash,咱們能夠更改這個東西須要更改router.js的內容
import Router from 'vue-router' //引入vue-router模塊
import routes from './routes' //引入咱們寫的路由信息
//每次引入路由文件時會返回一個路由對象
export default () => {
return new Router({
routes,
mode:'history' //mode改成 'hash'即爲hash方式
})
}
複製代碼
此時在此運行我就能夠發現那個#消失了
咱們還能夠經過base屬性設計基路徑
import Router from 'vue-router' //引入vue-router模塊
import routes from './routes' //引入咱們寫的路由信息
//每次引入路由文件時會返回一個路由對象
export default () => {
return new Router({
routes,
mode:'history',
base: '/base/' //設置基路徑爲base,經過vue-router的跳轉都會加入基路徑
})
}
複製代碼
此時咱們再訪問localhost:8080發現他的路徑跳轉爲了
localhost:8080/base/app
但基路徑並非強制的,咱們把base去掉訪問依然能夠訪問到app
還有兩個屬性使咱們要配合router-link使用的
//app.vue
<template>
<div id="app">
<div id="cover"></div>
<Header></Header>
<router-link to="/app">app</router-link>
<router-link to="/login">login</router-link>
<router-view></router-view>
<!-- <todo></todo> -->
<Footer></Footer>
</div>
</template>
複製代碼
咱們在app.vue中加入兩個router-link(與a標籤相似,原理是經過a標籤實現的),to的內容即爲他們要跳轉的路由,而後咱們能夠全局設置連接的樣式
export default () => {
return new Router({
routes,
mode:'history',
linkActuveCLass:'active-link', //只要有一部分被激活會加上
linkExactActiveClass: 'exact-active-link' //當前路徑徹底匹配才加上
})
}
複製代碼
可能會有點難理解,那咱們這樣想,你當前有一個/app的頁面,展現的是app.vue,而後app下面有個子頁面是childApp.vue,路徑是/app/childApp,當咱們在localhost:8080/app/childApp的路徑下時,此時routerlink to 爲childApp的連接的樣式爲'active-link' 和'exact-active-link',而app的routerlink的樣式爲'active-link' 而不會有'exact-active-link'
咱們把路徑輸入url時,按下回車,會想服務器發送一個請求,若是此時咱們沒有在服務器中,添加路由映射時,瀏覽器會返回咱們一個錯誤信息
Cannot GET /xxx //xxx即爲url的內容
//webpack.config.client.js
const devServer = {
port: 8000,
host: '0.0.0.0',
overlay: {
errors: true,
},
historyApiFallback: {
index: 'index.html' //加上這個咱們輸入url後刷新頁面仍是會顯示出內容
},
hot: true
}
複製代碼
咱們有時在跳轉頁面時,不想回到上一級時已經返回到了頂部而不是跳轉以前的位置,咱們能夠在Router裏設置一個scrollBehavior
export default () => {
return new Router({
routes,
mode:'history',
scrollBehavior (to, from, savedPosition){ //to -> 跳轉的路由 from -> 當前的路由即跳轉的起始點 savedPosition -> 保存當前滾動條滾動的位置
if(savedPosition) { //若是是有滾動距離的,返回到以前的頁面位置
return savedPosition
} else { //不然,返回頂部
return {x:0 , y:0}
}
}
})
}
複製代碼
這部分主要講路由方面的參數
import Todo from '../views/todo/todo.vue'
import Login from '../views/login/login.vue'
export default [
{
path: '/',
redirect: '/app' //當輸入默認路徑時重定向到app頁面
},
{
path: '/app',
component: Todo,
name: 'app' //給當前的路由設置一個姓名,能夠用來跳轉,與路徑和組件名無強制聯繫
},
{
path: '/login',
compoent: Login
}
]
複製代碼
而後在routerlink上能夠進行經過name跳轉
<router-link :to="{name:'app'}"> </router-link> //傳入對象,讓Vue來解析它
複製代碼
以後就能夠進行跳轉了,沒必要每次都要寫路徑
用來存放一些元信息
import Todo from '../views/todo/todo.vue'
import Login from '../views/login/login.vue'
export default [
{
path: '/',
redirect: '/app' //當輸入默認路徑時重定向到app頁面
},
{
path: '/app',
component: Todo,
meta: {
title:'this is app', //與html的meta一樣的效果
description: 'author Reaper Lee'
}
},
{
path: '/login',
compoent: Login
}
]
複製代碼
用來寫當前路徑下的子組件
import Todo from '../views/todo/todo.vue'
import Login from '../views/login/login.vue'
export default [
{
path: '/app',
component: Todo,
children: [ //注意是數組
{
path: 'child', //路徑信息,與父級相同
component: Child
}
]
}
]
複製代碼
但注意這個只會在 父組件即(Todo)下的routerview展現,不會和Todo搶佔同一個routerview
transition顧名思義就是路由的過分,即爲一次過渡動畫,咱們使用時要配合routerview使用
//app.vue
<template>
<div id="app">
<router-link to="/app">app</router-link>
<router-link to="/login">login</router-link>
<transition name="fade"> //使用fade的動畫做爲過渡
<router-view></router-view>
</transition>
</div>
</template>
<style> //定義這個fade動畫 .fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter, .fade-leave-to { opacity: 0; } </style>
複製代碼
咱們能夠經過路由傳遞一些參數,這個會在咱們好比查看一個物品的詳情頁等場景使用會比較多。具體方法以下
// routes.js
export default [
{
path: '/app/:id', //這裏咱們就聲明瞭一個路由上的參數
component: Todo,
}
]
複製代碼
此時咱們直接訪問/app 是不會有內容的
但當咱們訪問/app/xxxx (xxxx爲要傳遞的參數),此時咱們就能夠正常的顯示頁面,咱們獲取這個參數能夠在父組件中使用this.$route來獲取參數
this.$router.params.id 就能夠拿到路徑中的參數了,id是咱們在上面的path中給的參數名爲id,要與參數名保持一致
複製代碼
還有一種更強大的方法,那就是把路徑中的參數做爲組件的props傳遞給組件
// routes.js
export default [
{
path: '/app/:id', //這裏咱們就聲明瞭一個路由上的參數
props:true, //這裏咱們設置爲true便可讓參數做爲props傳遞給組件
component: Todo
}
]
複製代碼
而後在組件中咱們須要把參數的props聲明
//todo.vue
export default {
props: ['id'] //聲明一個名爲 id 的props數據
}
複製代碼
而後咱們就能夠在組件中拿到這個參數了!並且經過props傳遞的參數咱們能夠更好的使用,因此若是真的須要經過路徑傳參數咱們儘量使用props。
咱們有時會碰見在主頁要使用多個router-view來展現組件的狀況,此時咱們須要給一些router-view提供name屬性
//app.vue
<template>
<div id="app">
<router-link to="/app">app</router-link>
<router-link to="/login">login</router-link>
<router-view /> //內部不放內容能夠寫成空標籤形式
<router-view name="a" />
</div>
</template>
複製代碼
與此同時,咱們也要修改路由信息的JavaScript文件的一些內容
//routes.js
export default [
{
path: '/app/:id', //這裏咱們就聲明瞭一個路由上的參數
components:{ //注意由於要展現多個組件,因此咱們這裏定義爲components
default: App //在沒有給name屬性的router-view中展現的組件
a: Another //在name屬性爲a的router-view中展現
} ,
}
]
複製代碼
當咱們觸發一個導航時,全局前置守衛按照穿件的順序調用,守衛是異步執行的。咱們能夠經過守衛來進行一些攔截,好比只有登陸以後才能進入的一些頁面或者使用的一些功能。
函數名 | 做用 |
---|---|
beforeEach | 通常在這個守衛方法中進行全局攔截,好比必須知足某種條件(用戶登陸等)才能進入路由的狀況 |
beforeResolve | 和beforeEach相似,區別是在導航被確認以前,同時在全部組件內守衛和異步路由組件被解析以後,解析守衛就被調用 |
afterEach | 在全部路由跳轉結束的時候調用這些鉤子不會接受 next 函數也不會改變導航自己 |
beforeEnter | 可直接定義在路由配置上,和beforeEach方法參數、用法相同,調用位置在beforeEach 和 beforeResolve |
大致的用法以下
//index.js
import createRouter from './config/router' //先導入咱們寫的路由信息
const router = createRouter()
router.beforeEach((to, from, next) >= { //to -> 跳轉的路由 from -> 當前的路由即跳轉的起始點,next爲這次跳轉的函數,調用他才能執行跳轉
if(若是沒有登陸){
next('/login') //跳轉到登陸頁面
}else if(沒有註冊) {
next({path:'/register',replace:true}); //咱們也能夠傳遞一個對象,replace設置爲true就不會放在history的棧堆內
}
})
router.beforeResolve((to, from, next) >= {
//do something
next();
})
router.beforeEach((to, from) >= {
//do something
next();
})
複製代碼
在路由上設置beforeEnter
//router.js
export default [
{
path: '/app',
component: Todo,
name: 'app', // 給當前的路由設置一個姓名,能夠用來跳轉,與路徑和組件名無強制聯繫
meta: {
title: 'this is app', // 與html的meta一樣的效果
description: 'author Reaper Lee'
},
beforeEnter (to,from,next) { //只有在進入路由以前調用
//dosomething
}
}
]
複製代碼
函數名 | 做用 |
---|---|
beforeRouteEnter | 在渲染該組件的對應路由前調用,用法與參數和beforeEach相似, next須要被主動調用 ,此時實例並未被建立,不能使用this |
beforeRouteUpdate | 在當前路由改變,而且組件被複用時調用,此時實例已經建立,this能夠訪問實例,next須要被主動調用,不能傳回調 |
beforeRouteLeave | 導航離開該組件的對應路由時調用。能夠訪問組件實例this,next須要被主動調用,不能傳回調 |
//comp.vue
export default {
beforeRouteEnter (to, from, next) {
//在這裏咱們由於沒有實例,因此不能用this,但咱們要用獲取的參數,就在next裏使用回調函數
next( vm => {
//在這裏能夠拿到參數
})
},
beforeRouteUpdate (to,from, next){
next()
},
beforeRouteLeave (to, from, next){ //咱們能夠經過下面的代碼來實現退出時的提示確認
if(flobal.confirm('are you sure to leave?')){
next()
}
}
data() {
return {
}
}
}
複製代碼
咱們路由若是有很是多,一次性經過webpack把所有打包進去會致使js文件變得異常的大,而且初次加載的時間會變得很是長,顯然是不可取的。咱們可讓對應不一樣的路由只加載那一部分的組件的代碼。
使用這部分功能咱們須要安裝一個babel的插件
npm i babel-plugin-syntax-dynamic-import -D
以後在 .babelrc文件中咱們寫入
"plugins": [ "syntax-dynamic-import" ] 複製代碼
//routes.js
//注意咱們不在開頭import組件
export default [
{
path: '/app',
component:() => { import('組件的路徑')}, //注意要用一個函數
}
]
複製代碼
VueX 是基於Vue框架的一個狀態管理工具
官網的介紹是:
Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
npm install vuex -S
以後我麼你在項目的文件夾裏建一個新的文件夾爲stroe,並在內部建立stroe.js,他將做爲整個數據存儲的入口
//store.js
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
export default () => {
return new Vuex.store({
state:{ //儲存的對象
count: 0
},
mutations:{ //對state進行操做的方法
updateCount(state,num){ //第一個參數都爲state,第二個參數爲你能夠傳的參數
state.count = num;
}
}
})
}
複製代碼
咱們須要在index.js引入Vuex
//index.js
import Vuex from 'vuex'
import createStore from './store/store'
const store = createStore()
new Vue({
router,
store,
render: (h) => h(App)
}).$mount(root)
複製代碼
到這裏以後咱們就已經把Vuex引入了
//app.vue
<script>
export default {
components:{
},
mounted () {
this.$router //咱們就能夠經過this.$store拿到所需的數據
this.$store.commit('updateCount',參數) //咱們使用store的mutaitions時須要使用 commit方法,第一個參數
}
}
</script>
複製代碼
咱們能夠把state當作vue組件的data數據來使用
//state.js
export default {
}
複製代碼
咱們也要在store裏引入
//store.js
import defaultState from './state/state'
export default () => {
return new Vuex.Store({
state: defaultState,
mutations: {
updateCount(state,num){
state.count = num;
}
}
})
}
複製代碼
咱們也能夠把mutations也單獨寫個文件
//mutations.js
export default {
updateCount (state, num){
state.count = num;
}
}
//store.js
import Vuex from 'vuex'
import defaultState from './state/state'
import mutations from './mutations/mutations'
export default () => {
return new Vuex.Store({
state: defaultState,
mutations: mutations
})
}
複製代碼
咱們能夠把一些要直接在頁面用的數據放在getters,而後能夠直接方便使用
好比咱們在state.js裏寫入了咱們的名字信息
// state.js
export default {
count: 0,
firstName: 'Reaper',
lastName: 'Lee'
}
複製代碼
咱們在getters裏寫入獲取全名的方法
//getters.js
export default {
fullName (state) {
return `${state.firstName} ${state.lastName}`
}
}
複製代碼
而後咱們能夠經過Vuex提供的方法快速使用getters
//app.vue
<template>
<p>
{{fullName}}
</p>
</template>
<script>
export default {
computed: {
fullName () {
return this.$store.getters.fullName
}
}
}
</script>
複製代碼
咱們通常把修改state值的一些方法放在mutation中,而後在組件中經過調用修改state
注意,mutation 只能傳遞兩個參數,第一個是state對象,第二個是傳參的對象,單個參數能夠單獨放入,若是要傳遞多個參數,則要放在一個對象中
其實咱們在組件中能夠直接使用this.$store.state來進行修改,但這樣不夠規範,若是想防止這種狀況就在實例化時將strict屬性設置爲true
export default () => { return new Vuex.Store({ strict:true }) } 複製代碼
mutations只能同步操做,不能寫入異步的代碼,若是要執行異步操做,必需要寫入actions中
例如咱們要根據傳入的參數延時修改數據
//actions.js
export default {
updateCountAsync (store, data) {
setTimeout(() => {
store.commit('updateCount',data.num) //觸發mutations的修改事件
}, data.time)
}
}
複製代碼
咱們在vue文件中觸發actions的方法與mutations有所不一樣,觸發mutation使用commit,觸發action使用dispatch
//app.vue
export default {
...
mounted() {
this.$store.dispatch('updateCountAsync',{ num:5,time:2000})
}
}
複製代碼
咱們有時調用store要存在多種場景,須要劃分做用域,這時咱們就要使用到Vuex的模塊
//store.js
export default () => {
return new Vuex.Store({
modules: {
a: {
namespaced: true, //使用這個在不一樣的模塊中可使用相同命名的mutations
state: {
text :1
},
mutations: {
updateText(state,text){
state.text = text;
}
},
getters: {
textPlus(state,getters,rootState){ //第二個參數是getter方法,第三個參數是全局state
return state.text + 1
}
},
actions:{
add({state,commit,rootState}){
commit('updateText',rootState.count,{root:true}) //使用{root:true} 就可讓rootState爲全局
}
}
},
b: {
text: 2
}
}
})
}
複製代碼
在vue文件調用時
//app.vue
computed: {
textA() {
return this.$store.state.a.text //調用a模塊的text值
},
textB() {
return this.$store.state.b.text //調用b模塊的text值
}
}
複製代碼
咱們在使用vuex時會發現,每當咱們修改vuex內的內容再保存時,vue不會熱更替顯示內容,而是會刷新一下,WTF,這麼好用的功能難道Vuex用不了:horse:?
固然不是,咱們只須要在store.js加入部分代碼便可
//store.js
import defaultState from './state/state'
import mutations from './mutations/mutations'
import getters from './getters/getters'
import actions from './actions/actions'
export default () => {
const store = new Vuex.Store({
state: defaultState,
mutations: mutations,
getters: getters,
actions: actions,
})
if (module.hot) {
module.hot.accept([
'./state/state',
'./mutations/mutations',
'./actions/actions',
'./getters/getters'
],() => {
const newState = require('./state/state').default,
const newMutations = require('./mutations/mutations').default
const newGetters = require('./getters/getters').default
const newActions = require('./actions/actions').default
store.hotUpdate({
state:newState,
mutations:newMutations,
actions:newActions,
getters:newGetters
})
})
}
return store
}
複製代碼
一些更多的有關Vuex的API 能夠查看
服務端渲染的優點:
但同時也要注意一些權衡之處: