Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,讓構建單頁面應用變得易如反掌。包含的功能有:css
用 Vue.js + Vue Router 建立單頁應用,是很是簡單的。使用 Vue.js ,咱們已經能夠經過組合組件來組成應用程序,當你要把 Vue Router 添加進來,咱們須要作的是,將組件 (components) 映射到路由 (routes),而後告訴 Vue Router 在哪裏渲染它們html
安裝vue
npm i vue-router -S
ios在main.js中vue-router
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) 複製代碼
推薦使用:vue add router 添加插件(記得提早提交)vuex
router.jsnpm
import Vue from 'vue'
//1.導入
import Router from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'
//2.模塊化機制 使用Router
Vue.use(Router)
//3.建立路由器對象
const router = new Router({
routes:[{
path: '/home',
component: Home
},
{
path: '/about',
component: About
}
]
})
export default router;
複製代碼
main.js編程
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
// 4.掛載根實例
router,
render: h => h(App)
}).$mount('#app')
複製代碼
作好以上配置以後json
App.vueaxios
<template>
<div id="app">
<div id="nav">
<!-- 使用router-link組件來導航 -->
<!-- 經過傳入to屬性指定鏈接 -->
<!-- router-link默認會被渲染成一個a標籤 -->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
</div>
<!-- 路由出口 -->
<!-- 路由匹配的組件將被渲染到這裏 -->
<router-view/>
</div>
</template>
複製代碼
打開瀏覽器.,切換Home和About超連接,查看效果
在配置路由的時候,給路由添加名字,訪問時就能夠動態的根據名字來進行訪問
const router = new Router({
routes:[{
path: '/home',
name:"home",
component: Home
},
{
path: '/about',
name:'about'
component: About
}
]
})
複製代碼
要連接到一個命名路由,能夠給 router-link
的 to
屬性傳一個對象:
<router-link :to="{name:'home'}">Home</router-link> |
<router-link :to="{name:'about'}">About</router-link> |
複製代碼
咱們常常須要把某種模式匹配到的全部路由,全都映射到同個組件。例如,咱們有一個 User
組件,對於全部 ID 各不相同的用戶,都要使用這個組件來渲染。那麼,咱們能夠在 vue-router
的路由路徑中使用「動態路徑參數」(dynamic segment) 來達到這個效果
User.vue
<template>
<div>
<h3>用戶頁面</h3>
</div>
</template>
<script>
export default {
};
</script>
<style lang="scss" scoped>
</style>
複製代碼
路由配置
const router = new Router({
routes:[
{
path: '/user/:id',
name: 'user',
component: User,
},
]
})
複製代碼
<router-link :to="{name:'user',params:{id:1}}">User</router-link> |
複製代碼
訪問
查看效果
當匹配到路由時,參數值會被設置到this.$route.params,能夠在每一個組件中使用,因而,咱們能夠更新 User
的模板,輸出當前用戶的 ID:
<template>
<div>
<h3>用戶頁面{{$route.params.id}}</h3>
</div>
</template>
複製代碼
提醒一下,當使用路由參數時,例如從 /user/1 導航到
/user/2`,原來的組件實例會被複用。由於兩個路由都渲染同個組件,比起銷燬再建立,複用則顯得更加高效。不過,這也意味着組件的生命週期鉤子不會再被調用。
複用組件時,想對路由參數的變化做出響應的話,你能夠簡單地 watch (監測變化) $route
對象:
/*使用watch(監測變化) $route對象 watch: { $route(to, from) { console.log(to.params.id); } }, */
// 或者使用導航守衛
beforeRouteUpdate(to,from,next){
//查看路由的變化
//必定要調用next,否則就會阻塞路由的變化
next();
}
複製代碼
const router = new Router({
routes:[
//....
// 匹配不到理由時,404頁面顯示
{
path: '*',
component: () => import('@/views/404')
}
]
})
複製代碼
當使用通配符路由時,請確保路由的順序是正確的,也就是說含有通配符的路由應該放在最後。路由 { path: '*' }
一般用於客戶端 404 錯誤
當使用一個通配符時,$route.params
內會自動添加一個名爲 pathMatch
參數。它包含了 URL 經過通配符被匹配的部分:
{
path: '/user-*',
component: () => import('@/views/User-admin.vue')
}
this.$route.params.pathMatch // 'admin'
複製代碼
有時候,同一個路徑能夠匹配多個路由,此時,匹配的優先級就按照路由的定義順序:誰先定義的,誰的優先級就最高。
相似像地址上出現的這種:http://localhos:8080/page?id=1&title=foo
const router = new Router({
routes:[
//....
{
name:'/page',
name:'page',
component:()=>import('@/views/Page.vue')
}
]
})
複製代碼
<router-link :to="{name:'page',query:{id:1,title:'foo'}}">User</router-link> |
複製代碼
訪問http://localhos:8080/page?id=1&title=foo查看Page
Page.vue
<template>
<div>
<h3>Page頁面</h3>
<h3>{{$route.query.userId}}</h3>
</div>
</template>
<script>
export default {
created () {
//查看路由信息對象
console.log(this.$route);
},
}
</script>
<style lang="scss" scoped>
</style>
複製代碼
例子是從 /
重定向到 /home
:
const router = new Router({
mode: 'history',
routes: [
// 重定向
{
path: '/',
redirect: '/home'
}
{
path: '/home',
name: 'home',
component: Home
},
]
})
複製代碼
重定向的目標也能夠是一個命名的路由:
const router = new VueRouter({
routes: [
{ path: '/', redirect: { name: 'name' }}
]
})
複製代碼
別名
{
path: '/user/:id',
name: 'user',
component: User,
alias: '/alias'
}
複製代碼
起別名,僅僅起起別名 用戶訪問http://loacalhost:8080/alias的時候,顯示User組件
別名」的功能讓你能夠自由地將 UI 結構映射到任意的 URL,而不是受限於配置的嵌套路由結構。
在組件中使用 $route
會使之與其對應路由造成高度耦合,從而使組件只能在某些特定的 URL 上使用,限制了其靈活性。
使用 props
將組件和路由解耦:
取代與 $route 的耦合
{
path: '/user/:id',
name: 'user',
component: User,
props:true
},
複製代碼
User.vue
<template>
<div>
<h3>用戶頁面{{$route.params.id}}</h3>
<h3>用戶頁面{{id}}</h3>
</div>
</template>
<script>
export default{
//....
props: {
id: {
type: String,
default: ''
},
},
}
</script>
複製代碼
props也能夠是個函數
{
path: '/user/:id',
name: 'user',
component: User,
props: (route)=>({
id: route.params.id,
title:route.query.title
})
}
複製代碼
User.vue
<template>
<div>
<h3>用戶頁面{{id}}-{{title}}</h3>
</div>
</template>
<script>
export default {
// ...
props: {
id: {
type: String,
default: ''
},
title:{
type:String
}
},
};
</script>
複製代碼
除了使用 <router-link>
建立 a 標籤來定義導航連接,咱們還能夠藉助 router 的實例方法,經過編寫代碼來實現。
注意:在 Vue 實例內部,你能夠經過 router 訪問路由實例。所以你能夠調用 this.router.push。
聲明式 | 編程式 |
---|---|
<router-link :to="..."> |
router.push(...) |
該方法的參數能夠是一個字符串路徑,或者一個描述地址的對象。例如
// 字符串
this.$router.push('home')
// 對象
this.$router.push({ path: 'home' })
// 命名的路由
this.$router.push({ name: 'user', params: { userId: '123' }})
// 帶查詢參數,變成 /register?plan=private
this.$.push({ path: 'register', query: { plan: 'private' }})
複製代碼
前進後退
// 在瀏覽器記錄中前進一步,等同於 history.forward()
router.go(1)
// 後退一步記錄,等同於 history.back()
router.go(-1)
// 前進 3 步記錄
router.go(3)
// 若是 history 記錄不夠用,那就默默地失敗唄
router.go(-100)
router.go(100)
複製代碼
實際生活中的應用界面,一般由多層嵌套的組件組合而成。一樣地,URL 中各段動態路徑也按某種結構對應嵌套的各層組件
/user/1/profile /user/1/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
複製代碼
router.js
{
path: '/user/:id',
name: 'user',
component: User,
props: ({params,query})=>({
id: params.id,
title:query.title
}),
children:[
// 當 /user/:id/profile 匹配成功,
// Profile 會被渲染在 User 的 <router-view> 中
{
path:"profile",
component: Profile
},
// 當 /user/:id/posts 匹配成功,
// Posts 會被渲染在 User 的 <router-view> 中
{
path: "posts",
component: Posts
}
]
}
複製代碼
在 User
組件的模板添加一個 <router-view>
:
<template>
<div>
<h3>用戶頁面{{$route.params.id}}</h3>
<h3>用戶頁面{{id}}</h3>
<router-view></router-view>
</div>
</template>
複製代碼
App.vue
<template>
<div id='app'>
<!-- 嵌套理由 -->
<router-link to="/user/1/profile">User/profile</router-link> |
<router-link to="/user/1/posts">User/posts</router-link> |
</div>
</template>
複製代碼
有時候想同時 (同級) 展現多個視圖,而不是嵌套展現,例如建立一個佈局,有 sidebar
(側導航) 和 main
(主內容) 兩個視圖,這個時候命名視圖就派上用場了
{
path: '/home',
name: 'home',
//注意這個key是components
components: {
default: Home, //默認的名字
main: ()=>import('@/views/Main.vue'),
sidebar: () => import('@/views/Sidebar.vue')
}
},
複製代碼
App.vue
<router-view/>
<router-view name='main'/>
<router-view name='sidebar'/>
複製代碼
「導航」表示路由正在發生改變。
beforeEach
守衛。beforeRouteUpdate
守衛 (2.2+)。beforeEnter
。beforeRouteEnter
。beforeResolve
守衛 (2.5+)。afterEach
鉤子。beforeRouteEnter
守衛中傳給 next
的回調函數。你可使用router.beforeEach
註冊一個全局前置守衛
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
複製代碼
有個需求,用戶訪問在瀏覽網站時,會訪問不少組件,當用戶跳轉到/notes
,發現用戶沒有登陸,此時應該讓用戶登陸才能查看,應該讓用戶跳轉到登陸頁面,登陸完成以後才能夠查看個人筆記的內容,這個時候全局守衛起到了關鍵的做用
有兩個路由 /notes
和/login
router.vue
const router = new VueRouter({
routes:[
{
path: '/notes',
name: 'notes',
component: () => import('@/views/Notes')
},
{
path: "/login",
name: "login",
component: () => import('@/views/Login')
},
]
})
// 全局守衛
router.beforeEach((to, from, next) => {
//用戶訪問的是'/notes'
if (to.path === '/notes') {
//查看一下用戶是否保存了登陸狀態信息
let user = JSON.parse(localStorage.getItem('user'))
if (user) {
//若是有,直接放行
next();
} else {
//若是沒有,用戶跳轉登陸頁面登陸
next('/login')
}
} else {
next();
}
})
複製代碼
Login.vue
<template>
<div>
<input type="text" v-model="username">
<input type="password" v-model="pwd">
<button @click="handleLogin">提交</button>
</div>
</template>
<script>
export default {
data() {
return {
username: "",
pwd: ""
};
},
methods: {
handleLogin() {
// 1.獲取用戶名和密碼
// 2.與後端發生交互
setTimeout(() => {
let data = {
username: this.username
};
//保存用戶登陸信息
localStorage.setItem("user", JSON.stringify(data));
// 跳轉個人筆記頁面
this.$router.push({ name: "notes" });
}, 1000);
},
}
};
</script>
複製代碼
App.vue
<!-- 全局守衛演示 -->
<router-link to="/notes">個人筆記</router-link> |
<router-link to="/login">登陸</router-link> |
<button @click="handleLogout">退出</button>
複製代碼
export default {
methods: {
handleLogout() {
//刪除登陸狀態信息
localStorage.removeItem("user");
//跳轉到首頁
this.$router.push('/')
}
},
}
複製代碼
你能夠在路由組件內直接定義如下路由導航守衛:
beforeRouteEnter
beforeRouteUpdate
(2.2 新增)beforeRouteLeave
<template>
<div>
<h3>用戶編輯頁面</h3>
<textarea name id cols="30" rows="10" v-model="content"></textarea>
<button @click="saveData">保存</button>
<div class="wrap" v-for="(item,index) in list" :key="index">
<p>{{item.title}}</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
content: "",
list: [],
confir: true
};
},
methods: {
saveData() {
this.list.push({
title: this.content
});
this.content = "";
}
},
beforeRouteLeave(to, from, next) {
// 導航離開該組件的對應路由時調用
// 能夠訪問組件實例 `this`
if (this.content) {
alert("請確保保存信息以後,再離開");
next(false);
} else {
next();
}
}
};
</script>
複製代碼
給須要添加權限的路由設置meta字段
{
path: '/blog',
name: 'blog',
component: () => import('@/views/Blog'),
meta: {
requiresAuth: true
}
},
{
// 路由獨享的守衛
path: '/notes',
name: 'notes',
component: () => import('@/views/Notes'),
meta: {
requiresAuth: true
}
},
複製代碼
// 全局守衛
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
// 須要權限
if(!localStorage.getItem('user')){
next({
path:'/login',
query:{
redirect:to.fullPath
}
})
}else{
next();
}
} else {
next();
}
})
複製代碼
login.vue
//登陸操做
handleLogin() {
// 1.獲取用戶名和密碼
// 2.與後端發生交互
setTimeout(() => {
let data = {
username: this.username
};
localStorage.setItem("user", JSON.stringify(data));
// 跳轉到以前的頁面
this.$router.push({path: this.$route.query.redirect });
}, 1000);
}
複製代碼
有時候,進入某個路由後,須要從服務器獲取數據。例如,在渲染用戶信息時,你須要從服務器獲取用戶的數據。咱們能夠經過兩種方式來實現:
當你使用這種方式時,咱們會立刻導航和渲染組件,而後在組件的 created
鉤子中獲取數據。這讓咱們有機會在數據獲取期間展現一個 loading 狀態,還能夠在不一樣視圖間展現不一樣的 loading 狀態。
<template>
<div class="post">
<div v-if="loading" class="loading">Loading...</div>
<div v-if="error" class="error">{{ error }}</div>
<div v-if="post" class="content">
<h2>{{ post.title }}</h2>
<p>{{ post.body }}</p>
</div>
</div>
</template>
複製代碼
export default {
name: "Post",
data() {
return {
loading: false,
post: null,
error: null
};
},
// 組件建立完後獲取數據,
// 此時 data 已經被 監視 了
created() {
// 若是路由有變化,會再次執行該方法
this.fetchData();
},
watch: {
$route: "fetchData"
},
methods: {
fetchData() {
this.error = this.post = null;
this.loading = true;
this.$http.get('/api/post')
.then((result) => {
this.loading = false;
this.post = result.data;
}).catch((err) => {
this.error = err.toString();
});
}
}
};
複製代碼
Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化
vue add vuex
複製代碼
store.js
import Vue from 'vue'
import Vuex from 'vuex'
//確保開頭調用Vue.use(Vuex)
Vue.use(Vuex)
export default new Vuex.Store({
state: { //this.$store.state.count
count:0
},
getters:{
evenOrOdd:(state)=>{ //this.$store.getters.evenOrOdd
return state.count % 2 ===0 ? '偶數': '奇數'
}
},
mutations: {
increment(state){ //this.$store.commit('increment')
state.count++
},
decrement(state){ //this.$store.commit('decrement')
state.count--
}
},
actions: {
increment({commit}){ //this.$store.dispatch('increment')
// 修改狀態的惟一方式是提交mutation
commit('increment');
},
decrement({ commit }) { //this.$store.dispatch('decrement')
commit('decrement');
},
incrementAsync({commit}){ //this.$store.dispatch('incrementAsync')
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('increment');
resolve(10);
}, 1000);
})
}
}
})
複製代碼
咱們能夠在組件的某個合適的時機經過this.$store.state
來獲取狀態對象,以及經過this.$store.commit
方法觸犯狀態變動
this.$store.commit('increment');
複製代碼
當一個組件須要獲取多個狀態時候,將這些狀態都聲明爲計算屬性會有些重複和冗餘。爲了解決這個問題,咱們可使用 mapState
輔助函數幫助咱們生成計算屬性,讓你少按幾回鍵
// 在單獨構建的版本中輔助函數爲 Vuex.mapState
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭頭函數可以使代碼更簡練
count: state => state.count,
// 傳字符串參數 'count' 等同於 `state => state.count`
countAlias: 'count',
// 爲了可以使用 `this` 獲取局部狀態,必須使用常規函數
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
複製代碼
當映射的計算屬性的名稱與 state 的子節點名稱相同時,咱們也能夠給 mapState
傳一個字符串數組。
computed: mapState([
// 映射 this.count 爲 store.state.count
'count'
])
複製代碼
對象展開運算符
mapState
函數返回的是一個對象。咱們如何將它與局部計算屬性混合使用呢?一般,咱們須要使用一個工具函數將多個對象合併爲一個,以使咱們能夠將最終對象傳給 computed
屬性。可是自從有了對象展開運算符,極大地簡化寫法
computed:{
...mapState({
"count"
})
}
複製代碼
mapGetters
輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性:
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
...mapGetters([
'evenOrOdd'
])
},
}
複製代碼
若是你想將一個 getter 屬性另取一個名字,使用對象形式:
mapGetters({
// 把 `this.doneEvenOrOdd` 映射爲 `this.$store.getters.evenOrOdd`
doneEvenOrOdd: 'evenOrOdd'
})
複製代碼
Mutation
更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation。Vuex 中的 mutation 很是相似於事件:每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受 state 做爲第一個參數:
你能夠在組件中使用 this.$store.commit('xxx')
提交 mutation,或者使用 mapMutations
輔助函數將組件中的 methods 映射爲 store.commit
調用(須要在根節點注入 store
)。
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations('counter',[
'increment',
'decrement',
]),
}
}
複製代碼
Action
Action 相似於 mutation,不一樣在於:
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapActions('counter',[
'incrementAsync'
])
}
}
複製代碼
提交方式
//在組件內部
// 以載荷形式分發
this.$store.dispatch('incrementAsync', {
amount: 10
})
// 以對象形式分發
this,.$store.dispatch({
type: 'incrementAsync',
amount: 10
})
複製代碼
因爲使用單一狀態樹,應用的全部狀態會集中到一個比較大的對象。當應用變得很是複雜時,store 對象就有可能變得至關臃腫。
爲了解決以上問題,Vuex 容許咱們將 store 分割成模塊(module)。每一個模塊擁有本身的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行一樣方式的分割:
作一個購物車案例
有兩個模塊cart
和products
建立store文件夾
|---store
├── index.js
└── modules
├── cart.js
└── products.js
複製代碼
cart.js
若是但願你的模塊具備更高的封裝度和複用性,你能夠經過添加 namespaced: true
的方式使其成爲帶命名空間的模塊
當模塊被註冊後,它的全部 getter、action 及 mutation 都會自動根據模塊註冊的路徑調整命名。
export default {
//使當前模塊具備更高的封裝度和複用性
namespaced: true,
state: {
...
},
getters: {
...
},
mutations: {
...
},
actions: {
...
},
}
複製代碼
products.js
export default {
//使當前模塊具備更高的封裝度和複用性
namespaced: true,
state: {
...
},
getters: {
...
},
mutations: {
...
},
actions: {
...
},
}
複製代碼
index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import cart from './modules/cart';
import products from './modules/products';
export default new Vuex.Store({
modules:{
cart,
products,
}
})
//this.$store.state.cart //獲取cart的狀態
//this.$store.state.products //獲取products的狀態
複製代碼
完整購物車案例
mock數據
新建vue.config.js
const products = [
{ id: 1, title: 'iphone11', price: 600, inventory: 10 },
{ id: 2, title: 'iphone11 pro', price: 800, inventory: 5 },
{ id: 3, title: 'iphone11 max', price: 1600, inventory: 6 },
]
module.exports = {
devServer: {
before(app, server) {
app.get('/api/products', (req, res) => {
res.json({
products:products
})
})
}
}
}
複製代碼
cart.js
export default {
//使當前模塊具備更高的封裝度和複用性
namespaced: true,
state: {
items: [],
},
getters: {
//獲取購物車中的商品
cartProducts: (state, getters, rootState) => {
return state.items.map(({ id, quantity }) => {
const product = rootState.products.products.find(product => product.id === id)
return {
title: product.title,
price: product.price,
quantity
}
})
},
// 購物車總價格
cartTotalPrice: (state, getters) => {
return getters.cartProducts.reduce((total, product) => {
return total + product.price * product.quantity
}, 0)
}
},
mutations: {
pushProductToCart(state, { id }) {
state.items.push({
id,
quantity: 1
})
},
incrementItemQuantity(state, { id }) {
const cartItem = state.items.find(item => item.id === id);
cartItem.quantity++;
},
},
actions: {
//添加商品到購物車
addProductToCart({ commit, state }, product) {
// 若是有庫存
if (product.inventory > 0) {
const cartItem = state.items.find(item => item.id === product.id);
if (!cartItem) {
commit('pushProductToCart', { id: product.id });
} else {
commit('incrementItemQuantity', cartItem);
}
//提交products模塊中decrementProductInventory方法
//讓商品列表的庫存數量減1
commit('products/decrementProductInventory', { id: product.id }, { root: true })
}
}
},
}
複製代碼
products.js
import Axios from "axios";
export default {
//使當前模塊具備更高的封裝度和複用性
namespaced: true,
state: {
products: []
},
getters: {
},
mutations: {
setProducts(state, products) {
state.products = products;
},
//減小商品庫存的方法
decrementProductInventory(state, { id }) {
const product = state.products.find(product => product.id === id)
product.inventory--
}
},
actions: {
//獲取全部商品的方法
getAllProducts({ commit }) {
Axios.get('/api/products')
.then(res => {
console.log(res.data.products);
commit('setProducts',res.data.products)
})
.catch(err => {
console.log(err);
})
}
},
}
複製代碼
Products.vue
<template>
<div>
<h3>商鋪</h3>
<ul>
<li v-for='product in products' :key = 'product.id'>
{{product.title}} - {{product.price | currency}}
<br>
<button :disabled='!product.inventory' @click='addProductToCart(product)'>添加到購物車</button>
</li>
</ul>
<hr>
</div>
</template>
<script>
import { mapState,mapActions } from "vuex";
export default {
name: "ProductList",
data() {
return {};
},
computed: {
products(){
return this.$store.state.products.products
}
},
methods: {
...mapActions('cart',[
'addProductToCart'
])
},
created() {
this.$store.dispatch("products/getAllProducts");
}
};
</script>
<style scoped>
</style>
複製代碼
Cart.vue
<template>
<div>
<h2>個人購物車</h2>
<i>請增長商品到您的購物車.</i>
<ul>
<li
v-for="product in products"
:key="product.id"
>{{product.title}}-{{product.price | currency}} x {{product.quantity}}
</li>
</ul>
<p>總價格:{{total | currency}}</p>
</div>
</template>
<script>
import { mapGetters,mapState } from "vuex";
export default {
name: "shoppingcart",
computed:{
...mapGetters('cart',{
products:'cartProducts',
total:'cartTotalPrice'
})
}
};
</script>
<style scoped>
</style>
複製代碼
Vuex 能夠幫助咱們管理共享狀態,並附帶了更多的概念和框架。這須要對短時間和長期效益進行權衡。
若是您不打算開發大型單頁應用,使用 Vuex 多是繁瑣冗餘的。確實是如此——若是您的應用夠簡單,您最好不要使用 Vuex。一個簡單的 store 模式就足夠您所需了。可是,若是您須要構建一箇中大型單頁應用,您極可能會考慮如何更好地在組件外部管理狀態,Vuex 將會成爲天然而然的選擇。引用 Redux 的做者 Dan Abramov 的話說就是:
Flux 架構就像眼鏡:您自會知道何時須要它
日誌插件
Vuex 自帶一個日誌插件用於通常的調試:
import createLogger from 'vuex/dist/logger'
const store = new Vuex.Store({
plugins: [createLogger({
collapsed: false, // 自動展開記錄的 mutation
})]
})
複製代碼
要注意,logger 插件會生成狀態快照,因此僅在開發環境使用。
還有2件事拜託你們
一:求贊 求收藏 求分享 求留言,讓更多的人看到這篇內容
二:歡迎添加個人我的微信
備註「資料」, 300多篇原創技術文章,海量的視頻資料便可得到
備註「加羣」,我會拉你進技術交流羣,羣裏大牛學霸具在,哪怕您作個潛水魚也會學到不少東西
本文由練識課堂發佈!