快速入門 - Vue2 Tutorials (一)

Vue 的官方文檔 對 Vue 介紹很是詳細,但官方文檔使用在 HTML 中引入 vue 的方式進行講解,而實際項目中通常使用腳手架如 vue-cli 初始化項目。以致於剛看完文檔時,卻依舊不能當即當即 vue-cli 建立的項目代碼。因此本文 vue-cli 構建的項目爲基礎,詳細解釋其代碼及對應的概念,並進行簡單的實踐。html

本文的代碼在 https://github.com/nodejh/vue2-tutorials/tree/master/01.QuickStartvue

命令行工具

安裝 vue-cli 並初始化項目

首先要全局安裝 vue-cl:node

$ npm install --global vue-cli

而後使用 vue-cli 初始化一個基於 webpack 模板的新項目,除了 Install vue-router?N (No),其他均可以直接回車選 Y (Yes),由於咱們暫時不會講到 vue-routerwebpack

$ vue init webpack demo
? Project name demo
? Project description A Vue.js project

? Author nodejh <jianghangscu@gmail.com>
? Vue build standalone
? Install vue-router? No
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Setup unit tests with Karma + Mocha? Yes
? Setup e2e tests with Nightwatch? Yes

安裝依賴

$ cd demo
$ npm install
$ npm run dev

而後打開瀏覽器,輸入 http://localhost:8080 就能看到界面。git

接下來分析一下代碼。github

代碼分析

項目目錄結構以下:web

├── README.md
├── build    # 編譯項目的配置文件目錄
├── config    # 配置文件目錄
├── src    # 項目主要代碼目錄
├── static    # 靜態資源
├── test    # 測試文件目錄

開發階段的主要代碼都在 src 目錄中編寫,vue-cli 默認生成了一些代碼:vue-router

src
├── App.vue
├── assets
│   └── logo.png
├── components
│   └── Hello.vue
└── main.js

能夠發現,代碼的後綴名有兩種:vuex

  • .js JS 文件vue-cli

  • .vue Vue 組件,裏面定義了 Vue 實例、模板、樣式等。須要由 webpack 等工具來轉換爲 js 代碼

接下來會逐一解釋這些文件及代碼。

main.js

main.js 是項目的入口文件,也是 webpack 打包的入口文件。裏面最代碼不多,主要就是經過 new Vue() 建立 Vue 實例:

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
});

每一個 Vue.js 應用都是經過構造函數 Vue 建立一個 Vue 的根實例啓動的。

在實例化 Vue 時,傳入一個了一個對象,對象包含如下幾個選項。

el

el 的值是 Vue 實例的掛載目標,這裏是 #app,也就是 demo/index.htmlid="app" 這個元素:

<div id="app"></div>

el 必須是一個已存在的元素。

api/#el

components

在說 template 以前,先來看看 components 屬性。

components: { App } 等價於 components: { App: App },是一個包含了對 Vue 實例可見的組件的哈希表。只有在 components 裏面列出來的組件,才能夠在 template 裏面使用。

若是咱們把 components: { App } 改成 components: { App } 改成 components: { MyApp: App },那麼在 template 裏面就須要這樣使用:template: '<my-app />'

因爲 HTML 標籤不區分大小寫,因此 components 裏面的駝峯命名會自動轉換爲短橫線。詳見 camelCase vs. kebab-case

template

template 就是掛載到頁面的模板。

這裏的值是 <App/> 組件就是 components 屬性中的 App,也就是經過 import 引入的 App 這個模板。

new Vue({
  el: '#app',
  // 這裏的 <App/> 就是 components 屬性的值 App
  template: '<App/>',
  components: { App },
});

因此這段代碼的含義就是,將 <App/> 這個模板掛載到元素 #app 上。

src/App.vue

src/App.vue 是一個典型的單文件組件。實際在項目中,咱們寫的基本都是組件,再根據須要用組件組成頁面,這其實就是組件化。組件與組件之間相互獨立,項目結構更加清晰,也更有利於維護。

