首页 > 其他分享 >Vue:Vuex-Store使用指南

Vue:Vuex-Store使用指南

时间:2024-08-13 22:52:23浏览次数:17  
标签:Vue console log state 使用指南 Vuex store

一、简介

1.1Vuex 是什么

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

1.2 什么是“状态管理模式”?

一个简单的 Vue 计数应用开始:

new Vue({
  // state
  data () {
    return {
      count: 0
    }
  },
  // view
  template: `
    <div>{{ count }}</div>
  `,
  // actions
  methods: {
    increment () {
      this.count++
    }
  }
})

这个状态自管理应用包含以下几个部分:

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

以下是一个表示“单向数据流”理念的简单示意:
在这里插入图片描述

但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

  • 多个视图依赖于同一状态。
  • 来自不同视图的行为需要变更同一状态。

对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。
对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!

通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。

这就是 Vuex 背后的基本思想,借鉴了 Flux (opens new window)、Redux (opens new window)和 The Elm Architecture (opens new window)。与其他模式不同的是,Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。

在这里插入图片描述

二、什么情况下我应该使用 Vuex?

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式 就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

三、安装

3.1 直接下载 / CDN 引用

https://unpkg.com/vuex
https://unpkg.com/ , 提供了基于 NPM 的 CDN 链接。以上的链接会一直指向 NPM 上发布的最新版本。您也可以通过 https://unpkg.com/[email protected] 这样的方式指定特定的版本。

在 Vue 之后引入 vuex 会进行自动安装:

<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>
3.2 NPM

npm install vuex --save

3.3 Yarn
yarn add vuex

在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来安装 Vuex:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

四、最简单的 Store(Vuex 记数应用)实例

提醒:下面实例是在TestVue2的项目里运行的

4.1 TestVue2项目结构图

在这里插入图片描述

4.2 安装 vuex @3.1.0
npm install [email protected]

安装成功后,查看package.json文件
在这里插入图片描述

4.3 创建一个 store

安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 state 对象和一些 mutation:

store文件夹里index.js文件代码

import Vue from 'vue'
import Vuex from 'vuex'
// 全局
Vue.use(Vuex)
// https://www.jb51.net/javascript/297247rzd.htm
//  https://blog.csdn.net/weixin_44904953/article/details/129159961

// export default new Vuex.Store({
const store = new Vuex.Store({
	namespaced: true,
	state: {
		count: 0,
	},
	mutations: {
		increment(state) {
			state.count++
		},
		decrement: state => state.count--,
		
		getCount(state){
			return state.count
		},
	},

	actions: {
		// 异步任务 store.dispatch
		tryactions(context, val) { //第一个参数是context固定不变,第二个是自定义参数
			setTimeout(() => {
				context.commit('increment') //调用mutations中的方法修改state中的数据
			}, val);
		},
	},
	
	getters: {
		
	},

})

export default store;

现在,你可以通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更:

store.commit('increment')

console.log(store.state.count) // -> 1
4.4 注入store

为了在 Vue 组件中访问 this.$store property,你需要为 Vue 实例提供创建好的 store。Vuex 提供了一个从根组件向所有子组件,以 store 选项的方式“注入”该 store 的机制:

在store文件里index.js里使用了Vue.use(Vuex),接下来在main.js将index.js导入

main.js文件代码

import Vue from 'vue'
import App from './App.vue'
// 将 Vuex Store 注入到应用中
import store from './store'
import router from './router'
Vue.config.productionTip = false
// Vue.prototype.$store = store

// https://www.jb51.net/javascript/297247rzd.htm
// 如果使用 ES6,你也可以以 ES6 对象的 property 简写 (用在对象某个 property 的 key 和被传入的变量同名时):
new Vue({
	router,
	store,
	render: h => h(App),
}).$mount('#app')

// 使用 ES2015 语法
// new Vue({
// 	router: router,
// 	store: store,
// 	render: h => h(App),
// }).$mount('#app')

再次强调,我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。

由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutation。

4.4 创建两个vue文件

