Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Svelteとは?~React、Vueとの違いから学ぶ~
Search
M-Taguchi
May 27, 2022
830
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Svelteとは?~React、Vueとの違いから学ぶ~
Svelte勉強会資料
M-Taguchi
May 27, 2022
Featured
See All Featured
The Invisible Side of Design
smashingmag
301
52k
New Earth Scene 8
popppiees
4
2.6k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
690
Accessibility Awareness
sabderemane
1
210
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.2k
Writing Fast Ruby
sferik
630
63k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
520
Scaling GitHub
holman
464
140k
The browser strikes back
jonoalderson
0
1.7k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
500
sira's awesome portfolio website redesign presentation
elsirapls
0
410
Transcript
©2022 RAKUS Co., Ltd. Svelteとは? ~React、Vueとの違いから学ぶ~ UI開発課 田口 真輝
目次 • Svelteとは? • React、Vueとの実装比較 • 実際に記述した感想 • まとめ 2
Svelteとは? 3
Svelteとは? 下記のような特徴を持つWebフレームワーク • コードの記述量が少ない • 仮想DOMを使わない • Reactiveに書ける • バンドルサイズが小さい
4
Svelteとは?~仮想DOMを使わない~ 従来のDOM構築…ページ変更→DOM全体を再描画 仮想DOMとは… 1. インメモリ内で仮想のDOMを構築し、 2. DOMの操作が行われたらまず仮想DOM内で変更箇所を 検知し、(差分検出) 3. 変更箇所のみを再描画する
→余分なレンダリングが抑えられる 5
Svelteとは?~仮想DOMを使わない~ <body> <div> <div> <div> <div> <div> <p>foo</p> <p>bar</p> 変更したい→仮想DOMはここだけ変更
6
Svelteとは?~仮想DOMを使わない~ 仮想DOM有能! なのに… 何故Svelteは使わないの??? 7
Svelteとは?~仮想DOMを使わない~ 問題点 1. 差分検出のコスト 2. props受け渡しによる余分な再描画問題 親から子に渡しているprops内の状態に変化があると、 子コンポーネントで再描画が発生してしまう 8
Svelteとは?~仮想DOMを使わない~ 解決策 • コンパイル時に、変更がありそうな箇所のDOMを書き換える JSファイルを生成 →「Svelteはコンパイラ」 9
Svelteとは?~Reactiveに書ける~ let count = 0; $: doubled = count *
2; data: { count: 0 }, computed: { doubled: function() { return this.count * 2; } } Svelte Vue 10 countが変化するとdoubledも即変化する
Svelteとは?~バンドルサイズが小さい~ 11
Svelteとは?~バンドルサイズが小さい~ 12
React、Vueとの比較 13
React、Vueとの比較 下記の観点で比較(Svelte、Vueは3系) • Hello World! • スタイリング • Container、Presentationコンポーネント分割 •
API処理 • 状態管理 14
React、Vueとの比較~Hello World~ 15
Svelte、Reactの比較~Hello World~ 1. <script> 2. const hello = "Hello World!";
3. </script> 4. 5. <main> 6. <h1>{hello}</h1> 7. </main> 8. 9. <style></style> 1. import './App.css'; 2. 3. function App() { 4. const hello = "Hello World!" 5. return ( 6. <h1>{hello}</h1> 7. ); 8. } 9. 10. export default App; App.svelte App.js 16 JSX形式 SFC形式
Svelte、Vueの比較~Hello World~ 1. <script> 2. const hello = "Hello World!";
3. </script> 4. 5. <main> 6. <h1>{hello}</h1> 7. </main> 8. 9. <style></style> 1. <template> 2. <h1>{{ hello }}</h1> 3. </template> 4. 5. <script> 6. export default { 7. name: "App", 8. setup() { 9. return { 10. hello: "Hello World!", 11. }; 12. }, 13. }; 14. </script> 15. 16. <style></style> App.svelte App.vue 17 SFC形式 SFC形式
React、Vueとの比較~スタイリング~ 18
Svelte、Reactの比較~スタイリング~ 1. <script> 2. let count = 0; 3. const
countUp = () => count++; 4. const countDown = () => count--; 5. </script> 6. 7. <main> 8. <button on:click={countDown}>-</button> 9. <span class="{count < 0 && "minus"}">{count}</span> 10. <button on:click={countUp}>+</button> 11. </main> 12. 13. <style> 14. span.minus { 15. color: red; 16. } 17. </style> 1. import './App.css'; 2. import { useState } from 'react'; 3. 4. function App() { 5. const [count, setCount] = useState(0); 6. const countUp = () => setCount(count + 1); 7. const countDown = () => setCount(count - 1); 8. 9. const minus = { 10. color: count < 0 && "red", 11. } 12. 13. return ( 14. <> 15. <button onClick={countDown}>-</button> 16. <span style={minus}>{count}</span> 17. <button onClick={countUp}>+</button> 18. </> 19. ); 20. } 21. 22. export default App; App.svelte App.js 19 css-modules的書き方 css-modules的書き方
Svelte、Vueの比較~スタイリング~ 1. <script> 2. let count = 0; 3. const
countUp = () => count++; 4. const countDown = () => count--; 5. </script> 6. 7. <main> 8. <button on:click={countDown}>-</button> 9. <span class="{count < 0 && "minus"}">{count}</span> 10. <button on:click={countUp}>+</button> 11. </main> 12. 13. <style> 14. span.minus { 15. color: red; 16. } 17. </style> 1. <template> 2. <div> 3. <button @click="countDown ">-</button> 4. <span :class="{ minus: count < 0 }">{{ count }}</span> 5. <button @click="countUp">+</button> 6. </div> 7. </template> 8. 9. <script> 10. import { ref } from "vue"; 11. export default { 12. name: "App", 13. setup() { 14. const count = ref(0); 15. return { 16. count, 17. countDown : () => count.value--, 18. countUp: () => count.value++, 19. }; 20. }, 21. }; 22. </script> 23. 24. <style> 25. span.minus { 26. color: red; 27. } 28. </style> App.svelte App.vue 20 css-modules的書き方
React、Vueとの比較~コンポーネント分割~ 21
Svelte、Reactの比較~コンポーネント分割~ 1. <script> 2. import TodoContainer from "./TodoContainer.svelte"; 3. </script>
4. 5. <main> 6. <TodoContainer /> 7. </main> 1. import './App.css'; 2. import TodoContainer from './TodoContainer'; 3. 4. function App() { 5. 6. return ( 7. <> 8. <TodoContainer /> 9. </> 10. ); 11. } 12. 13. export default App; App.svelte App.js Todo TodoContainer Todo TodoContainer 22 script省略
1. <script> 2. import Todo from "./Todo.svelte" 3. 4. let
todoList = []; 5. let value = ""; 6. 7. const addTodo = () => { 8. todoList = [...todoList, value]; 9. value = ""; 10. } 11. 12. const deleteTodo = (index) => { 13. todoList.splice(index, 1); 14. todoList = todoList 15. } 16. </script> 17. 18. <div> 19. <Todo {todoList} {addTodo} {deleteTodo} bind:value /> 20. </div> 1. import { useState } from 'react'; 2. import Todo from './Todo'; 3. 4. function TodoContainer () { 5. const [todoList, setTodoList] = useState([]); 6. const [val, setVal] = useState(""); 7. 8. const addTodo = () => { 9. setTodoList([...todoList, val]); 10. setVal(""); 11. } 12. 13. const deleteTodo = (index) => { 14. const newTodoList = [...todoList]; 15. newTodoList.splice(index, 1); 16. setTodoList(newTodoList) 17. } 18. 19. return ( 20. <> 21. <Todo val={val} setVal={setVal} todoList={todoList} addTodo={addTodo} deleteTodo={deleteTodo}/> 22. </> 23. ); 24. } 25. 26. export default TodoContainer ; App.js Todo TodoContainer App.svelte Todo TodoContainer 23 Svelte、Reactの比較~コンポーネント分割~ 再生成 再生成
1. <script> 2. export let todoList; 3. export let value;
4. export let addTodo; 5. export let deleteTodo; 6. </script> 7. 8. <div> 9. <div> 10. <input bind:value> 11. <button on:click={addTodo}>追加</button> 12. </div> 13. <div> 14. {#each todoList as todo, i} 15. <div>{todo}<button on:click={deleteTodo(i)}>×</button></div> 16. {/each} 17. </div> 18. </div> 1. function Todo({val, setVal, todoList, addTodo, deleteTodo }) { 2. return ( 3. <> 4. <div> 5. <input type="text" value={val} onChange={(e) => setVal(e.target.value)}/> 6. <button onClick={() => addTodo()}>追加 </button> 7. </div> 8. <div> 9. {todoList.map((todo, i) => ( 10. <div key={i}>{todo}<button onClick={() => deleteTodo (i)}>×</button></div> 11. )) } 12. </div> 13. </> 14. ); 15. } 16. 17. export default Todo; App.js Todo TodoContainer App.svelte Todo TodoContainer 24 Svelte、Reactの比較~コンポーネント分割~
Svelte、Vueの比較~コンポーネント分割~ 1. <script> 2. import TodoContainer from "./TodoContainer.svelte"; 3. </script>
4. 5. <main> 6. <TodoContainer /> 7. </main> 1. <template> 2. <TodoContainer /> 3. </template> 4. 5. <script> 6. import TodoContainer from "./components/TodoContainer.vue" ; 7. export default { 8. name: "App", 9. components: { 10. TodoContainer , 11. }, 12. }; 13. </script> App.vue Todo TodoContainer App.svelte Todo TodoContainer 25
Svelte、Vueの比較~コンポーネント分割~ 1. <script> 2. import Todo from "./Todo.svelte" 3. 4.
let todoList = []; 5. let value = ""; 6. 7. const addTodo = () => { 8. todoList = [...todoList, value]; 9. value = ""; 10. } 11. 12. const deleteTodo = (index) => { 13. todoList.splice(index, 1); 14. todoList = todoList 15. } 16. </script> 17. 18. <div> 19. <Todo {todoList} {addTodo} {deleteTodo} bind:value /> 20. </div> 1. <template> 2. <Todo 3. v-model:val="val" 4. :todoList="todoList" 5. :addTodo="addTodo" 6. :deleteTodo="deleteTodo" 7. /> 8. </template> 9. 10. <script> 11. import Todo from "./Todo.vue"; 12. import { ref } from "vue"; 13. export default { 14. name: "TodoContainer", 15. components: { 16. Todo, 17. }, 18. setup() { 19. const todoList = ref([]); 20. const val = ref(""); 21. 22. const addTodo = () => { 23. todoList.value.push(val.value); 24. val.value = ""; 25. }; 26. const deleteTodo = (index) => { 27. todoList.value.splice(index, 1); 28. }; 29. return { 30. todoList, 31. val, 32. addTodo, 33. deleteTodo, 34. }; 35. }, 36. }; 37. </script> App.vue Todo TodoContainer App.svelte Todo TodoContainer 26 破壊的代入で更新
Svelte、Vueの比較~コンポーネント分割~ 1. <script> 2. export let todoList; 3. export let
value; 4. export let addTodo; 5. export let deleteTodo; 6. </script> 7. 8. <div> 9. <div> 10. <input bind:value> 11. <button on:click={addTodo}>追加</button> 12. </div> 13. <div> 14. {#each todoList as todo, i} 15. <div>{todo}<button on:click={deleteTodo(i)}>×</button></div> 16. {/each} 17. </div> 18. </div> 1. <template> 2. <div> 3. <div> 4. <input :value="val" @input="$emit('update:val', $event.target.value)" /> 5. <button @click="addTodo()">追加</button> 6. </div> 7. <div> 8. <div v-for="(todo, i) in todoList" :key="i"> 9. {{ todo }}<button @click="deleteTodo(i)">×</button> 10. </div> 11. </div> 12. </div> 13. </template> 14. 15. <script> 16. export default { 17. name: "TodoPresentation", 18. props: { 19. todoList: Array, 20. val: String, 21. addTodo: Function, 22. deleteTodo: Function, 23. }, 24. setup() { 25. return; 26. }, 27. }; 28. </script> App.vue Todo TodoContainer App.svelte Todo TodoContainer 27 バインド バインド
React、Vueとの比較~API処理~ 28
Svelte、Reactの比較~APIモック~ 1. // APIモック 2. const fetchTodoList = async() =>
{ 3. const data = await new Promise(resolve => { 4. setTimeout(() => { 5. resolve(["テスト1", "テスト2", "テス ト3"]) 6. }, 2000) 7. }) 8. todoList = [...todoList, ...data]; 9. }; 1. // APIモック 2. const fetchTodoList = async() => { 3. const data = await new Promise(resolve => { 4. setTimeout(() => { 5. resolve(["テスト1", "テスト2", "テスト3"]) 6. }, 2000) 7. }) 8. setTodoList([...todoList, ...data]); 9. }; React Svelte 29 コード長いのでAPIモックだけ切り出し
Svelte、Reactの比較~API処理~ 1. <script> 2. import TodoContainer from "./TodoContainer.svelte" ; 3.
</script> 4. 5. <main> 6. <TodoContainer /> 7. </main> 1. import './App.css'; 2. import TodoContainer from './TodoContainer'; 3. 4. function App() { 5. 6. return ( 7. <> 8. <TodoContainer /> 9. </> 10. ); 11. } 12. 13. export default App; App.js Todo TodoContainer App.svelte Todo TodoContainer 30
Svelte、Reactの比較~API処理~ 1. <script> 2. import Todo from "./Todo.svelte" 3. 4.
let todoList = []; 5. let value = ""; 6. 7. // APIモック 8. 9. const addTodo = () => { 10. todoList = [...todoList, value]; 11. value = ""; 12. } 13. 14. const deleteTodo = (index) => { 15. todoList.splice(index, 1); 16. todoList = todoList 17. } 18. </script> 19. 20. <div> 21. {#await fetchTodoList ()} 22. <p>Loading...</p> 23. {:then _} 24. <Todo {todoList} {addTodo} {deleteTodo} bind:value /> 25. {/await} 26. </div> 1. import { useEffect , useState } from 'react' ; 2. import Todo from './Todo' ; 3. 4. function TodoContainer () { 5. const [todoList , setTodoList ] = useState ([]); 6. const [val, setVal ] = useState (""); 7. 8. // API モック 9. 10. useEffect (() => { 11. fetchTodoList (); 12. },[]); 13. 14. const addTodo = () => { 15. setTodoList ([... todoList , val]); 16. setVal (""); 17. } 18. 19. const deleteTodo = (index ) => { 20. const newTodoList = [... todoList ]; 21. newTodoList .splice (index , 1); 22. setTodoList (newTodoList ) 23. } 24. 25. if(!todoList .length ) return <p>loading... </p> 26. 27. return ( 28. <> 29. <Todo val={val} setVal ={setVal } todoList ={todoList } addTodo ={addTodo } deleteTodo ={deleteTodo }/> 30. </> 31. ); 32. } 33. 34. export default TodoContainer ; App.js Todo TodoContainer App.svelte Todo TodoContainer 31 PromiseのPending中 useEffectの処理前
Svelte、Reactの比較~API処理~ 1. <script> 2. export let todoList ; 3. export
let value; 4. export let addTodo; 5. export let deleteTodo ; 6. </script> 7. 8. <div> 9. <div> 10. <input bind:value> 11. <button on:click={addTodo}>追加</button> 12. </div> 13. <div> 14. {#each todoList as todo, i} 15. <div>{todo}<button on:click={deleteTodo (i)}>×</button></div> 16. {/each} 17. </div> 18. </div> 1. function Todo({val, setVal, todoList, addTodo, deleteTodo}) { 2. return ( 3. <> 4. <div> 5. <input type="text" value={val} onChange={(e) => setVal(e.target.value)}/> 6. <button onClick={() => addTodo()}>追加 </button> 7. </div> 8. <div> 9. {todoList.map((todo, i) => ( 10. <div key={i}>{todo}<button onClick={() => deleteTodo(i)}>×</button></div> 11. ))} 12. </div> 13. </> 14. ); 15. } 16. 17. export default Todo; App.js Todo TodoContainer App.svelte Todo TodoContainer 32
Svelte、Vueの比較~APIモック~ 1. // APIモック 2. const fetchTodoList = async() =>
{ 3. const data = await new Promise(resolve => { 4. setTimeout(() => { 5. resolve(["テスト1", "テスト2", "テス ト3"]) 6. }, 2000) 7. }) 8. todoList = [...todoList, ...data]; 9. }; 1. // APIモック 2. const fetchTodoList = async () => { 3. const data = await new Promise((resolve) => { 4. setTimeout(() => { 5. resolve(["テスト1", "テスト2", "テスト 3"]); 6. }, 2000); 7. }); 8. todoList.value.push(...data); 9. }; Vue Svelte 33
Svelte、Vueの比較~API処理~ 1. <script> 2. import TodoContainer from "./TodoContainer.svelte" ; 3.
</script> 4. 5. <main> 6. <TodoContainer /> 7. </main> 1. <template> 2. <Suspense> 3. <template #default> 4. <TodoContainer /> 5. </template> 6. <template #fallback><p>Loading...</p></template> 7. </Suspense> 8. </template> 9. 10. <script> 11. import TodoContainer from "./components/TodoContainer.vue"; 12. export default { 13. name: "App", 14. components: { 15. TodoContainer, 16. }, 17. }; 18. </script> App.vue Todo TodoContainer App.svelte Todo TodoContainer 34 PromiseのPending中
1. <script> 2. import Todo from "./Todo.svelte" 3. 4. let
todoList = []; 5. let value = ""; 6. 7. // APIモック 8. 9. const addTodo = () => { 10. todoList = [...todoList, value]; 11. value = ""; 12. } 13. 14. const deleteTodo = (index) => { 15. todoList.splice(index, 1); 16. todoList = todoList 17. } 18. </script> 19. 20. <div> 21. {#await fetchTodoList ()} 22. <p>Loading...</p> 23. {:then _} 24. <Todo {todoList} {addTodo} {deleteTodo} bind:value /> 25. {/await} 26. </div> 1. <template > 2. <Todo 3. v-model :val="val" 4. : todoList ="todoList " 5. : addTodo ="addTodo " 6. : deleteTodo ="deleteTodo " 7. /> 8. </template > 9. 10. <script > 11. import Todo from "./Todo.vue" ; 12. import { ref } from "vue" ; 13. export default { 14. name: "TodoContainer" , 15. components: { 16. Todo , 17. }, 18. async setup () { 19. const todoList = ref([]); 20. const val = ref(""); 21. 22. // API モック 23. 24. await fetchTodoList (); 25. 26. const addTodo = () => { 27. todoList .value .push (val.value ); 28. val.value = ""; 29. }; 30. const deleteTodo = ( index ) => { 31. todoList .value .splice (index , 1); 32. }; 33. return { 34. todoList , 35. val, 36. addTodo , 37. deleteTodo , 38. }; 39. }, 40. }; 41. </script > App.vue Todo TodoContainer App.svelte Todo TodoContainer 35 Svelte、Vueの比較~API処理~
1. <script> 2. export let todoList ; 3. export let
value; 4. export let addTodo; 5. export let deleteTodo ; 6. </script> 7. 8. <div> 9. <div> 10. <input bind:value> 11. <button on:click={addTodo}>追加</button> 12. </div> 13. <div> 14. {#each todoList as todo, i} 15. <div>{todo}<button on:click={deleteTodo (i)}>×</button></div> 16. {/each} 17. </div> 18. </div> 1. <template> 2. <div> 3. <div> 4. <input :value="val" @input="$emit('update:val' , $event.target.value)" /> 5. <button @click="addTodo()">追加</button> 6. </div> 7. <div> 8. <div v-for="(todo, i) in todoList" :key="i"> 9. {{ todo }}<button @click="deleteTodo (i)">×</button> 10. </div> 11. </div> 12. </div> 13. </template> 14. 15. <script> 16. export default { 17. name: "TodoPresentation" , 18. props: { 19. todoList: Array, 20. val: String, 21. addTodo: Function, 22. deleteTodo : Function, 23. }, 24. setup() { 25. return; 26. }, 27. }; 28. </script> App.vue Todo TodoContainer App.svelte Todo TodoContainer 36 Svelte、Vueの比較~API処理~
React、Vueとの比較~状態管理~ 37
Svelte、Reactの比較~状態管理~ 1. <script> 2. import TodoContainer from "./TodoContainer.svelte" ; 3.
</script> 4. 5. <main> 6. <TodoContainer /> 7. </main> 1. import { useState, createContext } from 'react'; 2. import './App.css'; 3. import TodoContainer from './TodoContainer'; 4. 5. export const TodoListContext = createContext(); 6. 7. function App() { 8. const [todoList, setTodoList] = useState(["テスト1", "テスト2", "テスト3"]) 9. 10. return ( 11. <> 12. <TodoListContext.Provider value={{todoList, setTodoList}} > 13. <TodoContainer /> 14. </TodoListContext.Provider> 15. </> 16. ); 17. } 18. 19. export default App; Store App.js Todo TodoContainer App.svelte Todo TodoContainer 38 Contextを使用
1. <script> 2. import Todo from "./Todo.svelte" 3. import {
todoList } from './store.js' ; 4. 5. let value = ""; 6. 7. const addTodo = () => { 8. $todoList = [...$todoList , value]; 9. value = ""; 10. } 11. 12. const deleteTodo = (index) => { 13. $todoList .splice(index, 1); 14. $todoList = $todoList 15. } 16. </script> 17. 18. <div> 19. <Todo {addTodo} {deleteTodo} bind:value /> 20. </div> 1. import { useState, useContext } from 'react'; 2. import Todo from './Todo'; 3. import {TodoListContext } from './App' 4. 5. function TodoContainer () { 6. const [val, setVal] = useState(""); 7. const {todoList, setTodoList } = useContext (TodoListContext ); 8. 9. const addTodo = () => { 10. setTodoList ([...todoList, val]); 11. setVal(""); 12. } 13. 14. const deleteTodo = (index) => { 15. const newTodoList = [...todoList]; 16. newTodoList .splice(index, 1); 17. setTodoList (newTodoList ) 18. } 19. 20. return ( 21. <> 22. <Todo val={val} setVal={setVal} addTodo={addTodo} deleteTodo ={deleteTodo }/> 23. </> 24. ); 25. } 26. 27. export default TodoContainer ; Store App.js Todo TodoContainer App.svelte Todo TodoContainer 39 Svelte、Reactの比較~状態管理~ $変数名でStore参照 useContextでContext参照
1. <script> 2. import { todoList } from './store.js' ;
3. export let value; 4. export let addTodo; 5. export let deleteTodo ; 6. </script> 7. 8. <div> 9. <div> 10. <input bind:value> 11. <button on:click={addTodo}>追加</button> 12. </div> 13. <div> 14. {#each $todoList as todo, i} 15. <div>{todo}<button on:click={deleteTodo (i)}>×</button></div> 16. {/each} 17. </div> 18. </div> 1. import { useContext } from 'react'; 2. import {TodoListContext} from './App' 3. 4. function Todo({val, setVal, addTodo, deleteTodo}) { 5. const { todoList } = useContext(TodoListContext); 6. return ( 7. <> 8. <div> 9. <input type="text" value={val} onChange={(e) => setVal(e.target.value)}/> 10. <button onClick={() => addTodo()}>追加</button> 11. </div> 12. <div> 13. {todoList.map((todo, i) => ( 14. <div key={i}>{todo}<button onClick={() => deleteTodo(i)}>×</button></div> 15. ))} 16. </div> 17. </> 18. ); 19. } 20. 21. export default Todo; Store App.js Todo TodoContainer App.svelte Todo TodoContainer 40 Svelte、Reactの比較~状態管理~
1. import { writable } from 'svelte/store' ; 2. 3.
export const todoList = writable(["テスト 1", "テスト2", "テスト3"]); Store App.js Todo TodoContainer App.svelte Todo TodoContainer 41 Svelte、Reactの比較~状態管理~ readableやderived等も宣言可能
Svelte、Vueの比較~状態管理~ 1. <script> 2. import TodoContainer from "./TodoContainer.svelte" ; 3.
</script> 4. 5. <main> 6. <TodoContainer /> 7. </main> 1. <template> 2. <TodoContainer /> 3. </template> 4. 5. <script> 6. import TodoContainer from "./components/TodoContainer.vue"; 7. export default { 8. name: "App", 9. components: { 10. TodoContainer, 11. }, 12. }; 13. </script> Store Store main App.vue Todo TodoContainer App.svelte Todo TodoContainer 42
1. <script> 2. import Todo from "./Todo.svelte" 3. import {
todoList } from './store.js' ; 4. 5. let value = ""; 6. 7. const addTodo = () => { 8. $todoList = [...$todoList , value]; 9. value = ""; 10. } 11. 12. const deleteTodo = (index) => { 13. $todoList .splice(index, 1); 14. $todoList = $todoList 15. } 16. </script> 17. 18. <div> 19. <Todo {addTodo} {deleteTodo} bind:value /> 20. </div> 1. <template > 2. <Todo v-model :val="val" :addTodo ="addTodo " :deleteTodo ="deleteTodo " /> 3. </template > 4. 5. <script> 6. import Todo from "./Todo.vue" ; 7. import { ref } from "vue"; 8. import store from "../store" ; 9. export default { 10. name: "TodoContainer" , 11. components: { 12. Todo, 13. }, 14. setup() { 15. const val = ref(""); 16. 17. const addTodo = function () { 18. store.commit("addTodo" , val.value); 19. val.value = ""; 20. }; 21. const deleteTodo = function (index) { 22. store.commit("deleteTodo" , index); 23. }; 24. return { 25. val, 26. addTodo , 27. deleteTodo , 28. }; 29. }, 30. }; 31. </script> Store Store main App.vue Todo TodoContainer App.svelte Todo TodoContainer 43 Svelte、Vueの比較~状態管理~ 直接Stateを操作しない
1. <script> 2. import { todoList } from './store.js' ;
3. export let value; 4. export let addTodo; 5. export let deleteTodo ; 6. </script> 7. 8. <div> 9. <div> 10. <input bind:value> 11. <button on:click={addTodo}>追加</button> 12. </div> 13. <div> 14. {#each $todoList as todo, i} 15. <div>{todo}<button on:click={deleteTodo (i)}>×</button></div> 16. {/each} 17. </div> 18. </div> 1. <template> 2. <div> 3. <div> 4. <input :value="val" @input="$emit('update:val' , $event.target.value)" /> 5. <button @click="addTodo()">追加</button> 6. </div> 7. <div> 8. <div v-for="(todo, i) in this.$store.state.todoList" :key="i"> 9. {{ todo }}<button @click="deleteTodo (i)">×</button> 10. </div> 11. </div> 12. </div> 13. </template> 14. 15. <script> 16. export default { 17. name: "TodoPresentation" , 18. props: { 19. val: String, 20. addTodo: Function, 21. deleteTodo : Function, 22. }, 23. setup() { 24. return; 25. }, 26. }; 27. </script> Store Store main App.vue Todo TodoContainer App.svelte Todo TodoContainer 44 Svelte、Vueの比較~状態管理~
1. import { writable } from 'svelte/store' ; 2. 3.
export const todoList = writable(["テスト 1", "テスト2", "テスト3"]); 1. import { createStore } from 'vuex' 2. 3. export default createStore({ 4. state () { 5. return { 6. todoList: ["テスト1", "テスト2", "テスト3"] 7. } 8. }, 9. mutations: { 10. addTodo(state, value){ 11. state.todoList.push(value); 12. }, 13. deleteTodo(state, index){ 14. state.todoList.splice(index, 1); 15. } 16. }, 17. actions: { 18. }, 19. modules: { 20. } 21. }) Store Store main App.vue Todo TodoContainer App.svelte Todo TodoContainer 45 Svelte、Vueの比較~状態管理~ 本当はここからmutations呼び出し
1. import { createApp } from 'vue' 2. import App
from './App.vue' 3. import store from './store' 4. 5. createApp(App).use(store).mount('#app') Store Store App.vue Todo TodoContainer App.svelte Todo TodoContainer 46 Svelte、Vueの比較~状態管理~ main
実際に記述した感想 47
実際に記述した感想 + 書きやすい + 公式ページのチュートリアルが充実している + Vue経験者は取っ付きやすそう + データバインディング簡単 +
store簡単 48
実際に記述した感想 − propsの受け渡しがexportなのに違和感 − テストの設定記述が面倒 − 規模が大きくなった時の管理が大変そう − マテリアルデザインの選択肢が少ない − TypeScriptないと大分厳しい ←
Svelte関係ない − 実行コマンド統一してほしい ← package.json書きましょう 49
まとめ 50
まとめ Svelteは… 課題はたくさんある! けど 記述しやすく、今後伸びそう! なWebフレームワーク(個人的意見) 51
扱いたかった題材 • Next.js、Nuxt.js、Svelte Kitの比較 • マテリアルデザインの適用 • ライブラリ関係 • TypeScriptとの親和性
• パフォーマンス測定 52
参考 • Svelte https://svelte.jp/ • Vue.js https://v3.ja.vuejs.org/ • React https://ja.reactjs.org/
• Bundlephobia https://bundlephobia.com/ 53