Open shldhee opened 2 years ago
npm install pinia
vue-cli 사용시
vue add vue-cli-plugin-pinia
// app.ts
import { createPinia } from 'pinia'
app.use(createPinia())
import { createPinia } from 'pinia'
createApp(App)
.use(createPinia())
.mount("#app");
// store/main.ts
import { defineStore } from 'pinia'
// useStore could be anything like useUser, useCart
// the first argument is a unique id of the store across your application
export const useStore = defineStore('main', {
// other options...
})
defineStore
첫번째 인수는 고유이름import { useStore } from '@/stores/counter'
export default {
setup() {
const store = useStore()
return {
// you can return the whole store instance to use it in the template
store,
}
},
}
// 작동하지 않는다. 반응성을 깨뜨린다.
// ❌ This won't work because it breaks reactivity
// it's the same as destructuring from `props`
const { name, doubleCount } = store
<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";
import { generateFakeData, Item } from "./models/item.model";
import { useMainStore } from "./store/index";
export default defineComponent({
name: "App",
setup() {
const items = ref<Item[]>([]);
const mainStore = useMainStore();
onMounted(() => {
items.value = mainStore.items;
});
function createItem() {
mainStore.createNewItem(generateFakeData());
}
function deleteItem(id: string) {
mainStore.deleteItem(id);
}
function updateItem(id: string) {
mainStore.updateItem(id, generateFakeData());
}
return {
items,
createItem,
deleteItem,
updateItem,
};
},
});
</script>
mport { storeToRefs } from 'pinia'
export default defineComponent({
setup() {
const store = useStore()
// `name` and `doubleCount` are reactive refs
// This will also create refs for properties added by plugins
// but skip any action or non reactive (non ref/reactive) property
const { name, doubleCount } = storeToRefs(store)
return {
name,
doubleCount
}
},
})
import { defineStore } from 'pinia'
const useStore = defineStore('storeId', {
// arrow function recommended for full type inference
state: () => {
return {
// all these properties will have their type inferred automatically
counter: 0,
name: 'Eduardo',
isAdmin: true,
}
},
})
const store = useStore()
store.counter++
const store = useStore()
store.$reset()
store.$patch({
counter: store.counter + 1;
name: 'Abalam',
위와 같이 하면 모든 컬렉션 수정할때 비용이 많이 든다. 아래처럼 함수로 한다.
cartStore.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 })
state.hasChanged = true
})
cartStore.$subscribe((mutation, state) => {
// import { MutationType } from 'pinia'
mutation.type // 'direct' | 'patch object' | 'patch function'
// same as cartStore.$id
mutation.storeId // 'cart'
// only available with mutation.type === 'patch object'
mutation.payload // patch object passed to cartStore.$patch()
// persist the whole state to the local storage whenever it changes
localStorage.setItem('cart', JSON.stringify(state))
})
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
})
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
// automatically infers the return type as a number
doubleCount(state) {
return state.counter * 2
},
// the return type **must** be explicitly set
doublePlusOne(): number {
// autocompletion and typings for the whole store ✨
return this.counter * 2 + 1
// return this.doubleCount + 1
},
},
})
this
가 뭔지 찍어보기 전체 store같음 여기서 다른 getter구할듯?export const useStore = defineStore('main', {
getters: {
getUserById: (state) => {
return (userId) => state.users.find((user) => user.id === userId)
},
},
})
<script>
export default {
setup() {
const store = useStore()
return { getUserById: store.getUserById }
},
}
</script>
<template>
User 2: {{ getUserById(2) }}
</template>
export const useStore = defineStore('main', {
getters: {
getActiveUserById(state) {
const activeUsers = state.users.filter((user) => user.active)
return (userId) => activeUsers.find((user) => user.id === userId)
},
},
})
import { useOtherStore } from './other-store'
export const useStore = defineStore('main', {
state: () => ({
// ...
}),
getters: {
otherGetter(state) {
const otherStore = useOtherStore()
return state.localData + otherStore.data
},
},
})
export default {
setup() {
const store = useStore()
store.counter = 3
store.doubleCount // 6
},
}
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
actions: {
increment() {
this.counter++
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random())
},
},
})
await
사용 가능import { mande } from 'mande' // fetch를 쉽게
const api = mande('/api/users')
export const useUsers = defineStore('users', {
state: () => ({
userData: null,
// ...
}),
actions: {
async registerUser(login, password) {
try {
this.userData = await api.post({ login, password })
showTooltip(`Welcome back ${this.userData.name}!`)
} catch (error) {
showTooltip(error)
// let the form component display the error
return error
}
},
},
})
export default defineComponent({
setup() {
const main = useMainStore()
// call the action as a method of the store
main.randomizeCounter()
return {}
},
})
import { useAuthStore } from './auth-store'
export const useSettingsStore = defineStore('settings', {
state: () => ({
// ...
}),
actions: {
async fetchUserPreferences(preferences) {
const auth = useAuthStore()
if (auth.isAuthenticated) {
this.preferences = await fetchPreferences()
} else {
throw new Error('User must be authenticated')
}
},
},
})
export default {
setup() {
const store = useStore()
store.randomizeCounter()
},
}
Here is an example that logs before running actions and after they resolve/reject.
다음은 작업을 실행하기 전과 해결/거부한 후 기록하는 예입니다.
const unsubscribe = someStore.$onAction(
({
name, // name of the action
store, // store instance, same as `someStore`
args, // array of parameters passed to the action
after, // hook after the action returns or resolves
onError, // hook if the action throws or rejects
}) => {
// a shared variable for this specific action call
const startTime = Date.now()
// this will trigger before an action on `store` is executed
console.log(`Start "${name}" with params [${args.join(', ')}].`)
// this will trigger if the action succeeds and after it has fully run.
// it waits for any returned promised
after((result) => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
)
})
// this will trigger if the action throws or returns a promise that rejects
onError((error) => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
)
})
}
)
// manually remove the listener
unsubscribe()
https://pinia.vuejs.org/getting-started.html