teststore1.vue代码

<template>
	<div>
		<h1>store 1 数量:{{this.$store.state.count}}</h1>
		<!-- <h1>getComputedCount 数量:{{getComputedCount}}</h1> -->
		<h1>mapState 数量:{{count}}</h1>
		<button @click="increment">+</button>
		<button @click="decrement">-</button>
		</br>
		<button @click="doactions">点击两秒后数量自动加1</button>
		<br />
		<br />
		<p>
			<button v-on:click="getCount">获取localCount最新值</button>
			获取到的数量:{{localCount}}
		</p>
		<br />
		<br />
		<button @click="openTest2Page">打开test2页面</button>

	</div>
</template>

<script>
	import {
		mapState
	} from 'vuex'
	export default {
		name: 'teststore1',
		data() {
			return {
				localCount: 0,
			}
		},
		computed: {
			...mapState([
				'count',
			]), //推荐这种方式
		},
		
		// watch: {
		// 	count: {
		// 		handler(newVal, oldVal) {
		// 			console.log(`teststore1 watch 新的值: ${newVal} , 旧的值: ${oldVal}`)
		// 		},
		
		// 	}
		// },
		
		created() {
			console.log("teststore1 执行了 created ")
		},
		
		activated() {
			console.log("teststore1 执行了 activated ")
		},
		
		mounted() {
			console.log("teststore1 执行了 mounted ", this.$store)
		},
		
		beforeUpdate() {
			console.log("teststore1 执行了 beforeUpdate ")
		},
		
		updated() {
			console.log("teststore1 执行了 updated ")
		},
		
		beforeDestroy() {
			console.log("teststore1 执行了 beforeDestroy ")
		},
		
		destroyed() {
			console.log("teststore1 执行了 beforeDestroy ")
		},
		
		methods: {
			increment() {
				this.$store.commit('increment')
			},

			decrement() {
				this.$store.commit('decrement')
			},
			// // 异步任务 store.dispatch	
			doactions() {
				this.$store.dispatch('tryactions', 2000)
			},

			getCount() {
				this.localCount = this.$store.state.count
				console.log("执行了 getCount this.localCount = ", this.localCount)
			},
			
			openTest2Page(){
				this.$router.push('/teststore2')
			},
		}

	}
</script>

<style>
	button {
		margin-left: 1.25rem;
		margin-top: 1.0rem;
	}
</style>

teststore2.vue代码

<template>
	<div>
		<!-- <h1>store 2 数量:{{this.$store.state.count}}</h1> -->
		<h1>store 2 数量:{{count}}</h1>
		<button @click="increment">+</button>
		<button @click="decrement">-</button>
		<button @click="goBack">返回到上个页面</button>

	</div>
</template>

<script>
	import {
		mapState
	} from 'vuex'
	export default {
		name: 'teststore2',
		data() {
			return {
				mCount: 0,
			}
		},
		
		created() {
			console.log("teststore2 执行了 created ")
		},
		
		activated() {
			console.log("teststore2 执行了 activated ")
		},
		
		mounted() {
			console.log("teststore2 执行了 mounted ", this.$store)
		},
		
		beforeUpdate() {
			console.log("teststore2 执行了 beforeUpdate ")
		},
		
		updated() {
			console.log("teststore2 执行了 updated ")
		},
		
		beforeDestroy() {
			console.log("teststore2 执行了 beforeDestroy ")
		},
		
		destroyed() {
			console.log("teststore2 执行了 beforeDestroy ")
		},
		
		computed: {
			...mapState([
				'count',
			]),
		},

		mounted() {
			console.log("teststore2 执行了 mounted ",this.$store)
		},
		methods: {
			increment() {
				this.$store.commit('increment')
			},

			decrement() {
				this.$store.commit('decrement')
			},
			
			goBack(){
				this.$router.replace('/teststore1')
			}
		}

	}
</script>

<style>
	button {
		margin-left: 1.25rem;
	}
</style>

五、启动TestVue2项目

TestVue2使用了vue-router,可参考vue-router使用指南

