-
State對象:給Vue Component提供數(shù)據(jù)狀態(tài)锉罐,
this.$store.state.name
、...mapState(['name']) + computed
-
gettings對象:對State里面的數(shù)據(jù)進(jìn)一步加工殖熟,
this.$store.getters.name
、...mapGetters(['name']) + computed
-
Mutation對象:改變state狀態(tài)的方法集合钉汗,
this.$store.commit('方法名',參數(shù))
蒲障、...mapMutations(['name']) + methods
-
Actions對象:處理異步數(shù)據(jù),
this.$store.dispatch('方法名',參數(shù))
1. 不使用Vuex實(shí)現(xiàn)Tab功能
關(guān)于Tab的實(shí)現(xiàn):理想狀態(tài)下萎战,"選擇層Tab + 展示層Current"咐容,就夠了舆逃。但是蚂维,由于沒有公共狀態(tài)存儲(chǔ)的地方戳粒,只能借助父組件App,進(jìn)行tabIndex屬性的傳遞通信虫啥,很麻煩蔚约。所以說,兄弟組件之間的通信還是Vuex比較適合
知識點(diǎn)1:動(dòng)態(tài)改變class類的方式
Array
知識點(diǎn)2:父子組件的通信派發(fā)事件this.$emit
涂籽、props
# 子組件Tab: 存放Tab組件樣式的地方
<template>
<div>
<a href="javascript:;" @click="clickTab(1)" :class="['router', { current: tabIndex == 1 }]">選項(xiàng)1</a>
<a href="javascript:;" @click="clickTab(2)" :class="['router', { current: tabIndex == 2 }]">選項(xiàng)2</a>
<a href="javascript:;" @click="clickTab(3)" :class="['router', { current: tabIndex == 3 }]">選項(xiàng)3</a>
<a href="javascript:;" @click="clickTab(4)" :class="['router', { current: tabIndex == 4 }]">選項(xiàng)4</a>
</div>
</template>
<script>
export default {
name: "tab",
props: {
tabIndex: Number,
},
methods: {
clickTab(index) {
// 自定義派發(fā)事件苹祟,監(jiān)聽Tab的改變(子組件向父組件通信)
this.$emit("clickTab", index);
},
},
};
</script>
<style scoped>
.router {
text-decoration: none;
color: #000;
margin-right: 10px;
}
.current {
color: aqua;
}
</style>
# 父組件:控制Tab邏輯的地方
<template>
<div id="app">
<Tab :tabIndex="tabIndex" @clickTab="changeTab"></Tab>
<Current :tabIndex="tabIndex"></Current>
</div>
</template>
<script>
import Tab from "@/components/tabs/index.vue";
import Current from "@/views/Current.vue";
export default {
name: "App",
data() {
return {
tabIndex: 1,
};
},
components: {
Tab,
Current,
},
methods: {
changeTab(index) {
this.tabIndex = index;
},
},
};
</script>
# 子組件Current,展示Tab內(nèi)容的地方
<template>
<div>頁面{{ tabIndex }}</div>
</template>
<script>
export default {
name: "Current",
props: {
tabIndex: Number,
},
};
</script>
2. 使用Vuex重寫Tab功能
將tabIndex屬性评雌,以及操作tabIndex屬性的方法树枫,統(tǒng)一存儲(chǔ)到Vuex當(dāng)中,然后景东,在"選擇層Tab + 展示層
Current"砂轻,就夠了,跟App.vue沒關(guān)系了斤吐。知識點(diǎn):如何在Vue組件當(dāng)中調(diào)用Vuex里面的數(shù)據(jù)和方法搔涝?
...mapState(['name'])
、...mapMutations(['name'])
# store.js和措,聲明數(shù)據(jù)庄呈、以及操作數(shù)據(jù)方法
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
tabIndex: 1,
test: "選項(xiàng)4"
},
mutations: {
setTabIndex(state, index) {
state.tabIndex = index;
}
}
});
# 子組件Tab: 存放Tab組件樣式的地方,并調(diào)用邏輯方法
<template>
<div>
<a href="javascript:;" @click="setTabIndex(1)" :class="['router', { current: tabIndex == 1 }]">選項(xiàng)1</a>
<a href="javascript:;" @click="setTabIndex(2)" :class="['router', { current: tabIndex == 2 }]">選項(xiàng)2</a>
<a href="javascript:;" @click="setTabIndex(3)" :class="['router', { current: tabIndex == 3 }]">選項(xiàng)3</a>
<a href="javascript:;" @click="setTabIndex(4)" :class="['router', { current: tabIndex == 4 }]">{{ test }}</a>
</div>
</template>
<script>
import { mapState, mapMutations } from "vuex";
export default {
name: "tab",
computed: {
// 輔助方法mapState派阱,拿到State對象里面的數(shù)據(jù)
// ...mapState(["tabIndex", "test"]),
tabIndex() {
return this.$store.state.tabIndex;
},
test() {
return this.$store.state.test;
},
},
methods: {
// 輔助方法mapMutations诬留,拿到Mutations對象里面的方法
// ...mapMutations(["setTabIndex"]),
setTabIndex(index) {
this.$store.commit("setTabIndex", index);
},
},
};
</script>
<style scoped>
.router {
text-decoration: none;
color: #000;
margin-right: 10px;
}
.current {
color: aqua;
}
</style>
#父組件App.vue
<template>
<div id="app">
<Tab></Tab>
<Current></Current>
</div>
</template>
<script>
import Tab from "@/components/tabs/index.vue";
import Current from "@/views/Current.vue";
export default {
name: "App",
components: {
Tab,
Current,
},
};
</script>
#子組件,展示內(nèi)容區(qū)
<template>
<div>頁面{{ tabIndex }}</div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "Current",
computed: {
...mapState(["tabIndex"]),
},
};
</script>
3.actions處理異步數(shù)據(jù)dispatch
颁褂、 context.commit()
問題:如何將接口請求到的數(shù)據(jù)存儲(chǔ)到Vuex里面故响,并渲染到Vue組件當(dāng)中?
第一步:定義actions方法獲取異步數(shù)據(jù)
第二步:調(diào)用mutations方法將異步數(shù)據(jù)存到state里面
第三步:vue components拿著state里面的數(shù)據(jù)渲染
# 前提:Express API
# // http://localhost:3000/api/test?name=小明&age=18
module.exports = (app) => {
var express = require("express");
var router = express.Router();
router.get("/test", (req, res) => {
if ("小明" == req.query.name && 18 == req.query.age) {
res.send("我是小明颁独,今年18");
} else {
res.send("hello world");
}
});
// 掛載router對象
app.use("/api", router);
};
# vuex定義異步請求彩届、數(shù)據(jù)存儲(chǔ)等方法
import Vue from "vue";
import Vuex from "vuex";
import { axios } from "@/libs/https.js";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
expressText: ""
},
mutations: {
setExpressText(state, text) {
state.expressText = text;
}
},
actions: {
// context上下文對象包含commit屬性、payload接受一個(gè)對象參數(shù)
getData(context, payload) {
axios.get(`/api/test?name=${payload.name}&age=${payload.age}`).then(res => {
context.commit("setExpressText", res);
});
}
}
});
# actions function調(diào)用誓酒、以及數(shù)據(jù)渲染
<template>
<div id="app">
{{ expressText }}
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "App",
computed: {
...mapState(["expressText"]),
},
mounted() {
this.$store.dispatch("getData", { name: "小明", age: 18 });
},
};
</script>