声明式渲染

<script>
export default {
data() {
return {
message: "haorical",
};
},
};
</script>

<template>
<h1>{{message}}</h1>
</template>

Attribute 绑定

<script>
export default {
data() {
return {
titleClass: "title",
};
},
};
</script>

<template>
<!-- 此处添加一个动态 class 绑定 -->
<h1 v-bind:class="titleClass">Make me red</h1>
<!-- 缩写 -->
<h1 :class="titleClass">Make me red</h1>
</template>

<style>
.title {
color: red;
}
</style>

事件监听

<script>
export default {
data() {
return {
count: 0,
};
},
methods: {
cnt() {
this.count++;
},
},
};
</script>

<template>
<!-- 使此按钮生效 -->
<button @click="cnt">count is: {{ count }}</button>
</template>

表单绑定

<script>
export default {
data() {
return {
text: "hahaha",
};
},
};
</script>

<template>
<input v-model="text" placeholder="Type here" />
<p>{{ text }}</p>
</template>

条件渲染

<script>
export default {
data() {
return {
awesome: true,
};
},
methods: {
toggle() {
this.awesome = !this.awesome;
},
},
};
</script>

<template>
<button @click="toggle">toggle</button>
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
</template>


列表渲染

<script>
// 给每个 todo 对象一个唯一的 id
let id = 0;

export default {
data() {
return {
newTodo: "",
todos: [
{ id: id++, text: "Learn HTML" },
{ id: id++, text: "Learn JavaScript" },
{ id: id++, text: "Learn Vue" },
],
};
},
methods: {
addTodo() {
// 添加todo
var haha = { id: id++, text: this.newTodo };
this.todos.push(haha);
this.newTodo = "";
},
removeTodo(todo) {
// 删除todo
this.todos = this.todos.filter((x) => x !== todo);
},
},
};
</script>

<template>
<form @submit.prevent="addTodo">
<input v-model="newTodo" />
<button>Add Todo</button>
<p>{{newTodo}}</p>
</form>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
<button @click="removeTodo(todo)">X</button>
</li>
</ul>
</template>

计算属性

<script>
let id = 0;

export default {
data() {
return {
newTodo: "",
hideCompleted: false,
todos: [
{ id: id++, text: "Learn HTML", done: true },
{ id: id++, text: "Learn JavaScript", done: true },
{ id: id++, text: "Learn Vue", done: false },
],
};
},
computed: {
filteredTodos() {
return this.todos.filter((x) => x.done != this.hideCompleted);
},
},
methods: {
addTodo() {
this.todos.push({ id: id++, text: this.newTodo, done: false });
this.newTodo = "";
},
removeTodo(todo) {
this.todos = this.todos.filter((t) => t !== todo);
},
},
};
</script>

<template>
<form @submit.prevent="addTodo">
<input v-model="newTodo" />
<button>Add Todo</button>
</form>
<ul>
<li v-for="todo in filteredTodos" :key="todo.id">
<input type="checkbox" v-model="todo.done" />
<span :class="{ done: todo.done }">{{ todo.text }}</span>
<button @click="removeTodo(todo)">X</button>
</li>
</ul>
<button @click="hideCompleted = !hideCompleted">
{{ hideCompleted ? 'Show all' : 'Hide completed' }}
</button>
</template>

<style>
.done {
text-decoration: line-through;
}
</style>

生命周期和模板引用

<script>
export default {
mounted() {
this.$refs.p.style.color = "red";
},
};
</script>

<template>
<p ref="p">hello</p>
</template>

侦听器

<script>
export default {
data() {
return {
todoId: 1,
todoData: null,
};
},
methods: {
async fetchData() {
this.todoData = null;
const res = await fetch(
`https://jsonplaceholder.typicode.com/todos/${this.todoId}`
);
this.todoData = await res.json();
},
},
mounted() {
this.fetchData();
},
watch: {
todoId(newtodoId) {
this.fetchData();
},
},
};
</script>

<template>
<p>Todo id: {{ todoId }}</p>
<button @click="todoId++">Fetch next todo</button>
<p v-if="!todoData">Loading...</p>
<pre v-else>{{ todoData }}</pre>
</template>

组件

// app.vue
<script>
import xxx from "./ChildComp.vue";
export default {
components: {
xxx,
},
};
</script>

<template>
<xxx />
</template>

// ChildComp.vue
<template>
<h2>A Child Component!</h2>
</template>

Props

// app.vue
<script>
import ChildComp from "./ChildComp.vue";

export default {
components: {
ChildComp,
},
data() {
return {
greeting: "Hello from parent",
};
},
};
</script>

<template>
<ChildComp :msg="greeting" />
</template>

// ChildComp.vue
<script>
export default {
props: {
msg: String,
},
};
</script>

<template>
<h2>{{ msg || 'No props passed yet' }}</h2>
</template>

Emits

// app.vue
<script>
import ChildComp from "./ChildComp.vue";

export default {
components: {
ChildComp,
},
data() {
return {
childMsg: "No child msg yet",
};
},
};
</script>

<template>
<ChildComp @response="(msg) => this.childMsg=msg" />
<p>{{ childMsg }}</p>
</template>

// child.vue
<script>
export default {
emits: ["response"],
created() {
this.$emit("response", "hello from child");
},
};
</script>

<template>
<h2>Child component</h2>
</template>

插槽

// app.vue
<script>
import ChildComp from "./ChildComp.vue";

export default {
components: {
ChildComp,
},
data() {
return {
msg: "from parent",
};
},
};
</script>

<template>
<ChildComp>{{msg}}</ChildComp>
</template>

// child.vue
<template>
<slot>Fallback content</slot>
</template>