一個組件裏面封裝了 HTML、CSS 和 JS,有本身獨立的樣式和邏輯。

<template> 就是組件中的模板,模板的代碼都在 <template> 標籤中,除 <hello> 以外都是普通的 HTML。由於 hello 也是一個組件,而後經過標籤的形式注入到模板中。

爲何模板中能使用 hello 這個組件呢?

這是由於 <script></script> 標籤裏面定義了 Hello(首字母大寫)這個組件:

import Hello from './components/Hello'

export default {
  name: 'app',
  components: {
    // Hello 組件,即 ./components/Hello 的一個引用
    Hello  
  }
}

這裏 components 屬性的含義,在以前已經提到過了,只有在 components 裏面列出來的組件,才能被模板使用。這裏列出了 Hello 這個組件,因此在 <template> 中咱們可使用 <hello>(前面也提到過, vue 會自動將駝峯法命名轉爲短橫線)。

components 屬性裏面的 Hello,則是 ./components/Hello 這個組件的一個引用:

import Hello from './components/Hello'

最後就是 <style> 標籤,裏面就是普通的 CSS 了。

src/components/Hello.vue

最後再來看看 src/components/Hello.vue 這個組件的代碼。

基本跟 src/App.vue 是同樣的,除了下面這兩個地方以外:

<h1>{{ msg }}</h1>
data () {
  return {
    msg: 'Welcome to Your Vue.js App'
  }
}

恭喜你!看到這裏,咱們就能夠真正開始寫代碼了。

{{}} 是 Vue 的一個模板語法,文本插值。如上面的例子所示,咱們在 data 裏面定義一個對象,就能夠在模板中經過 {{ }} 來訪問。

data 雖然是一個函數,但它執行以後就等價於:

data: {
  msg: 'Welcome to Your Vue.js App'
}

當咱們改變 msg 的值,在頁面上渲染出來的數據也會改變。也就是數據和 DOM 綁定在了一塊兒。

模板語法

插值

文本插值

上面咱們已經接觸到了文本插值 {{}}{{ msg }} 將會被替代爲對應數據對象上 msg 屬性的值。不管什麼時候,綁定的數據對象(即 data)上 msg 屬性發生了改變,插值處的內容都會更新。

經過使用 v-once 指令,咱們也能執行一次性地插值,當數據改變時,插值處的內容不會更新。但請留心這會影響到該節點上全部的數據綁定:

<h1 v-once>This will never change: {{ msg }}</h1>

純 HTML

雙大括號會將數據解釋爲純文本,而非 HTML 。爲了輸出真正的 HTML ,須要使用 v-html 指令:

<div v-html="rawHtml"></div>

這個 div 的內容將會被替換成爲屬性值 rawHtml,直接做爲 HTML —— 數據綁定會被忽略。注意,你不能使用 v-html 來複合局部模板,由於 Vue 不是基於字符串的模板引擎。組件更適合擔任 UI 重用與複合的基本單元。

你的站點上動態渲染的任意 HTML 可能會很是危險,由於它很容易致使 XSS 攻擊。請只對可信內容使用 HTML 插值,毫不要對用戶提供的內容插值。

JS 表達式

{{}} 中也能夠寫 JS 表達式:

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>

指令

指令(Directives)是帶有 v- 前綴的特殊屬性。

v-bind

{{}} 不能在 HTML 屬性中使用。針對 HTML 屬性須要使用 v-bind

<div v-bind:id="dynamicId"></div>

這對布爾值的屬性也有效 —— 若是條件被求值爲 false 的話該屬性會被移除:

<button v-bind:disabled="isButtonDisabled">Button</button>

v-bind 也能夠縮寫:

<div :id="dynamicId"></div>
<button :disabled="isButtonDisabled">Button</button>

v-on

v-on 用來監聽 DOM 事件:

<button v-on:click="doSomething"></button>

也能夠縮寫成下面這樣:

<button @click="doSomething"></button>

