-
-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: add shared state documentation #699
base: main
Are you sure you want to change the base?
Changes from 2 commits
80b87cb
d3bf9a8
c94d02e
c9623ce
64f228c
05602e6
797fae2
fdd7099
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
--- | ||
title: Shared State | ||
description: How to use a reactive composable to share your objects across component files. | ||
author: / | ||
thumbnail: /recipes/animations.png | ||
difficulty: 0 | ||
--- | ||
|
||
# Shared State in TresJS | ||
|
||
This guide will help you get started with shared state in TresJS by building a simple scene with a cube that can be shared across component files. | ||
|
||
<StackBlitzEmbed project-id="tresjs-minimal-reproduction-rycc4j" /> | ||
|
||
## Creating a State Composable | ||
|
||
First, we'll create a composable to store the objects. | ||
|
||
```ts | ||
//composables/state.ts | ||
import { reactive, toRefs } from "vue"; | ||
|
||
const state = reactive({ | ||
mesh: null, | ||
//you can add more objects here | ||
}) | ||
|
||
export function useState() { | ||
return { | ||
...toRefs(state) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should slim down the reactivity here. Feel free to point out if I'm misunderstanding, but I believe It's fine if users want to use Maybe one or both of:
@alvarosabu Thoughts here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's correct, better to use shallowRefs or shallowReactive. I wonder if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In the Vue docs, the type indicates that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @andretchen0 |
||
} | ||
} | ||
``` | ||
|
||
## Setting the object to the state | ||
|
||
Next, we'll assign an object to the state and include it in a subcomponent where we can access and use it. | ||
|
||
```vue | ||
//Parent component | ||
whitespacecode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<script setup lang="ts"> | ||
import { BoxGeometry, Mesh, MeshNormalMaterial } from 'three'; | ||
|
||
import SubComponent from './SubComponent.vue'; | ||
import { useState } from '../composables/state'; | ||
|
||
const { mesh } = useState(); | ||
|
||
//assinging the object to the state | ||
mesh.value = new Mesh(new BoxGeometry(), new MeshNormalMaterial()); | ||
</script> | ||
|
||
<template> | ||
<TresPerspectiveCamera /> | ||
|
||
<SubComponent /> | ||
</template> | ||
``` | ||
|
||
## Using the object in other components | ||
|
||
With the mesh assigned to the reactive state, it's available throughout your project. | ||
|
||
```vue | ||
//Subcomponent.vue | ||
<script setup lang="ts"> | ||
import { useState } from '../composables/state'; | ||
const { mesh, ground } = useState(); | ||
|
||
console.log('ground:', ground); | ||
</script> | ||
|
||
<template> | ||
<primitive v-if="mesh" :object="mesh" /> | ||
</template> | ||
``` | ||
|
||
## Using TresMesh components | ||
|
||
You can also add TresMesh components to the reactive state. Here, we'll use a reference and assign it to the state when mounted. | ||
|
||
```vue | ||
//Parent component | ||
whitespacecode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<script setup lang="ts"> | ||
import { BoxGeometry, Mesh, MeshNormalMaterial } from 'three'; | ||
|
||
import SubComponent from './SubComponent.vue'; | ||
import { useState } from '../composables/state'; | ||
|
||
const { mesh } = useState(); | ||
|
||
//reference the object | ||
const exampleRef = ref(null); | ||
|
||
//assinging the object to the state when mounted | ||
onMounted(() => { | ||
mesh.value = exampleRef.value; | ||
}); | ||
</script> | ||
|
||
<template> | ||
<TresPerspectiveCamera /> | ||
|
||
<TresMesh ref="exampleRef" :position="[0, 0, 0]" cast-shadow> | ||
<TresBoxGeometry :args="[1.5, 1.5, 1.5]" /> | ||
<TresMeshToonMaterial color="#4F4F4F" /> | ||
</TresMesh> | ||
|
||
<SubComponent /> | ||
</template> | ||
``` | ||
|
||
With these steps, you can easily manage and share objects across different components in your Vue 3 project using a reactive composable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @whitespacecode since the example doesn't rely on third party libs, can we replace this with a Tresjs repl playground https://play.tresjs.org/ ?
You can find an example on how here
tres/docs/cookbook/lights-shadows.md
Line 14 in 8d53bba
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @alvarosabu
I tried with the playground and i'm getting this error:
'get' on proxy: property 'modelViewMatrix' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '#<cr>' but got '#<cr>')
I tried a few things but i'm keep getting errors on the playground.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using play.tresjs