現狀
優缺點
Component 結構
<script />
<template />
EXAMPLE
Composition API
首次渲染速度比 2.0 快 55%,更新速度快 133%,記憶體減少使用 54%
TypeScript UP UP
雙向綁定很簡單
容量小 輕量
模板語法平易近人
Render 機制友善
<template>
<!-- <template lang="pug"> -->
<div class="container">
<h1 class="title">Vue Component</h1>
<HelloWorld msg="A basic Vue component." />
</div>
</template>
<template>
<!-- <template lang="pug"> -->
<div class="container">
<h1 class="title">Vue Component</h1>
<HelloWorld msg="A basic Vue component." />
</div>
</template>
<script>
// <script lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld
}
};
</script>
<template>
<!-- <template lang="pug"> -->
<div class="container">
<h1 class="title">Vue Component</h1>
<HelloWorld msg="A basic Vue component." />
</div>
</template>
<script>
// <script lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld
}
};
</script>
<style>
/* <style lang="scss"> sass, less, stylus */
/* <style lang="scss" scoped> */
.container {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
}
.title {
color: #42b983;
font-size: 8rem;
}
</style>
<template>
<!-- <template lang="pug"> -->
<div class="container">
<h1 class="title">Vue Component</h1>
<HelloWorld msg="A basic Vue component." />
</div>
</template>
<script>
// <script lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld
}
};
</script>
<style>
/* <style lang="scss"> sass, less, stylus */
/* <style lang="scss" scoped> */
.container {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
}
.title {
color: #42b983;
font-size: 8rem;
}
</style>
<docs>
## Example ...
</docs>
<script>
export default {};
</script>
<script>
import { onMounted, onBeforeUnmount } from "vue";
export default {
setup() {
// created ...
// ex. fetch api, init data ...
onMounted(() => {
// Do things ...
// ex. add event lister, or use third-party library
console.log("Mounted!");
});
onBeforeUnmount(() => {
// Do things ...
// ex. remove event lister
console.log("Before Unmount!");
});
}
};
</script>
<script>
import { onMounted, onBeforeUnmount, ref } from "vue";
export default {
setup() {
// created ...
// ex. fetch api, init data ...
// Ref, works like React useRef()
const name = ref("");
onMounted(() => {
// Do things ...
// ex. add event lister, or use third-party library
console.log("Mounted!");
console.log(name.value);
name.value = "Steven";
});
onBeforeUnmount(() => {
// Do things ...
// ex. remove event lister
console.log("Before Unmount!");
});
return {
name
};
}
};
</script>
<template>
<div ref="element"></div>
{{ name }}
</template>
<script>
import { onMounted, onBeforeUnmount, ref } from "vue";
export default {
setup() {
// created ...
// ex. fetch api, init data ...
// Ref, works like React useRef()
const name = ref("");
const element = ref(null);
onMounted(() => {
// Do things ...
// ex. add event lister, or use third-party library
console.log("Mounted!");
console.log(name.value);
name.value = "Steven";
element.value.innerHTML = "New content";
});
onBeforeUnmount(() => {
// Do things ...
// ex. remove event lister
console.log("Before Unmount!");
});
return {
element,
name
};
}
};
</script>
<template>
<div ref="element"></div>
{{ name }}
<HelloWorld />
</template>
<script>
import { onMounted, onBeforeUnmount, ref } from "vue";
import HelloWorld from "@/components/HelloWorld";
export default {
components: {
HelloWorld
},
// props: ["age"],
props: {
age: {
// Boolean, Number
type: Number,
// Optional
default: 50,
// Optional
required: true,
// Optional
validator: function(value) {
return value >= 50;
}
}
},
setup() {
// created ...
// ex. fetch api, init data ...
// Ref, works like React useRef()
const name = ref("");
const element = ref(null);
onMounted(() => {
// Do things ...
// ex. add event lister, or use third-party library
console.log("Mounted!");
console.log(name.value);
name.value = "Steven";
element.value.innerHTML = "New content";
});
onBeforeUnmount(() => {
// Do things ...
// ex. remove event lister
console.log("Before Unmount!");
});
return {
name,
element
};
}
};
</script>
<template>
<div :class="containerClass">
Container
</div>
<div v-bind:class="containerClass">
Container
</div>
<!-- <HelloWorld :msg="msg" /> -->
<!-- <HelloWorld v-bind="{ msg }" /> -->
</template>
<script>
export default {
setup() {
return {
containerClass: "container",
msg: "Hi"
};
}
};
</script>
<template>
<div v-text="msg" />
<div>
{{ msg }}
</div>
<div>
{{ isGreeting ? "Hello" : "Nope" }}
</div>
<!-- <div>
{{ if(isGreeting) 'Nope' }}
</div> -->
<div>
{{ Object.keys(user) }}
</div>
<div v-html="htmlContent" />
</template>
<script>
export default {
setup() {
return {
msg: "Hi",
isGreeting: true,
htmlContent: '<p style="color: red;">I am HTML content</p>',
user: {
id: 1,
name: "user1",
type: "VIP",
gender: "male"
}
};
}
};
</script>
<template>
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
</template>
<script>
export default {
setup() {
return {
type: "D"
};
}
};
</script>
<template>
<button @click="handleClickButton">點我</button>
<button v-on:click="handleClickButton">點我</button>
<form @submit.prevent="handleSubmit">
<input type="text" @keydown.enter.prevent="handleInputEnter" />
<button type="submit">送出按鈕</button>
</form>
<p>
{{ eventMessage }}
</p>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const eventMessage = ref("");
const handleClickButton = () => (eventMessage.value = "被點了");
const handleSubmit = () =>
(eventMessage.value = "被送出了,但不會有預設行為");
const handleInputEnter = () => (eventMessage.value = "我被按 Enter 了");
return {
eventMessage,
handleClickButton,
handleSubmit,
handleInputEnter
};
}
};
</script>
<template>
<div v-for="user in users" :key="user.id">
<p>{{ user }}</p>
<p>{{ user.name }}</p>
</div>
<div v-for="(column, index) in USER_1" :key="index">
<span>{{ index }}</span> : <span>{{ column }}</span>
</div>
</template>
<script>
const USER_1 = {
id: 1,
name: "user1",
type: "VIP",
gender: "male"
};
const USER_2 = {
id: 2,
name: "user2",
type: "VIP",
gender: "female"
};
const users = [USER_1, USER_2];
export default {
setup() {
return {
USER_1,
users
};
}
};
</script>
<template>
<form>
<input v-model="name" />
</form>
<p>{{ name }}</p>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const name = ref("Steven");
return {
name
};
}
};
</script>
<template>
<h1>ToDo Example</h1>
<form @submit.prevent="addTodo()">
<label>Add ToDo</label>
<input v-model="newTodo" name="newTodo" autocomplete="off" />
<button type="submit">Add</button>
</form>
<h2>ToDo List</h2>
<ul>
<li v-for="(todo, index) in todos" :key="index">
<span :class="{ done: todo.done }" @click="doneTodo(todo)">{{
todo.content
}}</span>
<button @click="removeTodo(index)">Remove</button>
</li>
</ul>
<h4 v-if="todos.length === 0">Empty list.</h4>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const newTodo = ref("");
const defaultData = [
{
done: false,
content: "Workshop presentation"
}
];
const todosData = JSON.parse(localStorage.getItem("todos")) || defaultData;
const todos = ref(todosData);
const addTodo = () => {
if (newTodo.value) {
todos.value.push({
done: false,
content: newTodo.value
});
newTodo.value = "";
}
saveData();
};
const doneTodo = todo => {
todo.done = !todo.done;
saveData();
};
const removeTodo = index => {
todos.value.splice(index, 1);
saveData();
};
const saveData = () => {
const storageData = JSON.stringify(todos.value);
localStorage.setItem("todos", storageData);
};
return {
todos,
newTodo,
addTodo,
doneTodo,
removeTodo,
saveData
};
}
};
</script>