v-if

<template>
  <p v-if="seen">Now you see me</p>
</template>

<script>
export default {
  name: 'hello',
  data: {
    seen: true
  }
}
</script>

這裏 v-if 指令將根據表達式 seen 的值的真假來移除/插入 <p> 元素。

v-for

v-for 指令能夠綁定數組的數據來渲染一個項目列表:

<template>
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</template>

<script>
  export default {
    data: {
      todos: [
        { text: '學習 JavaScript' },
        { text: '學習 Vue' },
        { text: '整個牛項目' }
      ]
    }
  }
</script>

實踐

讓咱們把目光回到 Hello.vue。在這個組件裏面有一些連接列表, Essential Links 和 Ecosystem,這些列表直接使用 HTML 編寫:

<ul>
  <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
  <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
  <li><a href="https://gitter.im/vuejs/vue" target="_blank">Gitter Chat</a></li>
  <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
  <br>
  <li><a href="http://vuejs-templates.github.io/webpack/" target="_blank">Docs for This Template</a></li>
</ul>
<h2>Ecosystem</h2>
<ul>
  <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
  <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
  <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
  <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
</ul>

按照傳統的寫法,若是咱們須要往裏面添加連接的時候,每次咱們都得添加 <li><a> 標籤。思考兩個問題:

  • 添加幾個連接還好,若是要添加很是很是多呢?難到要複製幾十次 <li><a> 標籤?

  • 若是要動態改變連接列表呢?難道要使用 innerHTML 等方法修改 DOM?

聰明的你可能已經想到了,很明顯不須要這麼作,咱們可使用模板語法。將連接信息寫到 Vue 的數據對象 data 裏面,而後經過動態綁定的方式,將數據綁定到 DOM。

因此修改以下:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li v-for="essentialLink in essentialLinks">
        <a :href="essentialLink.link" target="_blank">{{ essentialLink.text }}</a>
      </li>
      <br>
      <li><a href="http://vuejs-templates.github.io/webpack/" target="_blank">Docs for This Template</a></li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li v-for="ecosystem in ecosystems">
        <a :href="ecosystem.link" target="_blank">{{ ecosystem.text }}</a>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      ecosystems: [
        {
          link: 'http://router.vuejs.org/',
          text: 'vue-router'
        },
        {
          link: 'http://vuex.vuejs.org/',
          text: 'vuex'
        },
        {
          link: 'http://vue-loader.vuejs.org/',
          text: 'vue-loader'
        },
        {
          link: 'https://github.com/vuejs/awesome-vue',
          text: 'awesome-vue'
        }
      ],
      essentialLinks: [
        {
          link: 'https://vuejs.org',
          text: 'Core Docs'
        },
        {
          link: 'https://forum.vuejs.org',
          text: 'Forum'
        },
        {
          link: 'https://gitter.im/vuejs/vue',
          text: 'Gitter Chat'
        },
        {
          link: 'https://github.com/vuejs/awesome-vue',
          text: 'awesome-vue'
        },
        {
          link: 'https://twitter.com/vuejs',
          text: 'Twitter'
        }
      ]
    }
  }
}
</script>

這樣咱們就把數據和視圖分開了,模板裏面的代碼也簡潔了不少,再也不須要寫不少重複的代碼。而且根據不一樣數據,咱們也能展現出不一樣的 UI。

總結

本文詳細講解了 vue-cli 初始化的項目代碼,而且在講解代碼的過程當中,介紹了構造 vue 對象的一些參數,以及 vue 的一些基本概念,好比模板語法中的插值和指令。最後經過修改代碼對以上知識點進行實踐。

相信看到了這裏,你對如何使用 vue 寫一個項目已經有了初步瞭解。固然,看完本文,可能還有不少概念理解不清楚,這時推薦去看一下 vue 的官方文檔,這個時候再去看官方文檔,應該就會輕鬆不少了。


https://github.com/nodejh/nodejh.github.io/issues/38

相關文章
相關標籤/搜索