mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
Update docs
This commit is contained in:
parent
97096f8aff
commit
85b1127551
15 changed files with 200 additions and 298 deletions
0
docs/tut/control-flow/1-intro.md
Normal file
0
docs/tut/control-flow/1-intro.md
Normal file
1
docs/tut/control-flow/2-show.md
Normal file
1
docs/tut/control-flow/2-show.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# show()
|
||||
1
docs/tut/control-flow/3-switch.md
Normal file
1
docs/tut/control-flow/3-switch.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# switch()
|
||||
1
docs/tut/control-flow/4-indexes.md
Normal file
1
docs/tut/control-flow/4-indexes.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# indexes()
|
||||
1
docs/tut/control-flow/5-values.md
Normal file
1
docs/tut/control-flow/5-values.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# values()
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
# Control Flow
|
||||
|
||||
Vide has specific functions for dealing with sources that store a table value.
|
||||
|
||||
Often, you will have a table of values that will be displayed in a similar
|
||||
manner. Rather than manually looping over each value to generate a corresponding
|
||||
UI element, Vide provides functions `indexes()` and `values()` to do this for
|
||||
you.
|
||||
|
||||
`indexes()` maps each *index* in a table to a UI element.
|
||||
|
||||
```lua
|
||||
local names = source { "a", "b", "c" }
|
||||
|
||||
local elements = indexes(names, function(name, i)
|
||||
return create "TextLabel" {
|
||||
Text = function()
|
||||
return "Name: " .. name()
|
||||
end,
|
||||
|
||||
LayoutOrder = i
|
||||
}
|
||||
end)
|
||||
```
|
||||
|
||||
What happens here is the given callback is only ever ran *once* for each index
|
||||
in the table. The callback receives two arguments, a *source* containing the
|
||||
index's value and then the index itself.
|
||||
|
||||
Anytime the value at a corresponding index changes, the source for that index
|
||||
value is updated, causing the UI element depending on it to update too.
|
||||
|
||||
`values()` behaves similarly, except it maps each *value* in a table to a UI
|
||||
element.
|
||||
|
||||
```lua
|
||||
type Item = {
|
||||
Name: string,
|
||||
Icon: number
|
||||
}
|
||||
|
||||
local items = source({} :: Array<Item>)
|
||||
|
||||
local elements = values(items, function(item, i)
|
||||
return create "ImageLabel" {
|
||||
Image = "rbxassetid://" .. item.Icon,
|
||||
LayoutOrder = i
|
||||
}
|
||||
end)
|
||||
```
|
||||
|
||||
The callback is again only ever ran *once* for each value in the table. The
|
||||
callback receives two arguments, a value in the table and then a *source*
|
||||
containing the value's corresponding index.
|
||||
|
||||
Any time a value in a table changes index, the source for that value is updated,
|
||||
causing the UI element position to change.
|
||||
|
||||
In certain cases `values()` can cause less recalculation and rerenders than
|
||||
`indexes()` like when items are re-arranged and shifted within a table.
|
||||
|
||||
It is important that each value in a table is unique when using `values()`,
|
||||
and for this reason always using `indexes()` if a table contains primitive
|
||||
values.
|
||||
|
||||
Both `indexes()` and `values()` return an array of all mapped UI elements.
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
# Control Flow
|
||||
|
||||
Vide has specific functions for dealing with sources that store a table value.
|
||||
|
||||
Often, you will have a table of values that will be displayed in a similar
|
||||
manner. Rather than manually looping over each value to generate a corresponding
|
||||
UI element, Vide provides functions `indexes()` and `values()` to do this for
|
||||
you.
|
||||
|
||||
`indexes()` maps each *index* in a table to a UI element.
|
||||
|
||||
```lua
|
||||
local names = source { "a", "b", "c" }
|
||||
|
||||
local elements = indexes(names, function(name, i)
|
||||
return create "TextLabel" {
|
||||
Text = function()
|
||||
return "Name: " .. name()
|
||||
end,
|
||||
|
||||
LayoutOrder = i
|
||||
}
|
||||
end)
|
||||
```
|
||||
|
||||
What happens here is the given callback is only ever ran *once* for each index
|
||||
in the table. The callback receives two arguments, a *source* containing the
|
||||
index's value and then the index itself.
|
||||
|
||||
Anytime the value at a corresponding index changes, the source for that index
|
||||
value is updated, causing the UI element depending on it to update too.
|
||||
|
||||
`values()` behaves similarly, except it maps each *value* in a table to a UI
|
||||
element.
|
||||
|
||||
```lua
|
||||
type Item = {
|
||||
Name: string,
|
||||
Icon: number
|
||||
}
|
||||
|
||||
local items = source({} :: Array<Item>)
|
||||
|
||||
local elements = values(items, function(item, i)
|
||||
return create "ImageLabel" {
|
||||
Image = "rbxassetid://" .. item.Icon,
|
||||
LayoutOrder = i
|
||||
}
|
||||
end)
|
||||
```
|
||||
|
||||
The callback is again only ever ran *once* for each value in the table. The
|
||||
callback receives two arguments, a value in the table and then a *source*
|
||||
containing the value's corresponding index.
|
||||
|
||||
Any time a value in a table changes index, the source for that value is updated,
|
||||
causing the UI element position to change.
|
||||
|
||||
In certain cases `values()` can cause less recalculation and rerenders than
|
||||
`indexes()` like when items are re-arranged and shifted within a table.
|
||||
|
||||
It is important that each value in a table is unique when using `values()`,
|
||||
and for this reason always using `indexes()` if a table contains primitive
|
||||
values.
|
||||
|
||||
Both `indexes()` and `values()` return an array of all mapped UI elements.
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
# Control Flow
|
||||
|
||||
Vide has specific functions for dealing with sources that store a table value.
|
||||
|
||||
Often, you will have a table of values that will be displayed in a similar
|
||||
manner. Rather than manually looping over each value to generate a corresponding
|
||||
UI element, Vide provides functions `indexes()` and `values()` to do this for
|
||||
you.
|
||||
|
||||
`indexes()` maps each *index* in a table to a UI element.
|
||||
|
||||
```lua
|
||||
local names = source { "a", "b", "c" }
|
||||
|
||||
local elements = indexes(names, function(name, i)
|
||||
return create "TextLabel" {
|
||||
Text = function()
|
||||
return "Name: " .. name()
|
||||
end,
|
||||
|
||||
LayoutOrder = i
|
||||
}
|
||||
end)
|
||||
```
|
||||
|
||||
What happens here is the given callback is only ever ran *once* for each index
|
||||
in the table. The callback receives two arguments, a *source* containing the
|
||||
index's value and then the index itself.
|
||||
|
||||
Anytime the value at a corresponding index changes, the source for that index
|
||||
value is updated, causing the UI element depending on it to update too.
|
||||
|
||||
`values()` behaves similarly, except it maps each *value* in a table to a UI
|
||||
element.
|
||||
|
||||
```lua
|
||||
type Item = {
|
||||
Name: string,
|
||||
Icon: number
|
||||
}
|
||||
|
||||
local items = source({} :: Array<Item>)
|
||||
|
||||
local elements = values(items, function(item, i)
|
||||
return create "ImageLabel" {
|
||||
Image = "rbxassetid://" .. item.Icon,
|
||||
LayoutOrder = i
|
||||
}
|
||||
end)
|
||||
```
|
||||
|
||||
The callback is again only ever ran *once* for each value in the table. The
|
||||
callback receives two arguments, a value in the table and then a *source*
|
||||
containing the value's corresponding index.
|
||||
|
||||
Any time a value in a table changes index, the source for that value is updated,
|
||||
causing the UI element position to change.
|
||||
|
||||
In certain cases `values()` can cause less recalculation and rerenders than
|
||||
`indexes()` like when items are re-arranged and shifted within a table.
|
||||
|
||||
It is important that each value in a table is unique when using `values()`,
|
||||
and for this reason always using `indexes()` if a table contains primitive
|
||||
values.
|
||||
|
||||
Both `indexes()` and `values()` return an array of all mapped UI elements.
|
||||
|
|
@ -5,5 +5,27 @@ be set with `vide.strict = true` once when you first require Vide. Strict mode
|
|||
will add extra safety checks and emit better error traces, particularly when
|
||||
errors occur in property bindings.
|
||||
|
||||
Strict mode will run derived sources and effects twice each time they update.
|
||||
This is to help identify improper cleanup of side-effects and ensure that pure
|
||||
computations are actually pure.
|
||||
|
||||
```lua
|
||||
local source = vide.source
|
||||
local effect = vide.effect
|
||||
|
||||
vide.strict = true
|
||||
|
||||
local count = source(0)
|
||||
|
||||
local ran = 0
|
||||
effect(function()
|
||||
ran += 1
|
||||
end)
|
||||
|
||||
print(ran) -- 2
|
||||
count(1)
|
||||
print(ran) -- 4
|
||||
```
|
||||
|
||||
A full list of what strict mode will do can be found
|
||||
[here](../../api/strict-mode).
|
||||
|
|
|
|||
|
|
@ -1,56 +1,105 @@
|
|||
# Control Flow
|
||||
|
||||
Eventually you will need a way to dynamically create and destroy UI elements
|
||||
resulting from state changes. Vide provides functions to help you do this,
|
||||
resulting from source updates. Vide provides functions to help you do this,
|
||||
known as *control flow* functions.
|
||||
|
||||
These functions return a new source, which holds the instances to be displayed.
|
||||
These functions return new sources, which hold the instances to be displayed.
|
||||
These sources can be assigned as children, meaning the displayed children
|
||||
will update when the input source updates.
|
||||
|
||||
One of these functions is `switch()`, used to conditionally show one of a set of
|
||||
components.
|
||||
Control flow functions are special, because they run their components in a new
|
||||
reactive scope, which can be destroyed independently of the reactive scope that
|
||||
called the control flow function itself. This means that parts of your app can
|
||||
be independently created then destroyed and cleaned.
|
||||
|
||||
## show()
|
||||
|
||||
The most basic control flow function is `show()`, which is used to conditionally
|
||||
show a component.
|
||||
|
||||
```lua
|
||||
local source = vide.source
|
||||
local show = vide.show
|
||||
|
||||
local function JoinMenu()
|
||||
local joined = source(false)
|
||||
|
||||
local function JoinButton()
|
||||
return Button {
|
||||
Activated = function() joined(true) end
|
||||
}
|
||||
end
|
||||
|
||||
return create "Frame" {
|
||||
show(function() return not joined() end, JoinButton)
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
This will make a button to join if you have not joined already.
|
||||
|
||||
You can also pass a third argument, a fallback to show if the condition is falsey.
|
||||
|
||||
```lua
|
||||
local function JoinMenu()
|
||||
local joined = source(false)
|
||||
|
||||
local function JoinButton()
|
||||
return Button {
|
||||
Activated = function() joined(true) end
|
||||
}
|
||||
end
|
||||
|
||||
local function LeaveButton()
|
||||
return Button {
|
||||
Activated = function() joined(false) end
|
||||
}
|
||||
end
|
||||
|
||||
return create "Frame" {
|
||||
show(joined, LeaveButton, JoinButton)
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
## switch()
|
||||
|
||||
Similar to `show()`, `switch()`, also condtionally displays one instance at a
|
||||
time. It is more flexible since it can show one of many components, based on a
|
||||
table used to map a source value to a component.
|
||||
|
||||
```lua
|
||||
local vide = require(vide)
|
||||
local source = vide.source
|
||||
local switch = vide.switch
|
||||
|
||||
local function ToggleButton(p: {
|
||||
Text: string,
|
||||
Toggle: (boolean) -> boolean
|
||||
})
|
||||
return create "TextButton" {
|
||||
Size = UDim2.fromOffset(300, 300),
|
||||
Text = p.Text,
|
||||
Activated = function()
|
||||
p.Toggle(not p.Toggle())
|
||||
end
|
||||
}
|
||||
end
|
||||
local function JoinMenu()
|
||||
local joined = source(false)
|
||||
|
||||
local loggedIn = source(false)
|
||||
local function JoinButton()
|
||||
return Button {
|
||||
Activated = function() joined(true) end
|
||||
}
|
||||
end
|
||||
|
||||
local function LoginMenu()
|
||||
return Frame {
|
||||
switch(loggedIn) {
|
||||
[true] = function()
|
||||
return ToggleButton { Text = "Log out", Toggle = loggedIn }
|
||||
end,
|
||||
local function LeaveButton()
|
||||
return Button {
|
||||
Activated = function() joined(false) end
|
||||
}
|
||||
end
|
||||
|
||||
[false] = function()
|
||||
return ToggleButton { Text = "Log in", Toggle = loggedIn }
|
||||
end
|
||||
return create "Frame" {
|
||||
switch(joined) {
|
||||
[true] = LeaveButton,
|
||||
[false] = JoinButton
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
mount(function() return create "ScreenGui" { LoginMenu {} } end, game.StarterGui)
|
||||
```
|
||||
|
||||
Above is an example of using a switch to create a login menu. Each time
|
||||
`loggedIn` toggles, the current button will be destroyed, and a new button
|
||||
created, which the text to represent the current action, to log in or log out.
|
||||
Above is an example of using a switch to create a join menu. Each time
|
||||
`joined` toggles, the current button will be destroyed, and a new button
|
||||
created, which the text to represent the current action, to join or leave.
|
||||
|
||||
The callbacks given to control flow functions are ran in a new reactive-scope,
|
||||
so any cleanups registered will be ran when the input is changed and a new
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue