vue-day08 vuex
1.vuex
什么是vuex?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
1.安装
npm i vuex --save
2.引入 main.js
// import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
new Vue({
el: '#app',
router,
store:new Vuex.Store({
// 基础数据
state:{
name:'张三',
age:20
},
// 操作基础数据的方法 处理同步操作 state指的是当前的初始值
mutations:{
changeName(state){
state.name='李四'
}
},
// 处理异步操作 context 指的是当前的仓库
actions:{
changeN(context){
setTimeout(()=>{
context.commit('changeName')
},1000)
}
},
// 导出数据给组件使用 1.批量导出数据 2.可以得到计算属性
getters:{
name(state){
return state.name
},
sayHi(state){
return `我叫${state.name}`
},
age(state){
return state.age
}
}
}),
components: { App },
template: '<App/>'
})
3使用
a.vue
<div class="box">
<div>姓名:{{$store.state.name}}</div>
<div>年龄:{{$store.state.age}}</div>
//z这是触发mutations的方法 也就是同步操作
<button @click="$store.commit('changeName')">点击修改姓名为:李四</button>
//触发actions方法,也就是异步操作
<button @click="$store.dispatch('changeN')">通过action触发修改name</button>
</div>
4.getters
main.js中
// 导出数据给组件使用 1.批量导出数据 2.可以得到计算属性
getters:{
name(state){
return state.name
},
sayHi(state){
return `我叫${state.name}`
},
age(state){
return state.age
}
}
5.getters使用
c.vue
<div>getters:姓名:{{$store.getters.name}}</div>
<div>getters:计算属性{{$store.getters.sayHi}}</div>
<div>getters:年龄{{$store.getters.age}}</div>
6.辅助函数
mapGetters–>computed
mapActions-.>methods
import {mapGetters,mapActions} from 'vuex'
computed:{
// 如果以数组方式导出,那么getters里面的名字要与导出的一致
// ...mapGetters([
// 'name',
// 'sayHi',
// 'age'
// ])
// 第二种导出方式
...mapGetters({
myname:'name',
mysayHi:'sayHi',
myage:'age'
})
},
methods:{
...mapActions({
changeM:'changeM'
})
},
注意:
-
mapActions导出的数据只能修改store中的actions里面定义的方法,同时需要在mutations定义一个方法用来真正的修改state的值
2.单向数据流,所以不能应用于表单元素
重点:单向数据流,过程不可逆,也就是说 mutations不能修改actions
1.创建项目
2.清空项目
3.初始化项目(reset.css)
4.安装依赖 (axios vuex qs)
5.创建组件 (home,food,foodDetail,movie,movieDetail)
6.配置路由
7.uitl-》request.js 写的是所有的axios请求
import axios from 'axios'
import qs from 'qs'
const baseUrl = '/api'
// 拦截器
axios.interceptors.response.use(res=>{
console.log('=========请求地址:'+res.config.url+'==============')
console.log(res)
return res
})
// 电影列表
export const reqMovie=()=>{
return axios({
url:baseUrl+'/movie',
method:'get'
})
}
// 电影详情
export const reqMovieDetail=(params)=>{
return axios({
url:baseUrl+'/getMovieDetail',
method:'get',
params:qs.stringify(params)
})
}
// 美食列表
export const reqFoodList=()=>{
return axios({
url:baseUrl+'/foodList',
method:'get',
})
}
// 美食详情
export const reqFoodDetail=(id)=>{
return axios({
url:baseUrl+'/getFoodDetail',
method:'get',
params:id
})
}
8.创建仓库(store->index.js)
import Vue from 'vue'
import Vuex from 'vuex'
import { reqMovie ,reqMovieDetail,reqFoodList,reqFoodDetail} from '../util/request'
Vue.use(Vuex)
const state = {
movies: [],//电影的初始值,
movieDetail:{}, //电影详情的初始值
foods:[],
foodDetail:{}
}
const mutations = {
// 获取电影列表
getMovieList(state,arr) {
state.movies = arr
},
// 获取电影详情
getMovieDetail(state,obj){
state.movieDetail=obj
},
// 获取美食列表
getFoodList(state,arr){
state.foods = arr
},
// 获取美食详情
getFoodDetail(state,obj){
state.foodDetail = obj
}
}
const actions = {
// 异步请求movie数据
requestMovie(context) {
reqMovie().then(res => {
console.log(res)
context.commit('getMovieList',res.data.data)
})
},
// 异步请求movie详情数据
requsetMovieDetail(context,id){
reqMovieDetail(id).then(res=>{
console.log(res)
context.commit('getMovieDetail',res.data.detail)
})
},
// 美食列表
requestFood(context){
reqFoodList().then(res=>{
console.log(res)
context.commit('getFoodList',res.data.data)
})
},
// 美食详情
requestFoodDetail(context,id){
reqFoodDetail(id).then(res=>{
console.log(res)
context.commit('getFoodDetail',res.data.detail)
})
}
}
const getters = {
movies(state){
return state.movies
},
movieDetail(state){
return state.movieDetail
},
foods(state){
return state.foods
},
foodDetail(state){
return state.foodDetail
}
}
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
9.movie.vue
<template>
<div>
<h2>电影列表</h2>
<ul>
<li is='router-link' :to="'/movieDetail?id='+item.id" v-for='item in movies' :key='item.id'>
<div>电影名称:{{item.name}}</div>
<div>电影价格:{{item.price}}</div>
</li>
</ul>
</div>
</template>
<script>
import {mapGetters,mapActions} from 'vuex'
export default {
computed:{
...mapGetters({
movies:'movies'
})
},
components:{
},
data () {
return {
}
},
methods:{
...mapActions({
requestMovie:'requestMovie'
})
},
mounted(){
this.requestMovie()
}
}
</script>
<style scoped>
</style>
10.movieDetail.vue
<template>
<div>
<h3>电影详情</h3>
<img :src="movieDetail.img" alt="">
<div>电影名称:{{movieDetail.name}}</div>
<div>{{movieDetail.price}}</div>
</div>
</template>
<script>
import {mapActions,mapGetters} from 'vuex'
export default {
computed:{
...mapGetters({
movieDetail:'movieDetail'
})
},
components:{
},
data () {
return {
}
},
methods:{
...mapActions({
requsetMovieDetail:'requsetMovieDetail'
})
},
mounted(){
var id = this.$route.query.id
console.log(id)
this.requsetMovieDetail({'id':id})
}
}
</script>
<style scoped>
</style>
注意:
1.详情页传值。需要在store中有接收的位置
2.?传参 用query获取id
/传参 用params获取id