在终端里输入下面命令:
提醒:因为电脑里node版本问题,前面加了NODE_OPTIONS=–openssl-legacy-provider

NODE_OPTIONS=--openssl-legacy-provider npm run serve

在这里插入图片描述

六、效果图

home.vue页面

在这里插入图片描述
teststore1.vue页面
在这里插入图片描述

在这里插入图片描述
teststore2.vue页面
在这里插入图片描述

在这里插入图片描述

点击返回到上个页面(teststore2.vue)
在这里插入图片描述

七、TestVue2项目源码

点击查看TestVue2源码

标签:Vue,console,log,state,使用指南,Vuex,store
From: https://blog.csdn.net/ChinaDragon10/article/details/141143969

相关文章

  • vue事件绑定
    为元素添加属性命令:v-on:事件名=“方法名”,而方法则需要再Vue配置里面的methods属性里定义。主要的事件名有click、dbclick,mouseover,mouseout,keydown,keypress,blur,focus<buttonv-on:click="fn1">我是按钮2--vue事件绑定</button>这个fn1事件函数,需要再methods中进行定义。......
  • Vue3如何使用v-model写一个多条件联合搜索
    在Vue3中,使用v-model进行多条件联合搜索通常涉及到绑定多个输入字段到组件的数据属性上,并在搜索逻辑中根据这些属性的值来过滤数据。虽然v-model本身是针对单个表单元素进行双向数据绑定的,但你可以通过结合使用多个v-model和计算属性或方法来处理多条件搜索。以下是一个简单......
  • 动态组件,插槽,vue项目创建,vue项目目录结构,vue开发规范,es6语法
    Ⅰ动态组件【一】基本使用【1】不使用动态组件<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>动态组件</title><scriptsrc="./js2/vue.js"></script></head><......
  • 计算机毕设&毕设项目&毕业设计:基于springboot+vue校园宿舍管理系统
    一、前言        传统的宿舍管理往往依赖于纸质记录和人工操作,这种方式不仅效率低下,而且容易出现错误。随着学生数量的增长和管理需求的多样化,这种传统模式已经难以满足当前的需求。基于此背景,引入SpringBoot作为后端框架和Vue.js作为前端框架,结合数据库技术和云计算......
  • 计算机毕设&毕设项目&毕业设计:基于SpringBoot+Vue实现人事管理系统
    一、前言        在当今快节奏的企业环境中,有效的人力资源管理是组织成功的关键。随着数字化转型的加速,基于现代技术栈的人事管理系统成为了提升HR部门效率、优化员工体验的必要工具。本文将介绍如何利用SpringBoot和Vue.js这两种流行的技术,构建一个高效、灵活且用户......
  • 基于springboot的大学生个人财务收入支出管理系统-JAVA.VUE【全套源码论文】
     博主介绍:......
  • 基于springboot的电商购物在线商城系统-JAVA.VUE【全套源码论文】
     博主介绍:......
  • vue使用JavaScript运算符
    第一:加法运算符{{变量+n}}<p>num参与运算{{num+12}}</p>letvm=newVue({el:"#app",data:{num:101,isOK:true,message:'你......
  • vue绑定属性的指令
    前面学习的插值表达式{{}},并不能更改标签的属性。因此,以下的写法是错误的,<h1titlle="{{title}}">我是h1标签的内容</h1>如果想要给标签的属性绑定动态值,需要借助v-bind的指令语法:v-bind:原生HTML标签的属性="data中定义的值",可以在vscode直接写vbind会自动加载,如下:......
  • springboot+vue+mybatis计算机毕业设计汉服商城网站+PPT+论文+讲解+售后
    本系统为用户而设计制作“梦回汉唐”汉服商城网站,旨在实现“梦回汉唐”汉服商城网站智能化、现代化管理。本“梦回汉唐”汉服商城网站自动化系统的开发和研制的最终目的是将“梦回汉唐”汉服商城网站的运作模式从手工记录数据转变为网络信息查询管理,从而为现代管理人员的使用提......