aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw
diff options
context:
space:
mode:
authorPin-Ting Tang <qiiwiiq@hotmail.com>2021-05-07 10:53:54 +0800
committerGitHub <noreply@github.com>2021-05-07 10:53:54 +0800
commit86a8f14ca7218f2709c898fe7ed1ceddf6135cf3 (patch)
treec8a89d6c414033f0ad68443eb667ac2be9e896dd /files/zh-tw
parent15b682f3ce7549aac1711f78e64bdb5aa6679a41 (diff)
downloadtranslated-content-86a8f14ca7218f2709c898fe7ed1ceddf6135cf3.tar.gz
translated-content-86a8f14ca7218f2709c898fe7ed1ceddf6135cf3.tar.bz2
translated-content-86a8f14ca7218f2709c898fe7ed1ceddf6135cf3.zip
Update /learn/tools_and_testing/client-side_javascript_frameworks, zh-TW (#766)
* fix: Getting started with Vue 修改用詞 * update: Creating our first Vue component 頁面翻譯 (zh-TW, partial) * fix: 修改連結 - /en-US 改成 /zh-TW
Diffstat (limited to 'files/zh-tw')
-rw-r--r--files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_first_component/index.html403
-rw-r--r--files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_first_component/rendered-todoitem.pngbin0 -> 3024 bytes
-rw-r--r--files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_getting_started/index.html2
3 files changed, 404 insertions, 1 deletions
diff --git a/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_first_component/index.html b/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_first_component/index.html
new file mode 100644
index 0000000000..bdeb008621
--- /dev/null
+++ b/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_first_component/index.html
@@ -0,0 +1,403 @@
+---
+title: 建立第一個 Vue 元件
+slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component
+tags:
+ - Beginner
+ - Components
+ - Frameworks
+ - JavaScript
+ - Learn
+ - client-side
+ - props
+ - state
+ - vue
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</div>
+
+<p class="summary">現在是時候來更深入了解 Vue ,以及建立我們自訂的元件——我們將從建立一個元件開始,這個元件代表待辦清單裡的每一個項目。在過程中,我們會學到一些重要的概念,例如在元件裡面調用其他元件,使用 props 傳遞資料,以及儲存它的狀態( state )。</p>
+
+<div class="notecard note">
+<p class="summary"><strong>注意</strong>:如果你需要根據我們的版本來檢查你的程式碼,你可以從 <a href="https://github.com/mdn/todo-vue">todo-vue 存放庫</a>找到 Vue 範例應用程式最終版本的程式碼。有關實際運行的版本,請看 <a href="https://mdn.github.io/todo-vue/dist/">https://mdn.github.io/todo-vue/dist/</a> 。</p>
+</div>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">預備知識:</th>
+ <td>
+ <p>熟悉 <a href="/zh-TW/docs/Learn/HTML">HTML</a> 、 <a href="/zh-TW/docs/Learn/CSS">CSS</a> 以及 <a href="/zh-TW/docs/Learn/JavaScript">JavaScript</a> 核心語言,具備 <a href="/zh-TW/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">terminal/command line</a> 的知識。</p>
+
+ <p>Vue 元件是由 Javascript 物件(用來管理應用程式的資料)及樣版語法(用來映射成 DOM 結構)所組成的。此外,你將需要使用終端機安裝 node 和 npm ,以便下載及使用一些 Vue 的進階功能(像是單一檔案的元件或是渲染函式)。</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">目標:</th>
+ <td>學習如何建立一個 Vue 元件,將其渲染到另一個元件裡,使用 props 傳遞資料,以及儲存它的狀態( state )。</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Creating_a_ToDoItem_component">建立一個 ToDoItem 元件</h2>
+
+<p>來建立我們的一個元件,這個元件會顯示一個待辦項目,我們會使用它來建立待辦清單。</p>
+
+<ol>
+ <li>在你的 <code>moz-todo-vue/src/components</code> 資料夾裡建立一個新檔案並命名為 <code>ToDoItem.vue</code> 。在程式編輯器打開這個檔案。</li>
+ <li>在檔案頂端加上 <code>&lt;template&gt;&lt;/template&gt;</code> 來建立元件的模板。</li>
+ <li>在 template 區塊底下建立一個 <code>&lt;script&gt;&lt;/script&gt;</code> 區塊。在 <code>&lt;script&gt;</code> 標籤之間加上一個預設匯出的物件 <code>export default {}</code> ,這是你的元件物件。</li>
+</ol>
+
+<p>現在你的檔案應該會像這樣:</p>
+
+<pre class="brush: html">&lt;template&gt; &lt;/template&gt;
+&lt;script&gt;
+ export default {};
+&lt;/script&gt;</pre>
+
+<p>我們現在開始為 <code>ToDoItem</code> 添加實際內容。目前 Vue 模板只允許存在一個根元素——用一個元素來包裝在 template 區塊裡面的所有內容(這個情況在 Vue 3 發布後會改變)。我們將使用一個 <code><a href="/zh-TW/docs/Web/HTML/Element/div">&lt;div&gt;</a></code> 來做為根元素。</p>
+
+<ol>
+ <li>
+ <p>現在在元件 template 裡面新增一個空的 <code>&lt;div&gt;</code> 。</p>
+ </li>
+ <li>
+ <p>在這個 <code>&lt;div&gt;</code> 裡面,新增一個 checkbox 和一個相對應的 label。在 checkbox 加上一個 <code>id</code> 屬性,並在 label 加上 <code>for</code> 屬性,使 checkbox 對應到 label 。如下所示。</p>
+
+ <pre class="brush: html">&lt;template&gt;
+ &lt;div&gt;
+ &lt;input type="checkbox" id="todo-item" checked="false" /&gt;
+ &lt;label for="todo-item"&gt;My Todo Item&lt;/label&gt;
+ &lt;/div&gt;
+&lt;/template&gt;</pre>
+ </li>
+</ol>
+
+<h3 id="Using_TodoItem_inside_our_app">在我們的應用程式裡使用 TodoItem</h3>
+
+<p>目前一切都很好,但是我們還沒把元件加到應用程式裡面,所以沒辦法測試它是否可以正常運作。現在讓我們把它加到應用程式裡。</p>
+
+<ol>
+ <li>
+ <p>再一次打開 <code>App.vue</code> 。</p>
+ </li>
+ <li>
+ <p>在 <code>&lt;script&gt;</code> 標籤的頂端,加上以下內容來匯入 <code>ToDoItem</code> 元件:</p>
+
+ <pre class="brush: js">import ToDoItem from './components/ToDoItem.vue';</pre>
+ </li>
+ <li>
+ <p>在元件物件裡面添加 <code>components</code> 屬性,然後在它裡面添加 <code>ToDoItem</code> 元件來註冊它。</p>
+ </li>
+</ol>
+
+<p>現在你的 <code>&lt;script&gt;</code> 內容應該會像這樣:</p>
+
+<pre class="brush: js">import ToDoItem from './components/ToDoItem.vue';
+
+export default {
+ name: 'app',
+ components: {
+ ToDoItem
+ }
+};</pre>
+
+<p>這和之前 Vue CLI 註冊 <code>HelloWorld</code> 元件是同樣的方法。</p>
+
+<p>要在應用程式裡實際渲染 <code>ToDoItem</code> 元件,你需要在 <code>&lt;template&gt;</code> 元素裡面呼叫它——加上 <code>&lt;to-do-item&gt;&lt;/to-do-item&gt;</code> 元素。請注意,元件檔案名稱和它在 JavaScript 的表示法通常是用大駝峰式命名法( PascalCase ,例如: <code>ToDoList</code> ),而相對應的自訂元素是用 kebab-case(例如: <code>&lt;to-do-list&gt;</code> )。</p>
+
+<ol>
+ <li>在 <code><a href="/zh-TW/docs/Web/HTML/Element/Heading_Elements">&lt;h1&gt;</a></code> 底下建立一個無序清單( <code><a href="/zh-TW/docs/Web/HTML/Element/ul">&lt;ul&gt;</a></code> )包含單一個清單項目( <code><a href="/zh-TW/docs/Web/HTML/Element/li">&lt;li&gt;</a></code> )。</li>
+ <li>在清單項目( &lt;li&gt; )裡面加上 <code>&lt;to-do-item&gt;&lt;/to-do-item&gt;</code> 。</li>
+</ol>
+
+<p>現在你的 <code>App.vue</code> 的 <code>&lt;template&gt;</code> 內容應該會像這樣:</p>
+
+<pre class="brush: html">&lt;div id="app"&gt;
+ &lt;h1&gt;To-Do List&lt;/h1&gt;
+ &lt;ul&gt;
+ &lt;li&gt;
+ &lt;to-do-item&gt;&lt;/to-do-item&gt;
+ &lt;/li&gt;
+ &lt;/ul&gt;
+&lt;/div&gt;</pre>
+
+<p>如果你再次查看渲染應用程式,現在應該會看到你渲染的 <code>ToDoItem</code> 元件,它包含一個 checkbox 和 label 。</p>
+
+<p><img alt="目前應用程式的渲染狀態——包含一個標題( To-Do List ),一個 checkbox 和 label" src="rendered-todoitem.png" style="border-style: solid; border-width: 1px; display: block; margin: 0 auto;"></p>
+
+<h2 id="Making_components_dynamic_with_props">Making components dynamic with props</h2>
+
+<p>Our <code>ToDoItem</code> component is still not very useful because we can only really include this once on a page (IDs need to be unique), and we have no way to set the label text. Nothing about this is dynamic.</p>
+
+<p>What we need is some component state. This can be achieved by adding props to our component. You can think of props as being similar to inputs in a function. The value of a prop gives components an initial state that affects their display.</p>
+
+<h3 id="Registering_props">Registering props</h3>
+
+<p>In Vue, there are two ways to register props:</p>
+
+<ul>
+ <li>The first way is to just list props out as an array of strings. Each entry in the array corresponds to the name of a prop.</li>
+ <li>The second way is to define props as an object, with each key corresponding to the prop name. Listing props as an object allows you to specify default values, mark props as required, perform basic object typing (specifically around JavaScript primitive types), and perform simple prop validation.</li>
+</ul>
+
+<div class="notecard note">
+<p><strong>Note</strong>: Prop validation only happens in development mode, so you can't strictly rely on it in production. Additionally, prop validation functions are invoked before the component instance is created, so they do not have access to the component state (or other props).</p>
+</div>
+
+<p>For this component, we’ll use the object registration method.</p>
+
+<ol>
+ <li>Go back to your <code>ToDoItem.vue</code> file.</li>
+ <li>Add a <code>props</code> property inside the export <code>default {}</code> object, which contains an empty object.</li>
+ <li>Inside this object, add two properties with the keys <code>label</code> and <code>done</code>.</li>
+ <li>The <code>label</code> key's value should be an object with 2 properties (or <strong>props</strong>, as they are called in the context of being available to the components).
+ <ol>
+ <li>The first is a <code>required</code> property, which will have a value of <code>true</code>. This will tell Vue that we expect every instance of this component to have a label field. Vue will warn us if a <code>ToDoItem</code> component does not have a label field.</li>
+ <li>The second property we'll add is a <code>type</code> property. Set the value for this property as the JavaScript <code>String</code> type (note the capital "S"). This tells Vue that we expect the value of this property to be a string.</li>
+ </ol>
+ </li>
+ <li>Now on to the <code>done</code> prop.
+ <ol>
+ <li>First add a <code>default</code> field, with a value of <code>false</code>. This means that when no <code>done</code> prop is passed to a <code>ToDoItem</code> component, the <code>done</code> prop will have a value of false (bear in mind that this is not required — we only need <code>default</code> on non-required props).</li>
+ <li>Next add a <code>type</code> field with a value of <code>Boolean</code>. This tells Vue we expect the value prop to be a JavaScript boolean type.</li>
+ </ol>
+ </li>
+</ol>
+
+<p>Your component object should now look like this:</p>
+
+<pre class="brush: js">&lt;script&gt;
+ export default {
+ props: {
+ label: { required: true, type: String },
+ done: { default: false, type: Boolean }
+ }
+ };
+&lt;/script&gt;</pre>
+
+<h3 id="Using_registered_props">Using registered props</h3>
+
+<p>With these props defined inside the component object, we can now use these variable values inside our template. Let's start by adding the <code>label</code> prop to the component template.</p>
+
+<p>In your <code>&lt;template&gt;</code>, replace the contents of the <code>&lt;label&gt;</code> element with <code>\{{label}}</code>.</p>
+
+<p><code>\{{}}</code> is a special template syntax in Vue, which lets us print the result of JavaScript expressions defined in our class, inside our template, including values and methods. It’s important to know that content inside <code>\{{}}</code> is displayed as text and not HTML. In this case, we’re printing the value of the <code>label</code> prop.</p>
+
+<p>Your component’s template section should now look like this:</p>
+
+<pre class="brush: html">&lt;template&gt;
+ &lt;div&gt;
+ &lt;input type="checkbox" id="todo-item" checked="false" /&gt;
+ &lt;label for="todo-item"&gt;\{{label}}&lt;/label&gt;
+ &lt;/div&gt;
+&lt;/template&gt;</pre>
+
+<p>Go back to your browser and you'll see the todo item rendered as before, but without a label (oh no!). Go to your browser's DevTools and you’ll see a warning along these lines in the console:</p>
+
+<pre>[Vue warn]: Missing required prop: "label"
+
+found in
+
+---&gt; &lt;ToDoItem&gt; at src/components/ToDoItem.vue
+ &lt;App&gt; at src/App.vue
+ &lt;Root&gt;
+</pre>
+
+<p>This is because we marked the <code>label</code> as a required prop, but we never gave the component that prop — we've defined where inside the template we want it used, but we haven't passed it into the component when calling it. Let’s fix that.</p>
+
+<p>Inside your <code>App.vue</code> file, add a <code>label</code> prop to the <code>&lt;to-do-item&gt;&lt;/to-do-item&gt;</code> component, just like a regular HTML attribute:</p>
+
+<pre class="brush: html">&lt;to-do-item label="My ToDo Item"&gt;&lt;/to-do-item&gt;</pre>
+
+<p>Now you'll see the label in your app, and the warning won't be spat out in the console again.</p>
+
+<p>So that's props in a nutshell. Next we'll move on to how Vue persists data state.</p>
+
+<h2 id="Vues_data_object">Vue's data object</h2>
+
+<p>If you change the value of the <code>label</code> prop passed into the <code>&lt;to-do-item&gt;&lt;/to-do-item&gt;</code> call in your App component, you should see it update. This is great. We have a checkbox, with an updatable label. However, we're currently not doing anything with the "done" prop — we can check the checkboxes in the UI, but nowhere in the app are we recording whether a todo item is actually done.</p>
+
+<p>To achieve this, we want to bind the component's <code>done</code> prop to the <code>checked</code> attribute on the <code><a href="/zh-TW/docs/Web/HTML/Element/input">&lt;input&gt;</a></code> element, so that it can serve as a record of whether the checkbox is checked or not. However, it's important that props serve as one-way data binding — a component should never alter the value of its own props. There are a lot of reasons for this. In part, components editing props can make debugging a challenge. If a value is passed to multiple children, it could be hard to track where the changes to that value were coming from. In addition, changing props can cause components to re-render. So mutating props in a component would trigger the component to rerender, which may in-turn trigger the mutation again.</p>
+
+<p>To work around this, we can manage the <code>done</code> state using Vue’s <code>data</code> property. The <code>data</code> property is where you can manage local state in a component, it lives inside the component object alongside the <code>props</code> property and has the following structure:</p>
+
+<pre class="brush: js">data() {
+ return {
+ key: value
+ }
+}</pre>
+
+<p>You'll note that the <code>data</code> property is a function. This is to keep the data values unique for each instance of a component at runtime — the function is invoked separately for each component instance. If you declared data as just an object, all instances of that component would share the same values. This is a side-effect of the way Vue registers components and something you do not want.</p>
+
+<p>You use <code>this</code> to access a component's props and other properties from inside data, as you may expect. We'll see an example of this shortly.</p>
+
+<div class="notecard note">
+<p><strong>Note</strong>: Because of the way that <code>this</code> works in arrow functions (binding to the parent’s context), you wouldn’t be able to access any of the necessary attributes from inside <code>data</code> if you used an arrow function. So don’t use an arrow function for the <code>data</code> property.</p>
+</div>
+
+<p>So let's add a <code>data</code> property to our <code>ToDoItem</code> component. This will return an object containing a single property that we'll call <code>isDone</code>, whose value is <code>this.done</code>.</p>
+
+<p>Update the component object like so:</p>
+
+<pre class="brush: js">export default {
+ props: {
+ label: { required: true, type: String },
+ done: { default: false, type: Boolean }
+ },
+ data() {
+ return {
+ isDone: this.done
+ };
+ }
+};</pre>
+
+<p>Vue does a little magic here — it binds all of your props directly to the component instance, so we don’t have to call <code>this.props.done</code>. It also binds other attributes (<code>data</code>, which you’ve already seen, and others like <code>methods</code>, <code>computed</code>, etc.) directly to the instance. This is, in part, to make them available to your template. The down-side to this is that you need to keep the keys unique across these attributes. This is why we called our <code>data</code> attribute <code>isDone</code> instead of <code>done</code>.</p>
+
+<p>So now we need to attach the <code>isDone</code> property to our component. In a similar fashion to how Vue uses <code>\{{}}</code> expressions to display JavaScript expressions inside templates, Vue has a special syntax to bind JavaScript expressions to HTML elements and components: <code><strong>v-bind</strong></code>. The <code>v-bind</code> expression looks like this:</p>
+
+<pre>v-bind:attribute="expression"</pre>
+
+<p>In other words, you prefix whatever attribute/prop you want to bind to with <code>v-bind:</code>. In most cases, you can use a shorthand for the <code>v-bind</code> property, which is to just prefix the attribute/prop with a colon. So <code>:attribute="expression"</code> works the same as <code>v-bind:attribute="expression"</code>.</p>
+
+<p>So in the case of the checkbox in our <code>ToDoItem</code> component, we can use <code>v-bind</code> to map the <code>isDone</code> property to the <code>checked</code> attribute on the <code>&lt;input&gt;</code> element. Both of the following are equivalent:</p>
+
+<pre class="brush: html">&lt;input type="checkbox" id="todo-item" v-bind:checked="isDone" /&gt;
+
+&lt;input type="checkbox" id="todo-item" :checked="isDone" /&gt;</pre>
+
+<p>You're free to use whichever pattern you would like. It's best to keep it consistent though. Because the shorthand syntax is more commonly used, this tutorial will stick to that pattern.</p>
+
+<p>So let's do this. Update your <code>&lt;input&gt;</code> element now to replace <code>checked="false"</code> with <code>:checked="isDone"</code>.</p>
+
+<p>Test out your component by passing <code>:done="true"</code> to the <code>ToDoItem</code> call in <code>App.vue</code>. Note that you need to use the <code>v-bind</code> syntax, because otherwise <code>true</code> is passed as a string. The displayed checkbox should be checked.</p>
+
+<pre class="brush: js">&lt;template&gt;
+ &lt;div id="app"&gt;
+ &lt;h1&gt;My To-Do List&lt;/h1&gt;
+ &lt;ul&gt;
+ &lt;li&gt;
+ &lt;to-do-item label="My ToDo Item" :done="true"&gt;&lt;/to-do-item&gt;
+ &lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/div&gt;
+&lt;/template&gt;
+</pre>
+
+<p>Try changing <code>true</code> to <code>false</code> and back again, reloading your app in between to see how the state changes.</p>
+
+<h2 id="Giving_Todos_a_unique_id">Giving Todos a unique id</h2>
+
+<p>Great! We now have a working checkbox where we can set the state programmatically. However, we can currently only add one <code>ToDoList</code> component to the page because the <code>id</code> is hardcoded. This would result in errors with assistive technology since the <code>id</code> is needed to correctly map labels to their checkboxes. To fix this, we can programmatically set the <code>id</code> in the component data.</p>
+
+<p>We can use the <a href="https://www.npmjs.com/package/lodash">lodash</a> package's <code>uniqueid()</code> method to help keep the index unique. This package exports a function that takes in a string and appends a unique integer to the end of the prefix. This will be sufficient for keeping component <code>id</code>s unique.</p>
+
+<p>Let’s add the package to our project with npm; stop your server and enter the following command into your terminal:</p>
+
+<pre class="brush: bash">npm install --save lodash.uniqueid</pre>
+
+<div class="notecard note">
+<p><strong>Note</strong>: If you prefer yarn, you could instead use <code>yarn add lodash.uniqueid</code>.</p>
+</div>
+
+<p>We can now import this package into our <code>ToDoItem</code> component. Add the following line at the top of <code>ToDoItem.vue</code>’s <code>&lt;script&gt;</code> element:</p>
+
+<pre class="brush: js">import uniqueId from 'lodash.uniqueid';</pre>
+
+<p>Next, add an <code>id</code> field to our data property, so the component object ends up looking like so (<code>uniqueId()</code> returns the specified prefix — <code>todo-</code> — with a unique string appended to it):</p>
+
+<pre class="brush: js">import uniqueId from 'lodash.uniqueid';
+
+export default {
+ props: {
+ label: { required: true, type: String },
+ done: { default: false, type: Boolean }
+ },
+ data() {
+ return {
+ isDone: this.done,
+ id: uniqueId('todo-')
+ };
+ }
+};</pre>
+
+<p>Next, bind the <code>id</code> to both our checkbox’s <code>id</code> attribute and the label’s <code>for</code> attribute, updating the existing <code>id</code> and <code>for</code> attributes as shown:</p>
+
+<pre class="brush: js">&lt;template&gt;
+ &lt;div&gt;
+ &lt;input type="checkbox" :id="id" :checked="isDone" /&gt;
+ &lt;label :for="id"&gt;\{{label}}&lt;/label&gt;
+ &lt;/div&gt;
+&lt;/template&gt;</pre>
+
+<h2 id="Summary">Summary</h2>
+
+<p>And that will do for this article. At this point we have a nicely-working <code>ToDoItem</code> component that can be passed a label to display, will store its checked state, and will be rendered with a unique <code>id</code> each time it is called. You can check if the unique <code>id</code>s are working by temporarily adding more <code>&lt;to-do-item&gt;&lt;/to-do-item&gt;</code> calls into <code>App.vue</code>, and then checking their rendered output with your browser's DevTools.</p>
+
+<p><span class="author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qoxwoxz78zz83zz84zz69z2z80zgwxsgnz83zfkt5e5tz70zz68zmsnjz122zz71z">Now we're ready to add multiple <code>ToDoItem</code> components to our App. In our next article we'll look at adding a set of todo item data to our <code>App.vue</code> component, which we'll then loop through and display inside <code>ToDoItem</code> components using the <code>v-for</code> directive.   </span></p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</p>
+
+<h2 id="In_this_module">在本模組</h2>
+
+<ul>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">前端框架介紹</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">框架主要功能</a></li>
+ <li>React
+ <ul>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">React 入門</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">建立我們的 React 待辦清單</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">元件化我們的 React 應用程式</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">React 互動性:事件與狀態</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">React 互動性:編輯、過濾、條件式渲染</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">React 無障礙</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">React 資源</a></li>
+ </ul>
+ </li>
+ <li>Ember
+ <ul>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Ember 入門</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">Ember 應用程式結構及元件化</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">Ember 互動性:事件、類別、狀態</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">Ember 互動性: Footer 功能、條件式渲染</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">Ember 路由</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">Ember 資源及偵錯</a></li>
+ </ul>
+ </li>
+ <li>Vue
+ <ul>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Vue 入門</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">建立第一個 Vue 元件</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">渲染 Vue 清單</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">新增待辦表單: Vue 事件、方法、模型</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">透過 CSS 樣式化 Vue 元件</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">使用 Vue 計算屬性</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">Vue 條件式渲染:編輯已存在的待辦表單</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">聚焦 Vue refs</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">Vue 資源</a></li>
+ </ul>
+ </li>
+ <li>Svelte
+ <ul>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_getting_started">Svelte 入門</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_Todo_list_beginning">開始寫我們的 Svelte 待辦清單應用程式</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_variables_props">Svelte 中的動態行為:變數及屬性</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_components">元件化我們的 Svelte 應用程式</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility">進階 Svelte :反應性、生命週期、可存取性</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_stores">和 Svelte stores 共舞</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript">Svelte 中的 TypeScript</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_deployment_next">部署和下一步</a></li>
+ </ul>
+ </li>
+ <li>Angular
+ <ul>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_getting_started">Angular 入門</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_todo_list_beginning">開始我們的 Angular 待辦清單應用程式</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_styling">樣式化我們的 Angular 應用程式</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_item_component">Creating an item component 建立(待辦清單)項目元件</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_filtering">過濾我們的待辦項目</a></li>
+ <li><a href="/zh-TW/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Angular_building">建置 Angular 應用程式及更多資源</a></li>
+ </ul>
+ </li>
+ </ul>
diff --git a/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_first_component/rendered-todoitem.png b/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_first_component/rendered-todoitem.png
new file mode 100644
index 0000000000..63ac84a7eb
--- /dev/null
+++ b/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_first_component/rendered-todoitem.png
Binary files differ
diff --git a/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_getting_started/index.html b/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_getting_started/index.html
index e534abf22e..4ee8bc3864 100644
--- a/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_getting_started/index.html
+++ b/files/zh-tw/learn/tools_and_testing/client-side_javascript_frameworks/vue_getting_started/index.html
@@ -23,7 +23,7 @@ tags:
<td>
<p>熟悉 <a href="/zh-TW/docs/Learn/HTML">HTML</a> 、 <a href="/zh-TW/docs/Learn/CSS">CSS</a> 、以及 <a href="/zh-TW/docs/Learn/JavaScript">JavaScript</a> 的核心知識,知道如何使用<a href="/zh-TW/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">終端機/命令列工具( terminal/command line )</a>。</p>
- <p>Vue 元件是由 Javascript 物件(用來管理應用的資料)及樣本語法(用來映射成 DOM 結構)所組成的。另外,你將需要使用終端機安裝 node 和 npm ,以便下載及使用一些 Vue 的進階功能(像是單一檔案的元件或是渲染函式)</p>
+ <p>Vue 元件是由 Javascript 物件(用來管理應用程式的資料)及樣版語法(用來映射成 DOM 結構)所組成的。此外,你將需要使用終端機安裝 node 和 npm ,以便下載及使用一些 Vue 的進階功能(像是單一檔案的元件或是渲染函式)。</p>
</td>
</tr>
<tr>