Skip to content

Commit d1f606b

Browse files
committed
Update some references to Vuex
1 parent 48f3a4d commit d1f606b

File tree

2 files changed

+23
-20
lines changed

2 files changed

+23
-20
lines changed

docs/patterns/computed-v-model.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import ProxyExample from './computed-v-model/proxy-example.vue'
33
</script>
44
# Computed with v-model
55

6-
The principle of one-way data flow, with 'props down, events up', is just an extension of the idea that data should only be modified by its owner. This same idea can be extended to other scenarios, such as using Vuex, where the store is considered the owner of the data and so it should only be mutated by the store.
6+
The principle of one-way data flow, with 'props down, events up', is just an extension of the idea that data should only be modified by its owner. This same idea can be extended to other scenarios, such as using Pinia, where the store is considered the owner of the data and so it should only be mutated by the store.
77

8-
This causes problems when working with `v-model`, which attempts to modify the value directly. We can work around that using a `computed` value with a `get` and `set`.
8+
This causes problems when working with `v-model`, which attempts to modify the value directly. One way we can address this is by using `computed()` with `get` and `set`.
99

1010
There are more complete examples for [Checkbox](../components/checkbox.html) and [Radio](../components/radio.html) components, but to reduce it down to the essentials with an `<input>`:
1111

