1、在 mian.js 导入?pinia 里的?createPinia 函数。
2、app.use 这个?createPinia 函数的返回值。
// main.js
import { createPinia } from 'pinia';
app.use(createPinia());
3、创建一个 js 文件(该文件保存着共享的数据,共享的方法),惯例上会叫该 js 文件为?store。
4、在?store 文件里,从 pinia 里导入 defineStore 函数(该函数是定义 store 的函数)。
5、在?defineStore 函数的第二个参数定义共享的数据和方法。
6、用?export 导出 defineStore 函数的返回值,该返回值是一个函数,在这里我命名该函数为 useUserStore。
// userStore.js
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => {
return {
name: '李小明',
age: 18,
hobby: 'basketball'
}
},
getters: {
// this 形式
// doubleAge() {
// return this.age * 2
// },
doubleAge: (state) => {
return state.age * 2
}
},
actions: {
changeAge() {
this.age = 16
},
}
});
7、在需要该 store 里的数据和方法的 vue 文件里导入该 useUserStore 函数。
8、在 vue 文件里使用?setup 函数,在?setup 函数里运行一次 useUserStore 函数,并把该 useUserStore 函数的返回值赋予给一个变量,该变量保存着上面?defineStore 函数定义的共享的数据和方法。
10、在?setup 函数里 return 该变量,该变量就会被 vue 实例代理(即 this)。
<template>
<div>
<p>姓名:{{ userStore.name }}</p>
<p>年龄:{{ userStore.age }}</p>
<p>爱好:{{ userStore.hobby }}</p>
<p>双倍年龄:{{ userStore.doubleAge }}</p>
<p>计算属性:{{ getName }}</p>
<div>
<button @click="userStore.changeAge">userStore 的 changeAge 方法,点击改变年龄</button>
</div>
<div style="margin: 10px 0;">
app 的按钮<button @click="consoleName" style="margin-left: 5px;">点击我</button>
</div>
</div>
</template>
<script>
import { useUserStore } from './store/userStore.js';
export default {
setup() {
const userStore = useUserStore();
return {
userStore // 导出 userStore,userStore 会被 vue 实例代理,即 this。
}
},
data() {
return {
}
},
methods: {
consoleName() {
console.log(this.userStore.name); // 通过 this 访问 userStore
}
},
computed: {
getName() {
return this.userStore.name // 通过 this 访问 userStore
}
}
}
</script>
<style></style>
温馨提示: store 会保存在组件实例的?_pStores 属性里。
userStore.js(全局状态文件)
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
// 箭头函数
state: () => {
return {
name: '李小明',
age: 18,
hobby: 'basketball'
}
},
// 普通函数
// state() {
// return {
// name: '李小明',
// age: 18,
// hobby: 'basketball'
// }
// },
getters: {
// this 形式
// doubleAge() {
// return this.age * 2
// },
// 参数形式
doubleAge: (state) => {
return state.age * 2
}
},
actions: {
changeAge() {
this.age = 16
},
}
});
App.vue
<template>
<div>
<p>姓名:{{ userStore.name }}</p>
<p>年龄:{{ userStore.age }}</p>
<p>爱好:{{ userStore.hobby }}</p>
<p>双倍年龄:{{ userStore.doubleAge }}</p>
<p>计算属性:{{ getName }}</p>
<div style="margin: 10px 0;">
<button @click="userStore.changeAge">userStore 的 changeAge 方法,点击改变年龄</button>
</div>
<div style="margin: 10px 0;">
app 的按钮<button @click="consoleName" style="margin-left: 5px;">点击我</button>
</div>
<div style="border: 1px solid skyblue;padding: 10px ;">
<HelloWorld></HelloWorld>
</div>
</div>
</template>
<script>
import { useUserStore } from './store/userStore.js';
import HelloWorld from './components/HelloWorld.vue';
export default {
setup() {
const userStore = useUserStore();
return { userStore }
},
components: {
HelloWorld
},
mounted() {
},
data() {
return {
}
},
methods: {
consoleName() {
console.log(this.userStore.name);
}
},
computed: {
getName() {
return this.userStore.name
}
}
}
</script>
<style></style>
子组件 HelloWorld.vue
<template>
<p>我是子组件</p>
<p>userStore.age 等于 {{ userStore.age }}</p>
<button @click="changeAge">我是子组件按钮</button>
</template>
<script>
import { useUserStore } from '../store/userStore.js';
export default {
setup() {
const userStore = useUserStore(); // 整体导出
const changeAge = userStore.changeAge; // 单独导出一个方法
return {
userStore,
changeAge
}
},
data() {
return {
}
},
methods: {
}
}
</script>
<style></style>
state 的值是一个函数。
state 相当于 data,是我们需要在组件之间共享的数据。
普通方法
state() {
return {
name: '李小明',
age: 18,
hobby: 'basketball'
}
},
箭头函数
state: () => {
return {
name: '李小明',
age: 18,
hobby: 'basketball'
}
},
在 TypeScript 中使用箭头函数将自动推断这些属性的类型。
getters 的值是一个对象。
getter 相当于计算属性,计算的结果会被缓存下来,只有当依赖的值发生改变才会重新计算。
使用第一个参数 state 可以访问 state?
getters: {
doubleAge(state) {
return state.age * 2
},
}
也可以在普通函数里使用 this,从而访问到整个 pinia 实例(所以可以在 getter 里访问另外的 getter),
getters: {
doubleAge() {
return this.age * 2 // this(pinia 实例) 代理了 state 里的属性
},
}
但是在箭头函数里,因为箭头函数里 this 的指向问题,所以箭头函数只能使用第一个参数 state 来访问 state,
getters: {
doubleAge: (state) => {
return state.age * 2
}
}
actions 的值是一个对象。
action 相当于方法。
普通函数可以通过 this 访问 pinia 实例
actions: {
changeAge() {
this.age = 16
},
}
因为箭头函数的 this 的问题,Action?里使用箭头函数访问 pinia 实例是不行的。