Vue.js是什么
Vue.js(讀音 /vju?/, 類(lèi)似于 view) 是一套構(gòu)建用戶(hù)界面的 漸進(jìn)式框架。與其他重量級(jí)框架不同的是,Vue 采用自底向上增量開(kāi)發(fā)的設(shè)計(jì)。
Vue 的核心庫(kù)只關(guān)注視圖層,并且非常容易學(xué)習(xí),非常容易與其它庫(kù)或已有項(xiàng)目整合。另一方面,Vue 完全有能力驅(qū)動(dòng)采用單文件組件和Vue生態(tài)系統(tǒng)支持的庫(kù)開(kāi)發(fā)的復(fù)雜單頁(yè)應(yīng)用。
Vue.js 的目標(biāo)是通過(guò)盡可能簡(jiǎn)單的 API 實(shí)現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件。
Vue.js安裝
1、獨(dú)立版本
我們可以在 Vue.js 的官網(wǎng)上直接下載 vue.min.js 并用 <script> 標(biāo)簽引入。
下載地址: https://vuejs.org/js/vue.min.js
2、使用CDN方法
以下推薦國(guó)外比較穩(wěn)定的兩個(gè) CDN,國(guó)內(nèi)還沒(méi)發(fā)現(xiàn)哪一家比較好,目前還是建議下載到本地。
- BootCDN(國(guó)內(nèi)) : https://cdn.bootcss.com/vue/2.2.2/vue.min.js
- unpkg:https://unpkg.com/vue/dist/vue.js, 會(huì)保持和 npm 發(fā)布的最新的版本一致。
- cdnjs : https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.min.js
(1)在桌面建立一個(gè) Vue.html文件, 并添加HTML頁(yè)面的架構(gòu),然后引入 vue.js的CDN地址
<script src="https://unpkg.com/vue/dist/vue.js"></script>
(2)在Vue.html文件中插入一個(gè)id為firstVue的div標(biāo)簽
<div id="firstVue"></div>
(3)在Vue.html文件中插入如下js代碼
<script>
new Vue({
el: "#firstVue",
})
</script>
完整代碼如下:
<!DOCTYPE html>
<html>
<head>
<title>Vue Demo</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="firstVue"></div>
<body>
<script>
new Vue({
el: "#firstVue",
})
</script>
</html>
new Vue({})就是Vue創(chuàng)建的一個(gè)對(duì)象,可以理解成把<div id="firstVue></div>
和這個(gè)標(biāo)簽里面包含的所有DOM都實(shí)例化成了一個(gè)JS對(duì)象 。
el是Vue的保留字,用來(lái)指定實(shí)例化的DOM的id號(hào), #firstVue這句話就是id選擇器,告訴Vue要實(shí)例化id="firstVue"
的這個(gè)標(biāo)簽。
(4)在創(chuàng)建 vue實(shí)例的代碼中加入下面數(shù)據(jù)聲明:
data: {
my_data: "hello world"
}
(5)在標(biāo)簽中通過(guò){{}}來(lái)引用變量值:
<div id="firstVue">{{my_data}}</div>
雙大括號(hào)的語(yǔ)法叫做mustache 語(yǔ)法,大括號(hào)里面的是作為變量形式出現(xiàn)的。
完整代碼如下:
<!DOCTYPE html>
<html>
<head>
<title>Vue Demo</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="firstVue">{{my_data}}</div>
<body>
<script>
new Vue({
el: "#firstVue",
data: {
my_data: "hello world"
}
})
</script>
</html>
data參數(shù)用來(lái)綁定VUE實(shí)例的數(shù)據(jù)變量,每個(gè)不同變量之間用逗號(hào)分隔,上面我們綁定了自定義變量my_data
,并賦初值"hello world"。
完成數(shù)據(jù)綁定工作,<div>
標(biāo)簽里的 {{myData}} 數(shù)據(jù)會(huì)隨著myVue實(shí)例里的my_Data
數(shù)據(jù)的變動(dòng)而變動(dòng),瀏覽器查看當(dāng)前頁(yè)面,會(huì)出現(xiàn)"hello world"字符串,說(shuō)明數(shù)據(jù)綁定成功。
VUE這個(gè)框架的數(shù)據(jù)流向是單向的,數(shù)據(jù)綁定后的數(shù)據(jù)流向是從vue實(shí)例——>DOM文檔。
3、NPM方法
(1)國(guó)內(nèi)使用npm速度較慢,使用淘寶定制的cnpm(gzip壓縮支持)命令行工具代替默認(rèn)的npm:
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
$ npm config set registry https://registry.npm.taobao.org
(2)npm 版本需要大于 3.0,如果低于此版本需要升級(jí)它:
# 查看版本
$ npm -v
5.6.0
#升級(jí) npm
$ cnpm install npm -g
(3)在用 Vue.js 構(gòu)建大型應(yīng)用時(shí)推薦使用 NPM 安裝:
# 最新穩(wěn)定版
$ cnpm install vue
(4)創(chuàng)建項(xiàng)目并安裝運(yùn)行
Vue.js 提供一個(gè)官方命令行工具,可用于快速搭建大型單頁(yè)應(yīng)用。
# 全局安裝 vue-cli
$ cnpm install --global vue-cli
# 創(chuàng)建一個(gè)基于 webpack 模板的新項(xiàng)目
$ vue init webpack my-project
# 這里需要進(jìn)行一些配置,默認(rèn)回車(chē)即可
? Project name my-project
? Project description A Vue.js project
? Author thd
? Vue build (Use arrow keys)
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner jest
? Setup e2e tests with Nightwatch? Yes
vue-cli · Generated "my-project".
To get started:
cd my-project
npm run dev
#進(jìn)入項(xiàng)目,安裝并運(yùn)行
$ cd my-project
$ cnpm run dev
成功執(zhí)行以上命令后訪問(wèn) http://localhost:8080/,輸出結(jié)果如下所示:
Vue.js 目錄結(jié)構(gòu)
1、項(xiàng)目目錄
- build:項(xiàng)目構(gòu)建(webpack)相關(guān)代碼 ,用來(lái)保存文本pack的初始化配置。
- config:配置目錄,保存項(xiàng)目初始化配置,包括端口號(hào)等。我們初學(xué)可以使用默認(rèn)的 。
- node_modules:npm 加載的項(xiàng)目依賴(lài)模塊
-
src: 這里是我們要開(kāi)發(fā)的目錄,基本上要做的事情都在這個(gè)目錄里。
- assets:放置一些圖片,如logo等。
- components:放置組件文件,可以不用。
- router:前端路由配置
- App.vue:項(xiàng)目入口文件,可以直接將組件寫(xiě)這里,而不使用 components 目錄。
- main.js:項(xiàng)目的核心文件。
- static:靜態(tài)資源目錄,如圖片、字體等。
- test: 初始測(cè)試目錄,可刪除
- index.html:首頁(yè)入口文件,可以添加一些 meta 之類(lèi)的信息。
- package.json:項(xiàng)目配置文件
- README.md:項(xiàng)目的說(shuō)明文檔,Markdown格式。
2、相關(guān)文件
(1)index.html
項(xiàng)目的入口頁(yè)面,可以像普通的html文件一樣引入文件和書(shū)寫(xiě)基本信息,添加meta標(biāo)簽等。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>my-project</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
(2)main.js
項(xiàng)目的入口文件,可以引入一些插件或靜態(tài)資源,當(dāng)然引入之前要先安裝了該插件,在package.json文件中有記錄。
import Vue from 'vue'
import App from './App'
import router from './router'
//設(shè)置為 false 表示阻止啟動(dòng)生產(chǎn)消息,常用作指令。
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
/*
el: '#app' ---表示將所有的組件都放在id為app的元素中
router---配置路由,路由允許我們通過(guò)不同的 URL 訪問(wèn)不同的內(nèi)容
components: { App }---表示引入的文件,此處就是App.vue這個(gè)文件,也就是組件
template: '<App/>'---模板將會(huì)替換掛載的元素。掛載元素的內(nèi)容都將被忽略,template的值表示要使用的組件名稱(chēng),并將這個(gè)組件顯示在html頁(yè)面中,在組件中通過(guò)export default中的name來(lái)聲明組件名稱(chēng)
*/
(3)App.vue
這是一個(gè)標(biāo)準(zhǔn)的vue組件,包含三個(gè)部分,一個(gè)是模板,一個(gè)是script,一個(gè)是樣式。
<!-- 模板 -->
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view/>
</div>
</template>
<!-- script -->
<script>
export default {
name: 'App'
}
</script>
<!-- style -->
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
(4)修改第一個(gè)項(xiàng)目中顯示的內(nèi)容
- 在components目錄下定義一個(gè)Hello.vue組件文件,代碼如下:
<template>
<div>
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'hello',
data () {
return {
msg: '歡迎來(lái)到Vue'
}
}
}
</script>
- 打開(kāi) APP.vue 文件,在模板template中添加一個(gè)Vue組件,并在script中將該組件導(dǎo)入,如下:
<template>
<div id="app">
<img src="./assets/logo.png">
<!--添加的Vue組件-->
<hello></hello>
</div>
</template>
<script>
// 導(dǎo)入組件
import Hello from './components/Hello'
export default {
name: 'App',
components: {
Hello
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
啟動(dòng)項(xiàng)目,重新打開(kāi) http://localhost:8080/ ,顯示效果如下:
Vue.js 構(gòu)造器
每個(gè) Vue 應(yīng)用都需要通過(guò)實(shí)例化 Vue 來(lái)實(shí)現(xiàn)(創(chuàng)建Vue對(duì)象 new Vue({ })),而實(shí)例化時(shí)就要使用構(gòu)造器。構(gòu)造器格式如下:
var vm = new Vue({
// 選項(xiàng)
})
構(gòu)造器中可以有以下選項(xiàng):
- el:用來(lái)表示DOM元素的id
- data:用于定義屬性
- methods:用于定義函數(shù),可以通過(guò)return來(lái)返回函數(shù)值
在DOM元素中可以使用 {{ }} 來(lái)輸出對(duì)象屬性和函數(shù)返回值
示例:
<!DOCTYPE html>
<html>
<head>
<title>Vue Demo</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="myDiv">
<h2>site: {{site}}</h2>
<h2>url: {{url}}</h2>
<h2>{{details()}}</h2>
</div>
<body>
<script>
new Vue({
el: "#myDiv",
data: {
site: "百度一下,你就知道",
url: "http://www.baidu.com",
desc: "全球最大的中文搜索引擎、致力于讓網(wǎng)民更便捷地獲取信息,找到所求。百度超過(guò)千億的中文網(wǎng)頁(yè)數(shù)據(jù)庫(kù),可以瞬間找到相關(guān)的搜索結(jié)果。"
},
methods: {
details: function() {
return this.site + "--" + this.desc;
}
}
})
</script>
</html>
Vue.js 模板語(yǔ)法
Vue.js 使用了基于 HTML 的模版語(yǔ)法,允許開(kāi)發(fā)者聲明式地將 DOM 綁定至底層 Vue 實(shí)例的數(shù)據(jù)。
Vue.js 的核心是一個(gè)允許你采用簡(jiǎn)潔的模板語(yǔ)法來(lái)聲明式的將數(shù)據(jù)渲染進(jìn) DOM 的系統(tǒng)。
結(jié)合響應(yīng)系統(tǒng),在應(yīng)用狀態(tài)改變時(shí), Vue 能夠智能地計(jì)算出重新渲染組件的最小代價(jià)并應(yīng)用到 DOM 操作上。
1、插值
(1)文本
文本通常是作為數(shù)據(jù)綁定的值,數(shù)據(jù)綁定采用{{ }}
- 文本插值
<div id="app">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: '數(shù)據(jù)'
}
})
</script>
- v-html指令:讀取HTML標(biāo)簽
<div id="app">
<div v-html="message"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
message: '<h1>我的青春我做主</h1>'
}
})
</script>
(2)屬性
HTML 屬性中的值應(yīng)使用 v-bind 指令,該指令用于雙向數(shù)據(jù)綁定。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 屬性</title>
<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
修改顏色:<input type="checkbox" v-model="change"><br><br>
<div v-bind:class="{'newClass': change}">v-bind:class</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data:{
change: false //false表示沒(méi)有勾選,true表示勾選上
}
});
</script>
<style>
.newClass{
background: #444;
color: #eee;
}
</style>
</html>
(3)表達(dá)式
Vue.js 都提供了完全的 JavaScript 表達(dá)式支持。
<div id="app">
{{5+5}}<br>
{{ ok ? 'YES' : 'NO' }}<br>
{{ message.split('').reverse().join('') }}
</div>
<script>
new Vue({
el: '#app',
data: {
ok: true,
message: 'HELLO',
}
})
</script>
2、指令
指令是帶有 v- 前綴的特殊屬性。 指令用于在表達(dá)式的值改變時(shí),將某些行為應(yīng)用到 DOM 上 。
(1)v-if
條件渲染指令,根據(jù)其后表達(dá)式的bool值進(jìn)行判斷是否渲染該元素。v-if指令只渲染其后表達(dá)式值為true的元素 。
<div id="app">
<p v-if='seen'>看到我了</p>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
seen: true
}
})
</script>
(2)v-show
v-show指令是根據(jù)表達(dá)式的值來(lái)顯示或者隱藏HTML元素。當(dāng)v-show賦值為false時(shí),元素被隱藏。
<div id="app">
<p v-show='seen'>看到我了</p>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
seen: true
}
})
</script>
注意:注:v-show不支持<template>語(yǔ)法。
一般來(lái)說(shuō),v-if有更高的切換消耗,而v-show有更高的初始渲染消耗。因此,如果需要頻繁的切換,則使用v-show較好;如果在運(yùn)行時(shí)條件不大可能改變,則使用v-if較好。
(3)v-else
v-else就是JavaScript中的else的意思,它必須跟著v-if或者v-show使用。
<div id="app">
<P v-if="ok">我是對(duì)的</P>
<p v-else="ok">我是錯(cuò)的</p>
</div>
<script type="text/javascript">
var exampleVM2 = new Vue({
el: '#app',
data: {
ok: false
}
})
</script>
(4)v-else-if
v-else-if 在 2.1.0 新增,顧名思義,用作 v-if 的 else-if 塊,可以鏈?zhǔn)降亩啻问褂?/p>
<div id="app">
<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>
</div>
<script>
new Vue({
el: '#app',
data: {
type: 'C'
}
})
</script>
(5)v-bind
v-bind指令用于響應(yīng)更新HTML特性,將一個(gè)或者多個(gè)attribute,或者一個(gè)組件prop動(dòng)態(tài)綁定到表達(dá)式
<div id="app">
<a v-bind:href="url">百度一下</a>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
url: 'https://www.baidu.com'
}
})
</script>
- v-bind縮寫(xiě)
<!-- 完整語(yǔ)法 -->
<a v-bind:href="url"></a>
<!-- 縮寫(xiě) -->
<a :href="url"></a>
- 給元素綁定href時(shí)可以也綁一個(gè)target,新窗口打開(kāi)頁(yè)面。
<script>
new Vue({
el: '#app',
data: {
url: 'http://www.runoob.com',
target:'_blank'
}
})
</script>
- 在綁定class或者style時(shí),支持其他類(lèi)型的值,如數(shù)組或?qū)ο蟆?/li>
<div id="app">
<div v-bind:class="[classA,{classB:isB,classC:isC}]">hahaha</div>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
classA: 'A',
isB: false,
isC: true
}
})
</script>
<style type="text/css">
.A {
color: red;
}
.classC {
font-size: 50px;
}
</style>
(6)v-model
v-model指令用來(lái)在input、select、text、checkbox、radio等表單控件元素上創(chuàng)建雙向數(shù)據(jù)綁定的。根據(jù)控件類(lèi)型v-model自動(dòng)選取正確的方法更新元素 。
<div id="app">
<input type="text" v-model='msg' />
<p>{{msg}}</p>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
msg: 'hello'
}
})
</script>
(7)v-on
v-on指令用于綁定事件監(jiān)聽(tīng)器。事件類(lèi)型由參數(shù)指定。
<div id="app">
<button v-on:click='reverse'>點(diǎn)擊按鈕</button><br />
<p>{{msg}}</p>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
msg: 'hello'
},
methods: {
reverse: function() {
this.msg = this.msg.split('').reverse().join('')
}
}
})
</script>
- v-on縮寫(xiě)
<!-- 完整語(yǔ)法 -->
<a v-on:click="doSomething"></a>
<!-- 縮寫(xiě) -->
<a @click="doSomething"></a>
(8)v-for
v-for指令用于循環(huán)遍歷顯示一個(gè)數(shù)組或者對(duì)象 。用法形如 v-for="item in items", items為數(shù)組或?qū)ο?/strong>,item為數(shù)組中的每一項(xiàng)元素。
- v-for遍歷整數(shù)
<div id="app">
<ul>
<li v-for="n in 10">
{{ n }}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app'
})
</script>
- v-for遍歷數(shù)組
<div id="app">
<ol>
<li v-for='site in sites'>
{{site.name}}
</li>
</ol>
</div>
<script>
new Vue({
el: '#app',
data: {
sites: [
{name: 'baidu'},
{name: 'sina'},
{name: 'qq'}
]
}
})
</script>
/*注意:數(shù)組也可以定義在v-for的屬性值中*/
<ul>
<li v-for='n in [1,3,5,7]'>
{{ n }}
</li>
</ul>
- v-for遍歷數(shù)組帶索引
<div>
<ul>
<li v-for='(site, index) in sites'>
{{index}} : {{site.name}}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
sites: [
{name: 'baidu'},
{name: 'sina'},
{name: 'qq'}
]
}
})
</script>
- v-for遍歷對(duì)象
<div id='#app'>
<ul>
<li v-for='value in website'>
{{value}}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
website: {
name: '百度一下',
url: 'http://www.baidu.com',
desc: '全球最大的中文搜索引擎、致力于讓網(wǎng)民更便捷地獲取信息,找到所求。百度超過(guò)千億的 中文網(wǎng)頁(yè)數(shù)據(jù)庫(kù),可以瞬間找到相關(guān)的搜索結(jié)果。'
}
}
})
</script>
- v-for遍歷對(duì)象key-value
<div>
<ul>
<li v-for='(value, key) in website'>
{{key}} : {{value}}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
website: {
name: '百度一下',
url: 'http://www.baidu.com',
desc: '全球最大的中文搜索引擎、致力于讓網(wǎng)民更便捷地獲取信息,找到所求。百度超過(guò)千億的 中文網(wǎng)頁(yè)數(shù)據(jù)庫(kù),可以瞬間找到相關(guān)的搜索結(jié)果。'
}
}
})
</script>
- v-for遍歷對(duì)象key-value 帶索引
<div>
<ul>
<li v-for='(value, key, index) in website'>
{{index}} : {{key}} : {{value}}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
website: {
name: '百度一下',
url: 'http://www.baidu.com',
desc: '全球最大的中文搜索引擎、致力于讓網(wǎng)民更便捷地獲取信息,找到所求。百度超過(guò)千億的 中文網(wǎng)頁(yè)數(shù)據(jù)庫(kù),可以瞬間找到相關(guān)的搜索結(jié)果。'
}
}
})
</script>
Vue.js構(gòu)造器(2)
構(gòu)造器的格式如下:
<script>
var vm = new Vue({
el: '#id',
data: {
//數(shù)據(jù)
},
methods: {
//函數(shù)
},
computed: {
//計(jì)算屬性
},
watch: {
//監(jiān)聽(tīng)屬性
}
})
</script>
1、計(jì)算屬性
計(jì)算屬性關(guān)鍵詞: computed。計(jì)算屬性在處理一些復(fù)雜邏輯時(shí)是很有用的。
(1) computed getter
<div id="app">
<p>原始字符串: {{ msg }}</p>
<p>計(jì)算后反轉(zhuǎn)字符串: {{ reversedMsg }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
msg: 'Hello!'
},
computed: {
reversedMsg: function () {
return this.msg.split('').reverse().join('')
}
}
})
</script>
我們可以使用 methods 來(lái)替代 computed,效果上兩個(gè)都是一樣的,但是 computed 是基于它的依賴(lài)緩存,只有相關(guān)依賴(lài)發(fā)生改變時(shí)才會(huì)重新取值。而使用 methods ,在重新渲染的時(shí)候,函數(shù)總會(huì)重新調(diào)用執(zhí)行。
可以說(shuō)使用 computed 性能會(huì)更好,但是如果你不希望緩存,你可以使用 methods 屬性。
(2)computed setter
<script>
var vm = new Vue({
el: '#app',
data: {
name: '百度',
url: 'http://www.baidu.com'
},
computed: {
site: {
// getter
get: function () {
return this.name + ' ' + this.url
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.name = names[0]
this.url = names[names.length - 1]
}
}
}
})
// 調(diào)用setter, vm.name 和 vm.url 也會(huì)被對(duì)應(yīng)更新
vm.site = '新浪新聞 http://www.sina.com';
document.write('name: ' + vm.name);
document.write('<br>');
document.write('url: ' + vm.url);
</script>
2、監(jiān)聽(tīng)屬性
監(jiān)聽(tīng)屬性關(guān)鍵字:watch,可以通過(guò) watch 來(lái)響應(yīng)數(shù)據(jù)的變化
<div id="computed_props">
分 : <input type="text" v-model="minutes">
秒 : <input type="text" v-model="seconds">
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#computed_props',
data: {
minutes: 0,
seconds: 0
},
methods: {},
computed: {},
watch: {
minutes: function(val) {
this.minutes = val;
this.seconds = val * 60;
},
seconds: function(val) {
this.minutes = val / 60;
this.seconds = val;
}
}
});
</script>
Vue.js 樣式綁定
class 與 style 是 HTML 元素的屬性,用于設(shè)置元素的樣式,我們可以用 v-bind 來(lái)設(shè)置樣式屬性。
Vue.js v-bind 在處理 class 和 style 時(shí), 專(zhuān)門(mén)增強(qiáng)了它。表達(dá)式的結(jié)果類(lèi)型除了字符串之外,還可以是對(duì)象或數(shù)組。
1、綁定內(nèi)聯(lián)樣式style
- 可以通過(guò) v-bind:style 直接設(shè)置樣式
<div id="app">
<div v-bind:style='{ background: mycolor, fontSize: mysize + "px"}'>我是一個(gè)div</div>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
mycolor: 'pink',
mysize: 30
}
})
</script>
- 也可以直接綁定到一個(gè)樣式對(duì)象,讓模板更清晰
<div id="app">
<div v-bind:style='mystyle'>我是一個(gè)div</div>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
mystyle: {
background: 'pink',
fontSize: '30px'
}
}
})
</script>
- 可以使用數(shù)組將多個(gè)樣式對(duì)象應(yīng)用到一個(gè)元素上
<div id="app">
<div v-bind:style='[back, font]'>我是一個(gè)div</div>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
back: {
background: 'pink',
color: 'blue'
},
font: {
fontSize: '30px',
fontWeight: 'bold'
}
}
})
</script>
2、綁定屬性class
- 可以通過(guò)v-bind:class設(shè)置樣式
<div id="app">
<div v-bind:class="{classA: isA }"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isA: true
}
})
</script>
<style>
.classA {
width: 100px;
height: 100px;
background: green;
}
</style>
- 可以傳入多個(gè)屬性來(lái)改變樣式
<div class="static"
v-bind:class="{ classA: isA, classB: isB }">
</div>
<script>
new Vue({
el: '#app',
data: {
isA: true,
isB: true
}
})
</script>
<style>
.classA {
width: 100px;
height: 100px;
background: green;
}
.classB {
background: red;
}
</style>
- 可以直接綁定數(shù)據(jù)里的一個(gè)對(duì)象
<div class="static"
v-bind:class="object">
</div>
<script>
new Vue({
el: '#app',
data: {
object: {
classA: true,
classB: true
}
}
})
</script>
<style>
.classA {
width: 100px;
height: 100px;
background: green;
}
.classB {
background: red;
}
</style>
- 可以使用數(shù)組綁定多個(gè)樣式
<div id="app">
<div v-bind:class="[classA, classB]"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
classA: 'A',
classB: 'B'
}
})
</script>
<style>
.A {
width: 100px;
height: 100px;
background: green;
}
.B {
background: red;
}
- 可以使用三元表達(dá)式來(lái)切換列表中的 class
<div id="app">
<div v-bind:class="[isA ? aClass : bClass]"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isA: true,
aClass: 'A',
bClass: 'B'
}
})
</script>
<style>
.A {
width: 100px;
height: 100px;
background: red;
}
.B {
width: 100px;
height: 100px;
background: green;
}
</style>
Vue.js 表單
可以使用 v-model 指令在表單控件元素上創(chuàng)建雙向數(shù)據(jù)綁定。 v-model 會(huì)根據(jù)控件類(lèi)型自動(dòng)選取正確的方法來(lái)更新元素。
v-model會(huì)忽略所有表單元素的 value、checked、selected 特性的初始值而總是將 Vue 實(shí)例(new Vue({}))的數(shù)據(jù)(data)作為數(shù)據(jù)來(lái)源。你應(yīng)該通過(guò) JavaScript 在組件的 data選項(xiàng)中聲明初始值。
對(duì)于需要使用輸入法 (如中文、日文、韓文等) 的語(yǔ)言,你會(huì)發(fā)現(xiàn) v-model不會(huì)在輸入法組合文字過(guò)程中得到更新。如果你也想處理這個(gè)過(guò)程,請(qǐng)使用 input 事件。
1、input
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
2、textarea
在文本區(qū)域插值 (<textarea></textarea>) 并不會(huì)生效,應(yīng)用 v-model 來(lái)代替。
<textarea v-model="message" placeholder="add multiple lines"></textarea><br>
<span>Multiline message is:</span>
<p>{{ message }}</p>
3、checkbox
- 單個(gè)復(fù)選框,綁定到布爾值:
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
- 多個(gè)復(fù)選框,綁定到同一個(gè)數(shù)組:
<div id='app'>
<input type="checkbox" id="zhang3" value="張三" v-model="checkedNames">
<label for="zhang3">張三</label>
<input type="checkbox" id="li4" value="李四" v-model="checkedNames">
<label for="li4">李四</label>
<input type="checkbox" id="wang5" value="王五" v-model="checkedNames">
<label for="wang5">王五</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
checkedNames: []
}
})
</script>
4、radio
<div id="app">
<label> <input type='radio' name="single" value="H5" v-model='choice' /> H5 </label>
<label> <input type='radio' name="single" value="嵌入式" v-model='choice' /> 嵌入式 </label>
<label> <input type='radio' name="single" value="java" v-model='choice' /> java </label><br />
<span>{{choice}}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
choice: []
}
})
</script>
5、select
- 單選時(shí)
<div id="app">
<select v-model="selected">
<option disabled value="">請(qǐng)選擇</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
selected: ''
}
})
</script>
- 多選時(shí)(綁定到一個(gè)數(shù)組)
<div id="app">
<select v-model="selected" multiple style="width: 50px;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
selected: []
}
})
</script>
- 用v-for渲染的動(dòng)態(tài)選項(xiàng)
<div id='app'>
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})
</script>
6、修飾符
(1).lazy:在默認(rèn)情況下,v-model在每次 input事件觸發(fā)后將輸入框的值與數(shù)據(jù)進(jìn)行同步 。你可以添加 lazy 修飾符,從而轉(zhuǎn)變?yōu)槭褂?change事件進(jìn)行同步:
<div id="app">
<input type="text" v-model.lazy='msg'/><br />
<p>{{msg}}</p>
</div>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
msg: '你好'
}
})
</script>
(2).number:如果想自動(dòng)將用戶(hù)的輸入值轉(zhuǎn)為數(shù)值類(lèi)型,可以給 v-model 添加 number修飾符 。這通常很有用,因?yàn)榧词乖?type="number" 時(shí),HTML 輸入元素的值也總會(huì)返回字符串。
<div id="app">
<input type="text" v-model.number="message">
<p>{{message}}</p>
<input @click="assay" type="button" value="獲取">
</div>
<script>
new Vue({
el: '#app',
data: {
message: ""
},
methods: {
assay () {
console.log(typeof this.message);
}
}
})
</script>
需要注意的是:number修飾符并不是限制用戶(hù)的輸入,而是將用戶(hù)輸入的數(shù)據(jù)嘗試綁定為 js 中的 number類(lèi)型 。如果用戶(hù)輸入的是數(shù)字,那么會(huì)得到一個(gè)number類(lèi)型的值,而如果用戶(hù)輸入的不是數(shù)字,這個(gè)指令并不會(huì)產(chǎn)生任何效果。
(3).trim:如果要自動(dòng)過(guò)濾用戶(hù)輸入的首尾空格,可以添加 trim 修飾符到 v-model 上過(guò)濾輸入
<div id="app">
<input type="text" v-model.trim="message">
<p>{{message}}</p>
<input @click="assay" type="button" value="獲取">
</div>
<script>
new Vue({
el: '#app',
data: {
message: ""
},
methods: {
assay () {
console.log(this.message);
}
}
})
</script>
Vue.js 組件
組件(Component)是 Vue.js 最強(qiáng)大的功能之一。
組件可以擴(kuò)展 HTML 元素,封裝可重用的代碼。
組件相當(dāng)于新建一個(gè)屬于自己的標(biāo)簽。但是這個(gè)標(biāo)簽的功能很強(qiáng)大,可以有很多特殊的功能。
組件系統(tǒng)讓我們可以用獨(dú)立可復(fù)用的小組件來(lái)構(gòu)建大型應(yīng)用,幾乎任意類(lèi)型的應(yīng)用的界面都可以抽象為一個(gè)組件樹(shù):
1、全局組件
全局注冊(cè)的組件可以用在任何新創(chuàng)建的 Vue 根實(shí)例 (new Vue) 的模板中 ,需要注意的是:全局組件必須寫(xiě)在Vue實(shí)例創(chuàng)建之前,才在該根元素下面生效
(1)注冊(cè)全局組件語(yǔ)法格式 如下:定義在script中,new Vue({ })之前
<script>
Vue.component(tagName, options)
參數(shù)說(shuō)明:
tagName:組件名稱(chēng)
options:配置選項(xiàng)
</script>
(2)調(diào)用組件
<tagName></tagName>
示例:
<div id="app">
<!-- 3、使用組件 -->
<my-component></my-component>
</div>
<script>
// 2、注冊(cè)全局組件
Vue.component('my-component', {
template: '<h1>自定義組件!</h1>'
})
// 1、創(chuàng)建根實(shí)例
new Vue({
el: '#app'
})
</script>
2、局部組件
如果不需要全局注冊(cè),或者是讓組件使用在其它組件內(nèi),可以用選項(xiàng)對(duì)象的components屬性實(shí)現(xiàn)局部注冊(cè)。
<div id="app">
<!-- 3、my-componen只能在#app下使用 -->
<my-component></my-component>
</div>
<script>
//1、創(chuàng)建局部組件
var Child = {
template: '<h1>自定義組件!</h1>'
}
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app',
components: {
//2、在根實(shí)例中注冊(cè)局部組件
'my-component': Child
}
})
</script>
3、組件中的屬性
關(guān)于組件中的其他屬性,可以和實(shí)例中的一樣,但是data屬性必須是一個(gè)函數(shù)。
(1)全局組件
<div id="app">
<my-component></my-component>
</div>
<script>
Vue.component("my-component",{
template:"<button @click='add'>全局組件:{{m}}</button>",
data:function(){
return {
m:10
}
},
methods:{
add:function(){
this.m++
}
}
});
new Vue({
el:"#app"
})
</script>
(2)局部組件
<div id="app">
<child-component></child-component>
</div>
<script>
var child={
template:"<button @click='add'>我是局部組件:{{m}}</button>",
data:function(){
return {
m:1
}
},
methods:{
add:function(){
this.m++
}
}
};
new Vue({
el: "#app",
components:{
"child-component":child
}
})
</script>
4、prop
prop 是父組件用來(lái)傳遞數(shù)據(jù)的一個(gè)自定義屬性。
父組件的數(shù)據(jù)需要通過(guò) props 把數(shù)據(jù)傳給子組件,子組件需要顯式地用 props 選項(xiàng)聲明 "prop"
<div id="app">
<child message="hello!"></child>
</div>
<script>
// 注冊(cè)全局組件
Vue.component('child', {
// 聲明 props
props: ['message'],
template: '<span>{{ message }}</span>'
})
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app'
})
</script>
Vue.js 路由
有時(shí)候,我們?cè)谟胿ue的時(shí)候會(huì)有這樣的需求,比如一個(gè)管理系統(tǒng),點(diǎn)了左邊的菜單欄,右邊跳轉(zhuǎn)到一個(gè)新的頁(yè)面中,而且刷新的時(shí)候還會(huì)停留在原來(lái)打開(kāi)的頁(yè)面。
又或者,一個(gè)頁(yè)面中幾個(gè)不同的畫(huà)面來(lái)回點(diǎn)擊切換,這兩種情況都可以用vue router路由來(lái)解決
<!-- 導(dǎo)入js文件 -->
<script src="https://cdn.bootcss.com/vue-router/2.4.0/vue-router.js"></script>
<div id="app">
<div>
<!--
使用router-link組件來(lái)導(dǎo)航,
通過(guò) to屬性就是指向某個(gè)具體的鏈接,鏈接的內(nèi)容會(huì)被渲染到router-view標(biāo)簽中
router-link會(huì)被渲染成a標(biāo)簽,
例如第一個(gè)會(huì)變成<a href="#/first">第一個(gè)頁(yè)面</a>,前面加了個(gè)#
-->
<router-link to="/first">第1個(gè)頁(yè)面</router-link>
<router-link to="/second">第2個(gè)頁(yè)面</router-link>
<router-link to="/third">第3個(gè)頁(yè)面</router-link>
</div>
<!-- 路由匹配到的組件將渲染在這里 -->
<router-view></router-view>
</div>
<script type="text/javascript">
//1、申明三個(gè)模板(定義路由組件)
var first = { template: '<p>this is first page</p>' };
var second = { template: '<p>this is second page</p>' };
var third = { template: '<p>this is third page</p>' };
//2、定義路由,每個(gè)路由應(yīng)該映射一個(gè)組件
//其中,component屬性是通過(guò) Vue.extend()創(chuàng)建的組件構(gòu)造器,
//或者,只是一個(gè)組件配置對(duì)象。
var routes = [
{ path: '/first', component: first },
{ path: '/second', component: second },
{ path: '/third', component: third }
];
//3、創(chuàng)建VueRouter實(shí)例
var router = new VueRouter({
routes //(縮寫(xiě))相當(dāng)于routes: routes
});
/*4、創(chuàng)建和掛載根實(shí)例
* 通過(guò)router配置參數(shù)注入路由,給vue對(duì)象綁定路由
* .$mount("#app")手動(dòng)掛載,用來(lái)延遲掛載,跟
* const app = new Vue({
* el:"#app"
* router
* });
* 效果是一樣的
*/
const app = new Vue({
router
}).$mount("#app");
</script>
運(yùn)行步驟:
- 當(dāng)router-link對(duì)應(yīng)的標(biāo)簽被點(diǎn)擊時(shí),比如此時(shí)點(diǎn)擊第二個(gè),to的值是/second,那么實(shí)際的地址就是當(dāng)前頁(yè)面地址+#/second。
- Vue會(huì)找到當(dāng)前vue實(shí)例的路由里的routes里面path為/second的路由。
- 會(huì)將找到的這一行記錄的模板component渲染到router-view里面。