Vue 入門

目錄

  • 現狀

  • 優缺點

  • Component 結構

  • <script />

  • <template />

  • EXAMPLE

現狀

3.0 特性

Composition API

首次渲染速度比 2.0 快 55%,更新速度快 133%,記憶體減少使用 54%

TypeScript UP UP

優缺點

優點

雙向綁定很簡單

容量小 輕量

模板語法平易近人

Render 機制友善

模板語法

缺點

Component 結構

<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 />

<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 />

V-bind

<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>

v-text v-html

<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>

V-if V-else V-else-if

<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>

V-on

<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>

V-For

<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>

V-model

<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>

Custome ...

Example

<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>

DEMO

END

Made with Slides.com