Vuex是干什么的? vuex是处理数据交互的,父子组件用的是props和emit,但是处理大数据页面的时候就需要用vuex, 可以做到一个数据变,其他引用这个数据的都变。
Vuex官方文档:https://vuex.vuejs.org/zh/guide/
vuex详细教程视频: https://ke.qq.com/course/481750?taid=5008215335459286
该视频教程从0-1学会vuex,比之前听的这个讲的比较清晰;
Vuex的4个属性:state、getters、actions、mutation、
state:设置数据
getters:获取数据
actions:异步数据操作
mutations:对数据进行处理的唯一途径。
vuex可以理解为本来一个C页面前套了A、B两个组件,A组件里面有一堆数据,B组件里面有一堆数据,A、B数据都来着于C页面。现在A数据变了想要B,C页面用到的数据也跟着变。传统方法是A数据去调用C页面,C页面再去调B页面。一两个组件可能工作量不是很多,若项目大,层级关系多,这样页面互相传值很容易会乱掉。vuex可以用state把初始数据作为一个数据源仓库,如果大家想要用的话,就从里面进行获取getters,如果想改变数据就可以用到里面的mutations进行操作,对于一些异步操作类似定时器这类的方法时就要用到actions;
如何使用vuex?
1.安装vuex
$ npm install vuex --save
2.在main.js同级目录下创建一个store.js文件
import Vue from ‘vue’
import Vuex from ‘vuex’
这两个vue、vuex一定要小写,不可大写,不然在引用页面console.log(this.$store)显示undefined
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
strict:true,
state:{
product:[{
name: 'Num1',
value:100
},{
name: 'Num2',
value:200
},{
name: 'Num3',
value:300
},{
name: 'Num4',
value:400
}]
},
getters:{
saleProducts:(state)=>{
var saleProducts = state.product.map(product=>{
return {
name:"**"+product.name+"**",
value: product.value /2
}
})
return saleProducts;
}
},
mutations:{
reduceProducts:(state,payload)=>{
var reduceProducts = state.product.map(product=>{
product.value -=payload;
})
return reduceProducts;
}
},
actions:{
reduceProducts:(context,payload)=>{
setTimeout(()=>{
context.commit("reduceProducts",payload)
},300)
}
}
})
在main.js进行全局引入store.js
import Vue from 'vue'
import App from './App'
import {store} from './store.js'
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
components: { App },
template: '<App/>',
// render: h => h(App)
})
在view文件夹中创建一个父组件index.vue
<template>
<div class="parent">
<div>VUEX-DEMO</div>
<page1></page1>
<page2></page2>
</div>
</template>
<script>
import page1 from './page1.vue'
import page2 from './page2.vue'
export default {
components: {
page1,
page2
},
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
.parent{
margin-top:100px;
margin-left: 20px;
}
</style>
再创建一个page1.vue
<template>
<div class="page1">
<li v-for="(item,index) in product" :key="index">
<span>{{item.name}}</span>
<span>{{item.value}}</span>
</li>
</div>
</template>
<script>
export default {
data() {
return {
}
},
computed:{
product(){
return this.$store.state.product;
}
}
}
</script>
<style lang="scss" scoped>
.page1 {
width: 375px;
background: #cc0;
padding: 20px 0;
color:#fff;
font-weight: bold;
display: flex;
justify-content: space-around;
align-content: center;
li{
}
}
</style>
再创建一个page2.vue
<template>
<div class="page2">
<button @click="reduceProducts(4)">降价</button>
<li v-for="(item,index) in saleProducts" :key="index">
<span>{{item.name}}</span>
<span>{{item.value}}</span>
</li>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
import {mapActions} from 'vuex'
export default {
data() {
return {
}
},
computed:{
/* saleProducts(){
return this.$store.getters.saleProducts;
} */
...mapGetters([
"saleProducts"
])
},
methods:{
/* reduceProduct(amout){
/* this.$store.state.product.forEach(product=>{
product.value -=1;
}) */
// mutaion
// return this.$store.commit("reduceProducts",amout);
//actions
/* return this.$store.dispatch("reduceProducts",amout);
} */
...mapActions([
"reduceProducts"
])
}
}
</script>
<style lang="scss" scoped>
.page2 {
width: 375px;
background: #324e4e;
color:#fff;
font-weight: bold;
margin-top: 20px;
li{
padding: 20px;
}
}
</style>
效果图
debugger调试技巧:
vue的页面都是经过渲染之后的页面,比较难找到对应的组件关系,还有使用vuex产生的数据关系;
安装vue.js工具
谷歌-》扩展工具-〉谷歌商店-》搜vue-〉点击安装vue.js.tool