1、Vue中的Vuex
Vuex是一个专门为Vue.js应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生改变。
注意:
Vuex中禁止直接在组件中通过this.$store.state.name = 'test'
去修改Vuex中state的数据值,这样会导致后期的调试非常困难,因为多个组件直接修改同一个共享的数据的话,那么就无法定位到哪个组件修改导致后期出了问题,所以,Vuex中修改数据必须通过Mutation函数,且该函数为同步的。
1、state
state是单一状态树,每一个应用将仅仅包含一个store实例,使用方法:
this.$store.state.状态名称
或
...mapState(["title"])
2、getter
getters可以从store中的state中派生出一些状态,getters的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。可以将getters理解为store的计算属性。使用方法:
this.$store.getters.计算属性名称
...mapGetters(["getNames"])
3、mutations()
mutation方法是用于更改Vuex的store中的状态的唯一方法,即提交至mutation。
mutation是同步函数,使用方法:
mutations: {
// 同步函数的方法名
// state为Vuex的数据,payload为外部传过来的数据,也称之为‘载荷’
showFilmDetail(state,payload){
state.filmDetail = payload; // 修改Vuex中的filmDetail对象
}
},
4、actions()
actions方法是用于更改Vuex的store中的状态的异步操作方法,该区域内部执行的是异步操作,比如:调取后台接口,写定时器等等,执行完异步操作后,会再次提交至mutation,mutation再去修改数据的状态。
使用Vuex存储电影id
电影列表组件:
<template>
<div class="film">
<div class="my-film" >
<ul >
<li v-for="item in filmsList" :key="item.filmId" @click="handleSwitch(item)">
<!-- 内容显示区 -->
<div class="film-item" >
<!-- 左侧图片 -->
<div class="film-img">
<img :src="item.poster" alt="" />
</div>
<!-- 右侧详情 -->
<div class="film-detail">
<!-- 上侧电影名称 -->
<div class="film-top">
<span>{{ item.name }}</span>
<p>{{ item.filmType.name }}</p>
</div>
<!-- 电影主演 -->
<div class="film-bottom">
<div>
<p v-if="item.grade">
观众评分
<span style="color: #ff5f16">{{ item.grade }}</span>
</p>
</div>
<div>
主演:
<span v-for="el in item.actors" :key="el.id"
>{{ el.name }} </span
>
</div>
<div>
<span>{{ item.nation }}</span> |
<span>{{ item.runtime + "分钟" }}</span>
</div>
</div>
</div>
<!-- 按钮 -->
<div class="buy-ticket">
<div class="buy-ticket-btn">购票</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
import axios from "axios";
import BScroll from "better-scroll";
export default {
data() {
return {
pn: 1,
filmHeght: 0,
filmsList: [],
};
},
mounted() {
// this.filmHeght = document.documentElement.clientHeight - 81 + "px";
axios({
url: `https://m.maizuo.com/gateway?cityId=430100&pageNum=${this.pn}&pageSize=20&type=1&k=8865930`,
headers: {
"X-Client-Info":
'{"a":"3000","ch":"1002","v":"5.0.4","e":"16244625763360511261409281"}',
"X-Host": "mall.film-ticket.film.list",
},
}).then((res) => {
this.filmsList = res.data.data.films;
// 滚动加载
this.$nextTick(() => {
var myScroll = new BScroll(".my-film", {
scrollbar: {
fade: true, // 淡入淡出
interactive: false, //新增
},
pullUpLoad: {
threshold: 50,
},
});
myScroll.on("pullingUp", () => {
console.log("到底了");
});
});
});
},
methods: {
handleSwitch(row) {
this.$router.push("/about");
this.$store.commit("showFilmDetail", row);
},
},
};
</script>
电影详情组件:
<template>
<div class="film-detail">
<div class="film-card">
<div class="detail-top">
<img class="detail-top-img" :src="filmDetail.poster" alt="" />
</div>
<div class="detail-bottom-text">
<div class="film-name">
<span>{{ filmDetail.name }}</span>
<span>{{ filmDetail.filmType.name }}</span>
</div>
<div class="film-type">
<span>{{ filmDetail.category }}</span>
</div>
<div class="film-grade" v-if="filmDetail.grade">
<span>观众评分: </span>
<span>{{ filmDetail.grade }}</span>
</div>
<div class="film-nation">
<span>{{ filmDetail.nation }}</span> | 分钟
</div>
<div class="film-synopsis">
<div>
{{ filmDetail.synopsis }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
filmId: this.$store.state.filmDetail.filmId,
filmDetail: {},
time: new Date().getTime(),
};
},
methods: {},
mounted() {
// 请求接口数据
axios({
url: `https://m.maizuo.com/gateway?filmId=${this.filmId}&k=${this.time}`,
headers: {
"X-Client-Info":
'{"a":"3000","ch":"1002","v":"5.0.4","e":"16244625763360511261409281"}',
"X-Host": "mall.film-ticket.film.info",
},
}).then((res) => {
let data = res.data.data;
this.filmDetail = data.film;
});
console.log(this.filmDetail.poster);
},
};
</script>
由于空间有限,未贴出css样式代码,展示的即为该部分的效果。