生鲜网站策划,临潼区做网站的公司,深圳建筑工程交易服务主页,网站安全建设总结Vuex(vue) / Flux (angular) /Redux(react)
vuex 是什么? 状态管理工具 状态即数据, 状态管理就是管理组件中的data数据 Vuex 中的状态管理工具,采用了 集中式 方式统一管理项目中组件之间需要通讯的数据 [看图]
如何使用
最佳实践 : 只将组件之间共享的数据放在 vuex …Vuex(vue) / Flux (angular) /Redux(react)
vuex 是什么? 状态管理工具 状态即数据, 状态管理就是管理组件中的data数据 Vuex 中的状态管理工具,采用了 集中式 方式统一管理项目中组件之间需要通讯的数据 [看图]
如何使用
最佳实践 : 只将组件之间共享的数据放在 vuex 中, 而不是将所有的数据都放在 vuex 中 ,也就是说:如果数据只是在组件内部使用的,这个数据应该放在组件中,而不要放在 vuexvuex 中的数据也是响应式的,也就是说:如果一个组件中修改了 vuex 中的数据,另外一个使用的 vuex 数据的组件,就会自动更新 ( vuex 和 localstorage的区别)
什么时候用 ? 官网 说明: 项目体量很小,不需要使用 vuex, 如果项目中组件通讯不复杂,也不需要使用 vuex 只有写项目的时候,发现组件通讯多,组件之间的关系复杂,项目已经无法继续开发了,此时,就应该使用 vuex
Vuex的基本使用
1. vuex的基本使用
引入文件
script srcvue.js/script
script src./vuex.js/script使用 vuex 插件
// 和 router 一样 在工程化项目中 需要使用 use 安装一下
Vue.use(vuex)创建 store
const store new Vuex.Store()关联 vm 和 store
const vm new Vue({store, // 关联 storeel: #app,})2. state vuex通过state来提供数据 类似于组件的data 创建store的时候可以指定state const store new Vuex.Store({//1. state 是 vuex 用于提供数据的地方, 类似于组件的data , state中存放的是组件共享的数据//2. 在所有的组件, 都可以通过 this.$store.state 就能够访问vuex中state的数据//3. 只要vuex中state的数据发生了变化, 就会更新所有的组件 state: {name: hello,money: 1000,},})可以在任意组件的模板中访问到vuex中state的数据
p{{ $store.state.name }}/p
p{{ $store.state.money }}/p事件中
created() {console.log(this.$store.state.name)console.log(this.$store.state.money)},3. mutation
####3.1 演示报错
演示1 - 添加严格模式
const store new Vuex.Store({strict: true, # 添加严格模式state: {name: hello,money: 1000,},
})演示2 : 修改
p clickchangeName{{ $store.state.name }}/p
changeName() {this.$store.state.name 马哥console.log(this.$store.state.name)
},
# 报错 : [vuex] do not mutate vuex store state outside mutation handlers.
# 说明 : vuex中的数据不能直接修改, 需要在 mutation 里面才可以修改3.2 mutation使用
创建store的时候需要提供mutations
const store new Vuex.Store({state:{},mutations :{} # 添加
})mutation中所有的方法的第一个参数都是state 可以修改state里面的数据
// vuex 的 store
mutations : {// 修改 namechangeName(state) {state.name 马哥console.log(state.name)},// 修改 moneychangeMoney(state) {state.moneyconsole.log(state.money)},
}组件中不能直接修改state但是可以提交mutation类似于子组件触发事件
// 在点击的事件中 触发事件 提交 mutation// 点击事件
p clickchangeName{{ $store.state.name }}/p
p clickchangeMoney{{ $store.state.money }}/p
// vm 实例中methods: {changeName(state) {this.$store.commit(changeName)},changeMoney(state) {this.$store.commit(changeMoney)},},4. vuex 传参
传参
// 提交
this.$store.commit(changeName, {name: 6哥,})接收
// vuex 的 mutations 接收 参数
changeName(state, payload) {state.name payload.name},Todos 改造
Todos码云地址https://gitee.com/wang_yu5201314/tudos_potato_silk_case
1. 初始化项目
创建项目
vue create vuex-todos组件化开发 把结构和样式都拷贝过来并且引入组件分为三个组件 : TodoHeader TodoList TodosFooter
// App.vue
import TodoHeader from ./components/TodoHeader.vue;
import TodoList from ./components/TodoList.vue;
import TodoFooter from ./components/TodoFooter.vue;export default {components: {TodoHeader,TodoList,TodoFooter}
};// 结构
section classtodoapp!-- 头部 --todo-header/todo-header!-- 主体 --todo-list/todo-list!-- 底部 --todo-footer/todo-footer/section2. 配置 vuex
安装 vuex :
npm i vuex创建 store/index.js
import Vue from vue
import Vuex from vuexVue.use(Vuex) // 安装const state {list: [{ id: 1, name: 吃饭, done: true },{ id: 2, name: 睡觉, done: true },{ id: 3, name: 打豆, done: false },],
}const store new Vuex.Store({state,
})export default store
Todos 步骤
##1. 列表展示
li :class{completed : item.done} v-foritem in $store.state.list :keyitem.iddiv classviewinput classtoggle typecheckbox checked v-modelitem.done /label{{ item.name }}/labelbutton classdestroy/button/divinput classedit valueCreate a TodoMVC template //li##2. 删除任务
// vue 注册点击删除事件
del(id) {this.$store.commit(del, { id });
}// vuex store
// mutations
const mutations {del(state, playload) {let { id } playloadstate.list state.list.filter(v v.id ! id)},
}##3. 添加任务
// vueinputv-modeltodoName # keyup.enteraddTodo # classnew-todoplaceholderWhat needs to be done?autofocus/data() {return {todoName: # };},methods: {addTodo() {this.$store.commit(add, {name: this.todoName});this.todoName ;}}// vuex
const mutations {// 添加add(state, playload) {state.list.unshift({id: Date.now(),name: playload.name,done: false,})},
}##4. 修改任务
显示编辑框
//1. 准备 editId
data() {return {editId: -1};},
//2. 判断
li :class{completed : item.done ,editing : item.id editId }
//3. 双击显示showEdit(id) {this.editId id;} 回车 - 修改数据
// vue
input classedit :valueitem.name keyup.enterhideEdit(item.id,$event) /hideEdit(id, e) {this.$store.commit(updateName, {id,name: e.target.value});this.editId -1;} // vuex
const mutations {// 修改nameupdateName(state, playload) {let { id, name } playloadlet todo state.list.find(v v.id id)todo.name name},
}5. 修改状态
// vueinputclasstoggletypecheckbox:checkeditem.donechangeiptChange(item.id,$event)/
iptChange(id, e) {console.log(e.target.checked);this.$store.commit(iptChange, {id,checked: e.target.checked});}// vuex// 更新状态iptChange(state, playload) {let { id, checked } playloadlet todo state.list.find(v v.id id)todo.done checked # todo.done},##6. 计算属性(三个)
// 计算属性
const getters {// 底部的显示与隐藏isFooterShow(state) {return state.list.length 0},// 剩余未完成数itemLeftCount(state) {return state.list.filter(v !v.done).length},// 是否显示清除已完成isClearCompletedShow(state) {let b state.list.some(v v.done)console.log(b)return state.list.some(v v.done)},
}##7. 清除已经完成的任务
// vue!-- 清除已完成 --buttonclassclear-completedclick$store.commit(clear)v-show$store.getters.isClearCompletedShowClear completed/button// vuexclear(state) {state.list state.list.filter(v !v.done)},Action 的使用
官网介绍Action 类似于 mutation不同在于 Action 可以包含任意异步操作。Action 提交的是 mutation而不是直接变更状态。 mutaions 里不只能使用同步,不能出现异步 (演示删除任务 里使用setTimeout 会报错)演示1: actions 可以包含任意异步操作。 代码1演示2: actions 不能直接变更状态 , 代码2 会报错演示3 : actions 提交的是 mutation
// vuethis.$store.dispatch(addAsync, {name: this.todoName});// vuex - actions
const actions {// 添加 - 异步// store contextaddAsync(context, playload) {setTimeout(() {context.commit(add, playload)}, 3000)},
}// 添加add(state, playload) {state.list.unshift({id: Date.now(),name: playload.name,done: false,})},几个辅助函数
1. mapState 当一个组件需要获取多个状态的时候将这些状态都声明为计算属性会有些重复和冗余。 我们可以使用 mapState 辅助函数 将 store 中的 state 映射到局部计算属性 引入 mapState
import { mapState } from vuex;数组形式
// 如果本来就是有 计算属性 computed ,就不能全部使用 mapState 了
// 使用对象展开运算符将 state 混入 computed 对象中
computed: {// .... 之前 vue 里面的getTotal(){}// 维护 vuex...mapState([list])},let arr1 [1,2,3]
let arr [a,...arr1]let obj1 { list : [] }
let obj { name : 马哥, ...obj1 }
**对象形式 **- 取个名字
computed: {// .... 之前 vue 里面的// 维护 vuex...mapState({l :list})},2. mapGetters mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性 使用展开运算符将 getter 混入 computed 对象中 引入
import { mapGetters } from vuex;数组形式
computed: {// .... 之前 vue 的// 维护 vuex// 将 this.isFooterShow 映射为 this.$store.getters.isFooterShow...mapGetters([isFooterShow, itemLeftCount, isClearCompletedShow])}
// 使用
v-showisFooterShow
strong{{ itemLeftCount }}/strong item left对象形式 如果你想将一个 getter 属性另取一个名字使用对象形式 computed: {// .... 之前 vue 的// 维护 vuex...mapGetters([isFooterShow, itemLeftCount]),...mapGetters({// 把 this.isShow 映射为 this.$store.getters.isClearCompletedShowisShow: isClearCompletedShow // 起名字 })
}// 使用
button v-showisShowClear completed/button2. mapMutations 使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用需要在根节点注入 store 引入
import { mapState, mapMutations } from vuex;数组形式
methods: {// 讲 this.del() 映射为 this.$store.commit(del)...mapMutations([del,showEdit,hideEdit,iptChange])
}del(id) {// this.$store.commit(del, { id });this.del({id}) // 会造成死循环 改名字 },对象形式 : 如果你想将一个 methods 方法另取一个名字使用对象形式 methods: {// 将 this.del() 映射为 this.$store.commit(del)...mapMutations([showEdit, hideEdit, iptChange]),// 可以全部取名字 也可以改一个名字 // 将 this.d() 映射为 this.$store.commit(d) ...mapMutations({d: del}),del(id) {// this.$store.commit(del, { id });this.d({ id });}}3. mapActions 使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用 引入
import { mapActions } from vuex;数组形式 methods: {// 将 this.addAsync() 映射为 this.$store.dispatch(addAsync)...mapActions([addAsync]),addTodo() {this.addAsync({name: this.todoName});this.todoName ;}}对象形式 methods: {// // 将 this.a() 映射为 this.$store.dispatch(addAsync)...mapActions({a: addAsync}),addTodo() {this.a({name: this.todoName});this.todoName ;}}头条-vuex-动态设置keep-alive
设置 keep-alive的include属性改字符串为数组形式
// App.vue
// 之前 name 组件名
keep-alive includehome /keep-alive// 改之后
keep-alive :include[home] /keep-alive// 动态绑定
keep-alive :includecachelist /keep-alive// 数据
data(){return {cachelist : [home]}
}把 cachelist 放到 vuex中 配置 vuex const store new Vuex.Store({state: {cachelist: [home],},
})使用
// App.vue
computed: {...mapState([cachelist],
},keep-alive :includecachelistrouter-view/router-view
/keep-alive 需求 :
缓存首页的思路1. 只要进入到首页就应该把首页给缓存起来。2. 离开首页的时候需要判断了 如果进入的是详情页home组件依旧要被缓存。3. 离开首页的时候 如果进入的不是详情页home组件就不应该被缓存。添加两个 mutations的方法 mutations: {cache(state, playload) {// 如果缓存列表里面没有 name 就添加进去if (!state.cachelist.includes(playload.name)) {state.cachelist.push(playload.name)}},uncache(state, playload) {// 如果缓存列表里面 有 name , 就删除if (state.cachelist.includes(playload.name)) {state.cachelist state.cachelist.filter(v v ! playload.name) # 易错点}},},组件内导航守卫 - beforeRouteEnter - 进入之前
// Home.vue
import store from store// 路由跳转之前
beforeRouteEnter (to, from, next) {// this.$store.commit(cache) this 无法访问 因为还没有进入// 进入 home 把 home 添加到缓存列表store.commit(cache,{name :home})next()
}组件内导航守卫 - beforeRouteLeave - 离开之前
// Home.vue
// 离开 home 之前beforeRouteLeave(to, from, next) {if (to.name tabedit) {// 移除store.commit(uncache, {name: home,})}next()},