vue3中ref函数和reactive函数
1、ref函数
- 作用:定义一个响应式的数据
- 语法:const xx = ref(initValue)
创建一个包含响应式数据的引用对象(reference对象,简称ref对象)
js中操作数据:xxx.value
模版中读取数据:不需要.value,直接:<div>{{xxx}}</div>
- 备注
接受的数据可以是:基本类型,也可以是对象类型
基本数据类型:响应式依然是靠object.defineProperty()的get与set完成
对象类型的数据:内部求助了vue3.0的新函数——reactive函数
2、reactive函数
- 作用:定义一个对象类型的响应式数据(基本类型不用这个,用ref函数)
- 语法:const 代理对象 = reactive(源对象) (接收一个对象/数据,返回一个代理对象proxy的实例对象,简称proxy对象)
- reactive定义的响应式数据是“深层次的”
- 内部基于es6的proxy实现,通过代理对象源对象内部数据进行操作
3、reactive对比ref
- 从定义数据角度对比:
ref定义基本类型数据,也可以定义对象/数据类型数据,内部会通过reactive转换会代理对象
reactive定义对象/数据类型数据
- 从定义原理角度对比:
ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)
reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据
- 从定义使用角度对比:
ref定义的数据:操作数据需要.value,读取数据时膜拜中直接读取
reactive定义的数据:操作数据与读取数据均直接写/读取
vue3中事件处理
内部进行柯里化,可以直接调用传参
- 获取默认事件传参可以用$event
- 也可以使用箭头函数
- 可以用逗号分隔多个函数,⚠️每个函数都需要显式调用
vue3中watch、watchEffect的详解
此篇讲解好
https://blog.csdn.net/ZYS10000/article/details/124535467
vuex与pinia
vuex
pinia
挂载
- vuex
// 新建vuexStore/index.js import { createStore } from 'vuex' export default createStore({ //全局state,类似于vue种的data state() { return { vuexmsg: "hello vuex", name: "xiaoyue", }; }, //修改state函数 mutations: { }, //提交的mutation可以包含任意异步操作 actions: { }, //类似于vue中的计算属性 getters: { }, //将store分割成模块(module),应用较大时使用 modules: { } })
// main.js引入 import { createApp } from 'vue' import App from './App.vue' import store from '@/store' createApp(App).use(store).mount('#app')
// App.vue测试 <template> <div></div> </template> <script setup> import { useStore } from 'vuex' let vuexStore = useStore() console.log(vuexStore.state.vuexmsg); //hello vuex </script>
- pinia
// src下新建piniaStore/storeA.js export const storeA = defineStore("storeA", { state: () => { return { piniaMsg: "hello pinia", }; }, getters: {}, actions: {}, });
// main.js引入 import { createApp } from "vue"; import App from "./App.vue"; import {createPinia} from 'pinia' const pinia = createPinia() createApp(App).use(pinia).mount("#app");
// App.vue使用 <template> <div></div> </template> <script setup> import { storeA } from '@/piniaStore/storeA' let piniaStoreA = storeA() console.log(piniaStoreA.piniaMsg); //hello pinia </script>
- 比较
- pinia中没有mutations和modules
- vuex通过moudles引入模块,pinia每个store就是一个模块storeA,storeB……
- vuex每次修改state的值都需要调用mutations里的修改函数,因为需要追踪数据的变化;pinia同步异步都可以在action中进行操作
修改状态
- vuex
在组件中直接修改state,vuex不能够记录每一次state的变化记录,影响我们的调试
1、所有的state变更都在vuex内部进行,在mutations进行修改
// vuexStore/index.js import { createStore } from "vuex"; export default createStore({ strict: true, //全局state,类似于vue种的data state: { vuexmsg: "hello vuex", }, //修改state函数 mutations: { setVuexMsg(state, data) { state.vuexmsg = data; }, }, //提交的mutation可以包含任意异步操作 actions: {}, //类似于vue中的计算属性 getters: {}, //将store分割成模块(module),应用较大时使用 modules: {}, });
// App.vue <template> <div>{{ vuexStore.state.vuexmsg }}</div> </template> <script setup> import { useStore } from 'vuex' let vuexStore = useStore() vuexStore.commit('setVuexMsg', 'hello juejin') console.log(vuexStore.state.vuexmsg) //hello juejin </script>
2、在actions中进行提交mutations修改state
import { createStore } from "vuex"; export default createStore({ strict: true, //全局state,类似于vue种的data state() { return { vuexmsg: "hello vuex", } }, //修改state函数 mutations: { setVuexMsg(state, data) { state.vuexmsg = data; }, }, //提交的mutation可以包含任意异步操作 actions: { async getState({ commit }) { //const result = await xxxx 假设这里进行了请求并拿到了返回值 commit("setVuexMsg", "hello juejin"); }, } });
// 组件中使用dispatch进行分发actions <template> <div>{{ vuexStore.state.vuexmsg }}</div> </template> <script setup> import { useStore } from 'vuex' let vuexStore = useStore() vuexStore.dispatch('getState') </script>
- pinia
1、直接修改状态的,并且调试工具能够记录到每一次state的变化
// App.vue <template> <div>{{ piniaStoreA.piniaMsg }}</div> </template> <script setup> import { storeA } from '@/piniaStore/storeA' let piniaStoreA = storeA() console.log(piniaStoreA.piniaMsg); //hello pinia piniaStoreA.piniaMsg = 'hello juejin' console.log(piniaStoreA.piniaMsg); //hello juejin </script>
2、使用$patch方法可以修改多个state中的值
// 在piniaStore/storeA.js中的state增加一个name import { defineStore } from "pinia"; export const storeA = defineStore("storeA", { state: () => { return { piniaMsg: "hello pinia", name: "xiaoyue", }; }, getters: {}, actions: {}, });
// 在App.vue中进行修改这两个state import { storeA } from '@/piniaStore/storeA' let piniaStoreA = storeA() console.log(piniaStoreA.name); //xiaoyue piniaStoreA.$patch({ piniaMsg: 'hello juejin', name: 'daming' }) console.log(piniaStoreA.name);//daming
// 修改单个状态 piniaStoreA.$patch({ name: 'daming' })
// 还可以使用函数的方式进行修改状态 import { storeA } from '@/piniaStore/storeA' let piniaStoreA = storeA() cartStore.$patch((state) => { state.name = 'daming' state.piniaMsg = 'hello juejin' })
3、在actions中进行修改(推荐)
// 在piniaStore/storeA.js的actions添加一个修改name的函数 import { defineStore } from "pinia"; export const storeA = defineStore("storeA", { state: () => { return { piniaMsg: "hello pinia", name: "xiao yue", }; }, actions: { setName(data) { this.name = data; }, }, });
// 组件App.vue中调用不需要再使用dispatch函数,直接调用store的方法即可 import { storeA } from '@/piniaStore/storeA' let piniaStoreA = storeA() piniaStoreA.setName('daming')
4、可以重置state
// Pinia可以使用$reset将状态重置为初始值 import { storeA } from '@/piniaStore/storeA' let piniaStoreA = storeA() piniaStoreA.$reset()
- 比较
- vuex在组件中直接修改state,不能够记录每一次state的变化记录;但pinia可以,并提供了$patch操作,可单/多个修改。
- vuex在mutations中修改state,actions中提供异步调用;pinia在actions中修改,支持同步/异步。
- vuex使用actions中的方法需使用dispatch函数;pinia直接调用store的方法。
- pinia提供$reset将状态重置为初始值。
pinia解构(storeToRefs)
在pinia中,若通过解构的方式取值,会使state失去响应式。此时需要使用一个结构方法storeToRefs
<template> <div>{{ name }}</div> </template> <script setup> import { storeA } from '@/piniaStore/storeA' import { storeToRefs } from 'pinia' let piniaStoreA = storeA() let { piniaMsg, name } = storeToRefs(piniaStoreA) piniaStoreA.$patch({ name: 'daming' }) </script>
getters方法
vuex中getters和pinia中的getters用法是一致的,用于自动监听对应state的变化。从而动态计算返回值,且具有缓存特性。
- vuex
import { createStore } from "vuex"; export default createStore({ strict: true, //全局state,类似于vue种的data state: { count1: 1, count2: 2, }, //类似于vue中的计算属性 getters: { sum(state){ return state.count1 + state.count2 } } });
- pinia
import { defineStore } from "pinia"; export const storeA = defineStore("storeA", { state: () => { return { count1: 1, count2: 2, }; }, getters: { sum() { console.log('我被调用了!') return this.count1 + this.count2; }, }, });
modules
切割成模块,每个模块拥有自己的state,mutations,action……
- vuex
// 每个module都会新建一个文件,然后再引入这个总的入口index.js中 export default createStore({ strict: true, //全局state,类似于vue种的data state() { return { vuexmsg: "hello vuex", name: "xiaoyue", }; }, modules: { moduleA, moduleB }, });
- pinia
// 直接定义多个store传入不同的id即可 import { defineStore } from "pinia"; export const storeA = defineStore("storeA", {...}); export const storeB = defineStore("storeB", {...}); export const storeC = defineStore("storeB", {...});
- 对比
- Pinia没有modules,如果想使用多个store,直接定义多个store传入不同的id即可
- vuex每个module都会新建一个文件,然后再引入这个总的入口index.js中,为了防止提交一些mutation或者actions中的方法重名,modules一般会采用命名空间的方式 namespaced: true
标签:vue,storeA,学习,state,pinia,import,vuex From: https://www.cnblogs.com/marilol/p/16866934.html