@@ -26,26 +26,28 @@ const inputValue = computed({
2626
})
2727
```
2828

29-
So for Vuex we might do something like this:
29+
So for a prop passed down from the parent component we might do something like this:
3030

3131
```js
3232
const inputValue = computed({
33-
get: () => store.state.value,
34-
set: newValue => store.commit('updateValue', newValue)
33+
get: () => props.title,
34+
set: newValue => emit('update:title', newValue)
3535
})
3636
```
3737

38-
A similar idea is common when working with data passed down from a parent component:
38+
Using an event with a name of the form `update:propName` allows it to be used with `v-model` on the parent. The default prop name for this would be `modelValue`. As such, the technique described here is the standard way to 'pass on' a `v-model` from a component's parent to one of its children.
39+
40+
A similar approach would work for updating data via a Pinia action:
3941

4042
```js
43+
const store = useMyStore()
44+
4145
const inputValue = computed({
42-
get: () => props.value,
43-
set: newValue => emit('update:value', newValue)
46+
get: () => store.title,
47+
set: newValue => store.updateTitle(newValue)
4448
})
4549
```
4650

47-
Using an event with a name of the form `update:propName` allows it to be used with `v-model` on the parent. The default prop name for this would be `modelValue`. As such, the technique described here is the standard way to 'pass on' a `v-model` from a component's parent to one of its children.
48-
4951
## Libraries
5052

5153
This pattern is so common that it can be found in composable libraries:
@@ -88,7 +90,7 @@ Putting that all together gives:
8890
<proxy-example />
8991
</live-example>
9092

91-
While it might look a bit fiddly if you aren't used to working with a `Proxy`, most of this code is very reusable and can be hidden away behind a utility function. We could create a similar utility function for performing the same bit of trickery with an object coming from a Vuex store.
93+
While it might look a bit fiddly if you aren't used to working with a `Proxy`, most of this code is very reusable and can be hidden away behind a utility function. We could create a similar utility function for performing the same bit of trickery with an object coming from a store.
9294

9395
The approach does violate another best practice. The usual recommendation is to avoid mutating the properties of an object returned from a `computed`, as they're considered transient. However, we're breaking that rule knowingly here as mutating those properties is the whole point of the approach.
9496

docs/patterns/global-properties.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ app.config.globalProperties.$http = axios.create({ /* ... */ })
2424

2525
This allows us to use `this.$http`, just like in Vue 2.
2626

27-
You'll find this approach used in some official Vue libraries. For example, Vuex exposes `$store` and Vue Router exposes `$router` and `$route`. The mapping helpers provided by Vuex, e.g. `mapState`, all rely on using `this.$store` to access the correct store. These helpers wouldn't be possible using most of the other techniques described on this page.
27+
You'll find this approach used in some official Vue libraries. For example, Vue Router exposes `$router` and `$route`. The mapping helpers provided by Vuex, e.g. `mapState`, all rely on using `this.$store` to access the correct store. These helpers wouldn't be possible using most of the other techniques described on this page.
2828

2929
However, the use of `globalProperties` in those official libraries shouldn't be seen as an endorsement to use them everywhere. Those libraries have some specific requirements that typically don't apply to application code.
3030

@@ -70,7 +70,7 @@ But the lack of availability in `setup` is a major problem, so let's consider so
7070

7171
## Application-level `provide` / `inject`
7272

73-
The standard solution for use with the Composition API is to use `provide` on the application and `inject` in `setup`. The latter will usually be wrapped in a dedicated helper function. We see this approach with Vuex and Vue Router, which have functions such as `useStore` and `useRouter` implemented this way.
73+
The standard solution for use with the Composition API is to use `provide` on the application and `inject` in `setup`. The latter will usually be wrapped in a dedicated helper function. We see this approach with Vue Router, which has functions such as `useRouter` and `useRoute` implemented this way.
7474

7575
Returning to the earlier example for `axios`:
7676

@@ -148,9 +148,9 @@ import http from './http.js'
148148

149149
This flips the dependency. Rather than having a value injected from outside, the dependency is an explicit import from a specific location. The gain in explicitness comes with a small loss in the reusability of the component.
150150

151-
ES modules also work well outside of Vue components. For the `axios` example, it's common to need the same `axios` instance in Vuex actions. While there are other ways that can be achieved, using an ES module is the most widely used in real applications.
151+
ES modules also work well outside of Vue components. For the `axios` example, it's common to need the same `axios` instance in Pinia actions. While there are other ways that can be achieved, using an ES module is the most widely used in real applications.
152152

153-
## Sharing state using Pinia or Vuex
153+
## Sharing state using Pinia
154154

155155
It can also be useful to share state globally. We could just use ES modules and Vue's Reactivity APIs to implement shared state ourselves:
156156

@@ -160,15 +160,16 @@ export default reactive({})
160160

161161
Then anything that needs this state object can use `import` to pull it in.
162162

163-
However, this roll-your-own approach tends to lead to problems. Standard solutions, such as [Pinia](https://pinia.vuejs.org/) or [Vuex](https://vuex.vuejs.org/), provide several benefits:
163+
However, using [Pinia](https://pinia.vuejs.org/), the official Vue state management library, provides several benefits:
164164

165165
- Documented APIs.
166166
- Familiarity among developers.
167167
- Standard usage patterns that, by design, avoid common problems.
168168
- Integration with Vue Devtools.
169+
- Third-party plugins.
169170
- You don't have to maintain the code yourself.
170171

171-
So if you need a reactive, central store for your state, you should probably be using either Pinia or Vuex.
172+
So if you need a reactive, central store for your state, you should probably be using Pinia.
172173

173174
## Global mixins
174175

@@ -216,15 +217,15 @@ If you want the equivalent of `v-if`/`v-else` you can use two slots:
216217

217218
The `permission-check` component would still need some way of accessing the 'global' data, and for that it would use one of the other techniques described on this page. The key thing about this approach is that only this one component would need to worry about how the global data is passed around, everything else would just use the component. If you need to refactor how the data is passed around it will only impact this one component.
218219

219-
To give a concrete example of how `permission-check` might be implemented in conjunction with Vuex:
220+
To give a concrete example of how `permission-check` might be implemented in conjunction with Pinia:
220221

221222
```js
222-
import { useStore } from 'vuex'
223+
import { useAuthStore } from '@/store/auth.js'
223224

224225
// Using a functional component, so this is effectively just a render function.
225226
// It doesn't render any VNodes of its own, just those created by its slots.
226227
const PermissionCheck = ({ name }, { slots }) => {
227-
const hasPermission = useStore().state.permissions[name]
228+
const hasPermission = useAuthStore().permissions[name]
228229

229230
if (hasPermission) {
230231
return slots.allowed?.() || slots.default?.()

0 commit comments

Comments
 (0)