Vue 的官方文檔 對 Vue 介紹很是詳細,但官方文檔使用在 HTML 中引入 vue 的方式進行講解,而實際項目中通常使用腳手架如 vue-cli 初始化項目。以致於剛看完文檔時,卻依舊不能當即當即 vue-cli 建立的項目代碼。因此本文 vue-cli 構建的項目爲基礎,詳細解釋其代碼及對應的概念,並進行簡單的實踐。html
本文的代碼在 https://github.com/nodejh/vue2-tutorials/tree/master/01.QuickStartvue
首先要全局安裝 vue-cl:node
$ npm install --global vue-cli
而後使用 vue-cli 初始化一個基於 webpack 模板的新項目,除了 Install vue-router?
選 N (No)
,其他均可以直接回車選 Y (Yes)
,由於咱們暫時不會講到 vue-router
:webpack
$ 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
是項目的入口文件,也是 webpack 打包的入口文件。裏面最代碼不多,主要就是經過 new Vue()
建立 Vue 實例:
new Vue({ el: '#app', template: '<App/>', components: { App }, });
每一個 Vue.js 應用都是經過構造函數 Vue 建立一個 Vue 的根實例啓動的。
在實例化 Vue 時,傳入一個了一個對象,對象包含如下幾個選項。
el
的值是 Vue 實例的掛載目標,這裏是 #app
,也就是 demo/index.html
中 id="app"
這個元素:
<div id="app"></div>
el
必須是一個已存在的元素。
在說 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
就是掛載到頁面的模板。
這裏的值是 <App/>
組件就是 components
屬性中的 App
,也就是經過 import
引入的 App
這個模板。
new Vue({ el: '#app', // 這裏的 <App/> 就是 components 屬性的值 App template: '<App/>', components: { App }, });
因此這段代碼的含義就是,將 <App/>
這個模板掛載到元素 #app
上。
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/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 ,須要使用 v-html
指令:
<div v-html="rawHtml"></div>
這個 div 的內容將會被替換成爲屬性值 rawHtml,直接做爲 HTML —— 數據綁定會被忽略。注意,你不能使用 v-html 來複合局部模板,由於 Vue 不是基於字符串的模板引擎。組件更適合擔任 UI 重用與複合的基本單元。
你的站點上動態渲染的任意 HTML 可能會很是危險,由於它很容易致使 XSS 攻擊。請只對可信內容使用 HTML 插值,毫不要對用戶提供的內容插值。
{{}}
中也能夠寫 JS 表達式:
{{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <div v-bind:id="'list-' + id"></div>
指令(Directives)是帶有 v-
前綴的特殊屬性。
{{}}
不能在 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
用來監聽 DOM 事件:
<button v-on:click="doSomething"></button>
也能夠縮寫成下面這樣:
<button @click="doSomething"></button>
<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
指令能夠綁定數組的數據來渲染一個項目列表:
<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 的官方文檔,這個時候再去看官方文檔,應該就會輕鬆不少了。