Skip to content

Commit

Permalink
Merge pull request #25 from skirtles-code/more-stubs
Browse files Browse the repository at this point in the history
Add some more questions and stub answers
  • Loading branch information
skirtles-code authored Nov 8, 2023
2 parents cf83f78 + e1f3def commit ab48b2c
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 6 deletions.
24 changes: 20 additions & 4 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ export default defineConfig({
// text: 'How should my components communicate?',
// link: '/faq/component-communication'
// },
// {
// text: 'How do I call a method in a child component?',
// link: '/faq/invoking-child-methods'
// },
// {
// text: 'Why are my template refs not working?',
// link: '/faq/template-refs'
// },
// {
// text: 'How can I share state with a composable?',
// link: '/faq/sharing-state'
// },
{
text: 'How can I pass slots through to a child component?',
link: '/faq/forwarding-slots'
Expand All @@ -99,18 +111,22 @@ export default defineConfig({
link: '/faq/template-local-variables'
},
// {
// text: 'Why does selecting one item select them all?',
// link: '/faq/independent-selections'
// text: 'Can I use JavaScript classes for my reactive data?',
// link: '/faq/reactivity-and-classes'
// },
// {
// text: 'Why are my template refs not working?',
// link: '/faq/template-refs'
// text: 'Why does selecting one item select them all?',
// link: '/faq/independent-selections'
// },
{
text: 'How do I create unique element ids with Vue?',
link: '/faq/unique-element-ids'
},
// {
// text: `Why can't I use the current route inside <code>App.vue</code>?`,
// link: '/faq/accessing-the-route'
// },
// {
// text: `Why does my logging show an empty/missing value after I've loaded the data?`,
// link: '/faq/logging-after-loading'
// },
Expand Down
7 changes: 7 additions & 0 deletions docs/faq/accessing-the-route.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Why can't I use the current route inside `App.vue`?

::: warning This answer is a stub.
We are still working on writing the answers to the FAQ questions. The answer below is incomplete, but you may still find it useful.
:::

The short answer is *timing*. You can use the current route inside `App.vue`, but it won't be available in time for the initial render.
8 changes: 6 additions & 2 deletions docs/faq/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This FAQ aims to answer some of the most common programming questions that we ge
It is not a substitute for the official Vue documentation, available at <https://vuejs.org/>. Those docs include an FAQ for Vue itself at <https://vuejs.org/about/faq.html>.

::: warning Work in progress
We've only just started work on this FAQ and most of the answers will be incomplete. Some questions don't really have an answer yet, they're just placeholders.
Only about half the questions have complete answers. Those questions are listed in the sidebar on the left. The other questions are just stubs.
:::

---
Expand Down Expand Up @@ -46,13 +46,17 @@ We've only just started work on this FAQ and most of the answers will be incompl
<!-- Vue code patterns -->

- [How should my components communicate?](component-communication)
- [How do I call a method in a child component?](invoking-child-methods)
- [Why are my template refs not working?](template-refs)
- [How can I share state with a composable?](sharing-state)
- [How can I pass all slots through to a child component?](forwarding-slots)
- [How can I make Vue 'wait' for the data before rendering?](delaying-rendering)
- [Why isn't `v-html` rendering my components?](components-in-v-html)
- [Can I create a local variable in my template?](template-local-variables)
- [Can I use JavaScript classes for my reactive data?](reactivity-and-classes)
- [Why does selecting one item select them all?](independent-selections)
- [Why are my template refs not working?](template-refs)
- [How do I create unique element ids with Vue?](unique-element-ids)
- [Why can't I use the current route inside `App.vue`?](accessing-the-route)

---

Expand Down
13 changes: 13 additions & 0 deletions docs/faq/invoking-child-methods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# How do I call a method in a child component?

::: warning This answer is a stub.
We are still working on writing the answers to the FAQ questions. The answer below is incomplete, but you may still find it useful.
:::

You can invoke methods on child components using template refs. See <https://vuejs.org/guide/essentials/template-refs.html>.

If the child component is using `<script setup>`, it'll need to expose any methods explicitly, using [`defineExpose()`](https://vuejs.org/api/sfc-script-setup.html#defineexpose).

See also [Why are my template refs not working?](template-refs).

However, template refs are a feature you should rarely need. Usually there's a better way, but it depends on the specifics of what exactly you're trying to do. It's common for newcomers to Vue to overuse template refs, often because they're trying to use patterns they've used in other types of programming. The premise of the question, that the parent needs to call a method on the child, is precisely the line of reasoning that leads to template refs being misused. There's usually a better alternative to implement the underlying requirements.
16 changes: 16 additions & 0 deletions docs/faq/reactivity-and-classes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Can I use JavaScript classes for my reactive data?

::: warning This answer is a stub.
We are still working on writing the answers to the FAQ questions. The answer below is incomplete, but you may still find it useful.
:::

You should avoid using JavaScript classes for reactive data.

Built-in classes such as `Array`, `Set` and `Map` will work fine, but Vue has specific code to handle those classes. It won't know how to handle classes that you've written yourself.

It is possible to use JS classes, but they have to be written carefully to avoid breaking reactivity.

There are two common reasons for using classes:

1. You're used to working with classes in other frameworks or languages. In that case, you should probably just not use them with Vue.
2. They're coming from a third-party library. In this scenario, you may want to keep the class non-reactive and instead create a separate object that exposes a reactive copy of the data. The original class will likely provide some mechanism, e.g. callbacks or events, that you can use to keep the objects in sync.
37 changes: 37 additions & 0 deletions docs/faq/sharing-state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# How can I share state with a composable?

::: warning This answer is a stub.
We are still working on writing the answers to the FAQ questions. The answer below is incomplete, but you may still find it useful.
:::

Composables are JavaScript functions. Vue doesn't have any specific support for composables, it's just a name given to a common usage pattern. Normal JavaScript rules still apply.

So if a ref is created inside the composable, you'll get a new ref each time the composable is called:

```js
export function useSidebar() {
const isOpen = ref(false)

return { isOpen }
}
```

Every component that calls `useSidebar()` will get a different ref, so this composable can't be used to shared state.

If we move the creation of the ref outside the function, it'll be shared instead:

```js
const isOpen = ref(false)

export function useSidebar() {
return { isOpen }
}
```

Now, every call to `useSidebar()` will return the same `ref`, allowing that state to be shared.

In the example above, where we're just returning a ref, it probably isn't necessary to use a composable at all. We could just share the ref directly:

```js
export const isOpen = ref(false)
```

0 comments on commit ab48b2c

Please sign in to comment.