一、模版指令
通過模版指令(寫在html中的),即是html和vue對(duì)象的粘合劑。
- 數(shù)據(jù)渲染 v-text、v-html、{{}}
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
v-text
更新元素的textContent
,v-html
更新元素的innerHTML
,內(nèi)容按普通 HTML 插入,不會(huì)作為 Vue 模板進(jìn)行編譯。如果想要title: 'TOMVC <sub>2.0</sub>'
不以字符串形式顯示,就可以使用v-html,<h2 v-html='title'></h2>
- 控制模塊顯示隱藏 v-if、v-show
<div id="view">
<p v-if='isShow'></p>
<p v-show='isShow'></p>
</div>
new Vue({
el: '#view',
data: {
isShow: true
}
});
v-if是直接不渲染該元素; v-show是通過display: none進(jìn)行隱藏;
- 渲染循環(huán)列表 v-for
模板引擎都會(huì)提供循環(huán)的支持。Vue也不例外,Vue是提供了一個(gè)v-for指令。基本的用法類似于foreach的用法。
<ul class="view">
// 遍歷數(shù)組,取出每個(gè)元素
<li v-for='item in list'>
{{item.text}}
</li>
</ul>
<script>
var app = new Vue({
el: '.view',
data: {
list: [ // 數(shù)組
{text: '01、HTML'},
{text: '02、CSS'},
{text: '03、JavaScript'}
]
}
});
</script>
- 事件綁定 v-on
<div id="view4">
<input type="button" value="按鈕" v-on:click='doThis' />
// 簡寫
<input type="button" value="按鈕" @click='doThis' />
</div>
<script>
new Vue({
el: '#view4',
methods: {
doThis: function(){
alert('hello');
}
}
});
</script>
- 屬性綁定 v-bind
Vue中不能直接使用{{ expression}}
語法進(jìn)行綁定html的標(biāo)簽,而是用它特有的v-bind指令,語法<標(biāo)簽 v-bind:屬性名="要綁定的Vue對(duì)象的data里的屬性名"></標(biāo)簽>
。
由于v-bind 使用非常頻繁,所以Vue提供了簡單的寫法,可以去掉v-bind直接使用:即可。
<div id="view">


<p :class='InfoClass'></p>
</div>
<script>
new Vue({
el: '#view',
data: {
imgSrc: 'm_3_100.png',
InfoClass: 'infoRed'
}
});
</script>
- 樣式綁定 v-bind
對(duì)于普通的屬性的綁定,只能用上面的講的綁定屬性的方式。而Vue專門加強(qiáng)了class和style的屬性的綁定。可以有復(fù)雜的對(duì)象綁定、數(shù)組綁定樣式和類。
經(jīng)常我們需要對(duì)樣式進(jìn)行切換,比如:div的顯示和隱藏,某些標(biāo)簽active等。Vue提供的對(duì)象綁定樣式的方式就很容做這些事情。
<style>
.view{
width: 300px;
height: 30px;
border: 1px solid gray;
line-height: 30px;
text-align: center;
}
.active{ // 使能樣式
color: red;
}
</style>
// 當(dāng)isActive為true時(shí),這個(gè)div就會(huì)添加類名active;當(dāng)isActive為false時(shí),這個(gè)div就會(huì)移出類名active;
<div class="view" :class='{active:isActive}'>
{{message}}
</div>
var app = new Vue({
el: '.view',
data: {
message: 'hello Vue.',
isActive: false
}
});
- 雙向數(shù)據(jù)綁定 v-model
上面的例子基本都是單向的js對(duì)象向 HTML數(shù)據(jù)進(jìn)行綁定,那HTML怎樣向js進(jìn)行反饋數(shù)據(jù)呢?
Vue提供了一個(gè)新的指令:v-model進(jìn)行雙向數(shù)據(jù)的綁定,注意不是v-bind。
<div id="app">
<p>{{ message }}</p>
// 雙向數(shù)據(jù)綁定
<input v-model="message">
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
二、Vue組件中重要選項(xiàng)
Vue的實(shí)例是Vue框架的入口,其實(shí)也就是前端的ViewModel,它包含了頁面中的業(yè)務(wù)邏輯處理、數(shù)據(jù)模型等,當(dāng)然它也有自己的一系列的生命周期的事件鉤子,輔助我們進(jìn)行對(duì)整個(gè)Vue實(shí)例生成、編譯、掛載、銷毀等過程進(jìn)行js控制。
- data數(shù)據(jù)選項(xiàng),代表vue對(duì)象的數(shù)據(jù)
創(chuàng)建的Vue對(duì)象中的data屬性就是用來綁定數(shù)據(jù)到HTML的,Vue框架會(huì)自動(dòng)監(jiān)視data里面的數(shù)據(jù)變化,自動(dòng)更新數(shù)據(jù)到HTML標(biāo)簽上去。本質(zhì)原理是:Vue會(huì)自動(dòng)將data里面的數(shù)據(jù)進(jìn)行遞歸抓換成getter和setter,然后就可以自動(dòng)更新HTML標(biāo)簽了,當(dāng)然用getter和setter所以老的瀏覽器Vue支持的不夠好。
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: { // data數(shù)據(jù)選項(xiàng)
message: 'Hello Vue!'
}
})
- methods方法選項(xiàng),代表vue對(duì)象的方法
方法中的 this 自動(dòng)綁定為 Vue 實(shí)例。
<div id="view">
<input type="button" value="按鈕" @click='doThis' />
</div>
<script>
new Vue({
el: '#view',
methods: { // methods方法選項(xiàng)
doThis: function(){
alert('hello');
}
}
});
</script>
- computed計(jì)算屬性
在做數(shù)據(jù)的綁定的時(shí)候,數(shù)據(jù)要進(jìn)行處理之后才能展示到html頁面上,雖然vue提供了非常好的表達(dá)式綁定的方法,但是只能應(yīng)對(duì)低強(qiáng)度的需求,另外放入太多的邏輯會(huì)讓模板過重且難以維護(hù)。而計(jì)算屬性,即屬性可以是一個(gè)方法。
所有 getter 和 setter 的 this 上下文自動(dòng)地綁定為 Vue 實(shí)例。這就很強(qiáng)大了,在計(jì)算屬性中定義的函數(shù)里面可以直接使用指向了vue實(shí)例的this。
<div class="view">
// 計(jì)算屬性,好處在于會(huì)自動(dòng)根據(jù)totalPrice顯示不同內(nèi)容
{{showStr}}
</div>
var app = new Vue({
el: '.view',
data: {
totalPrice: 18
},
computed: { // Vue對(duì)象的computed屬性
// 計(jì)算屬性,但該屬性是一個(gè)方法
showStr: function(){
// this指向vue實(shí)例
if(this.totalPrice < 20){
return '金額小于20,沒有優(yōu)惠喔!'
} else {
return '金額大于20,免配送費(fèi)!'
}
}
}
});
- watch監(jiān)聽選項(xiàng),設(shè)置了對(duì)象的監(jiān)聽方法
一個(gè)對(duì)象,鍵是需要觀察的表達(dá)式,值是對(duì)應(yīng)回調(diào)函數(shù)。值也可以是方法名,或者包含選項(xiàng)的對(duì)象。
var view2 = new Vue({
el: '#view2',
data: {
a: 1
},
methods: {
doSomething: function(){
this.a++;
}
},
watch: {
a: function(newvalue, oldvalue){
console.log(newvalue, oldvalue);
}
}
});
三、Vue實(shí)例的生命周期
Vue實(shí)例有一個(gè)完整的生命周期,也就是從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom、渲染→更新→渲染、卸載等一系列過程,我們稱這是Vue的生命周期。通俗說就是Vue實(shí)例從創(chuàng)建到銷毀的過程,就是生命周期。
Vue提供的可以注冊(cè)的鉤子都在上圖片的紅色框標(biāo)注:
-
beforeCreate
: 在實(shí)例初始化之后,數(shù)據(jù)觀測(cè)(data observer) 和 event/watcher 事件配置之前被調(diào)用。 -
created
: 實(shí)例已經(jīng)創(chuàng)建完成之后被調(diào)用。在這一步,實(shí)例已完成以下的配置:數(shù)據(jù)觀測(cè)(data observer),屬性和方法的運(yùn)算, watch/event 事件回調(diào)。然而,掛載階段還沒開始,$el 屬性目前不可見。 -
beforeMount
: 在掛載開始之前被調(diào)用:相關(guān)的 render 函數(shù)首次被調(diào)用。 -
mounted
: el 被新創(chuàng)建的 vm.$el 替換,并掛載到實(shí)例上去之后調(diào)用該鉤子。如果 root 實(shí)例掛載了一個(gè)文檔內(nèi)元素,當(dāng) mounted 被調(diào)用時(shí) vm.$el 也在文檔內(nèi)。 -
beforeUpdate
: 數(shù)據(jù)更新時(shí)調(diào)用,發(fā)生在虛擬 DOM 重新渲染和打補(bǔ)丁之前。 你可以在這個(gè)鉤子中進(jìn)一步地更改狀態(tài),這不會(huì)觸發(fā)附加的重渲染過程。 -
updated
: 由于數(shù)據(jù)更改導(dǎo)致的虛擬 DOM 重新渲染和打補(bǔ)丁,在這之后會(huì)調(diào)用該鉤子。當(dāng)這個(gè)鉤子被調(diào)用時(shí),組件 DOM 已經(jīng)更新,所以你現(xiàn)在可以執(zhí)行依賴于 DOM 的操作。然而在大多數(shù)情況下,你應(yīng)該避免在此期間更改狀態(tài),因?yàn)檫@可能會(huì)導(dǎo)致更新無限循環(huán)。 -
beforeDestroy
: 實(shí)例銷毀之前調(diào)用,在這一步,實(shí)例仍然完全可用。 -
destroyed
: Vue 實(shí)例銷毀后調(diào)用。調(diào)用后,Vue 實(shí)例指示的所有東西都會(huì)解綁定,所有的事件監(jiān)聽器會(huì)被移除,所有的子實(shí)例也會(huì)被銷毀。
四、Vue的全局API
- Vue.nextTick
在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個(gè)方法,獲取更新后的 DOM。即保證操作的DOM已經(jīng)渲染。
Vue.nextTick(function () {
// DOM 更新完成,可以操作
})
- Vue.set
設(shè)置對(duì)象的屬性。如果對(duì)象是響應(yīng)式的,確保屬性被創(chuàng)建后也是響應(yīng)式的,同時(shí)觸發(fā)視圖更新。這個(gè)方法主要用于避開 Vue 不能檢測(cè)屬性被添加的限制。
Vue.set( object, key, value )
- Vue.use
加載插件
// 導(dǎo)入VueRouter
import VueRouter from 'vue-router';
// 加載插件(全局注冊(cè)一樣)
Vue.use(VueRouter);
- Vue. mount
如果 Vue 實(shí)例在實(shí)例化時(shí)沒有收到 el 選項(xiàng),則它處于“未掛載”狀態(tài),沒有關(guān)聯(lián)的 DOM 元素。可以使用Vue. mount
手動(dòng)地掛載一個(gè)未掛載的實(shí)例。
var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
});
// 創(chuàng)建并掛載到 #app (會(huì)替換 #app)
new MyComponent().$mount('#app')
// 同上
new MyComponent({ el: '#app' })
五、組件
組件 (Component) 是 Vue.js 最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器為它添加特殊功能。組件其實(shí)就是一個(gè)擁有樣式、動(dòng)畫、js邏輯、HTML結(jié)構(gòu)的綜合塊。
- 如何劃分組件
- 功能模塊: select、pagenation...
- 頁面區(qū)域劃分: header、footer、sidebar...
- 全局?jǐn)U展方法Vue.extend
Vue提供了一個(gè)全局的API,Vue.extend可以幫助我們對(duì)Vue實(shí)例進(jìn)行擴(kuò)展,擴(kuò)展完了之后,就可以用此擴(kuò)展對(duì)象創(chuàng)建新的Vue實(shí)例了。 類似于繼承的方式。
<script>
// 創(chuàng)建構(gòu)造器
var Profile = Vue.extend({
// 新的對(duì)象的模板,所有子實(shí)例都會(huì)擁有此模板
template: '<p>{{firstName}} {{lastName}}</p>',
// 創(chuàng)建的Vue實(shí)例時(shí),data可以是Object 也可以是Function,但是在擴(kuò)展的時(shí)候,data必須是一個(gè)函數(shù),而且要返回值
data: function () {
return {
firstName: '張三',
lastName: '張二蛋',
}
}
});
// 創(chuàng)建 Profile 實(shí)例,并掛載到一個(gè)元素上
new Profile().$mount('#mount-point')
// 或者下面這種寫法
new Profile({
el: '#mount-point'
});
</script>
- 創(chuàng)建一個(gè)組件并注冊(cè)使用
Vue提供了一個(gè)全局注冊(cè)組件的方法:Vue.component。
使用 Vue.component 來定義全局組件,緊接著用 new Vue({ el: '#container '}) 在每個(gè)頁面內(nèi)指定一個(gè)容器元素
<div id="view">
<!--組件直接跟普通的標(biāo)簽一樣的使用-->
<my-title></my-title>
</div>
// 注冊(cè)一個(gè)組件
Vue.component('my-title', {
// 模板選項(xiàng)設(shè)置當(dāng)前組件,最終輸出的html模板。注意:有且只有一個(gè)根元素。
template: '<div>A custom component!</div>'
})
// 創(chuàng)建根實(shí)例
new Vue({
el: '#view'
})
- 局部注冊(cè)組件
不必在全局注冊(cè)每個(gè)組件,有時(shí)需要注冊(cè)一個(gè)局部模塊。
<div class="view">
// 組件在注冊(cè)之后,便可以在父實(shí)例的模塊中以自定義元素
<my-components></my-components>
</div>
<script>
var Child = {
template: '<div>A custom component!</div>'
}
// 創(chuàng)建一個(gè)Vue實(shí)例
var app = new Vue({
el: '.view',
components: { // 局部注冊(cè)組件(如果沒有局部注冊(cè)是不能使用的)
'my-components' : Child
}
});
</script>
- data必須是函數(shù)
通過 Vue 構(gòu)造器傳入的各種選項(xiàng)大多數(shù)都可以在組件里用。data 是一個(gè)例外,它必須是函數(shù)。
<div class="view">
<my-title></my-title>
</div>
<script>
// 注冊(cè)一個(gè)全局組件
Vue.component('my-title', {
template: '<h1> {{title}} </h1>',
data: function(){
return {
title: 'hello Vue!'
}
}
});
// 創(chuàng)建一個(gè)Vue實(shí)例
var app = new Vue({
el: '.view'
});
</script>
- 單文件組件的使用方式介紹 【項(xiàng)目開發(fā)都會(huì)是一個(gè)文件對(duì)應(yīng)一個(gè)組件】
通過上面我們定義組件的方式,就已經(jīng)感覺很不爽了,尤其是模板的定義,而且樣式怎么處理也沒有很好的進(jìn)行規(guī)整。 Vue可以通過Webpack等第三方工具實(shí)現(xiàn)單文件的開發(fā)的方式。
// Hello.vue組件
<template>
<h3>
標(biāo)題: {{str}}
</h3>
</template>
<script>
export default {
data: function(){
return {
str: 'hello Vue!'
}
}
}
</script>
<style>
h3{
text-align: center;
}
</style>
<script>
// App.vue組件中使用Hello.vue組件
// 導(dǎo)入Hello組件
import Hello from './components/Hello';
export default {
// ...
components: { // 局部注冊(cè)組件
Hello
}
}
</script>
<template>
// 使用自定義元素(Hello組件)
<hello></hello>
</template>
通過vue-cli腳手架構(gòu)造項(xiàng)目
- 組件間調(diào)用 --- components
如果要使用某個(gè)組件,單純通過import
導(dǎo)入是不行的,還需要通過components
進(jìn)行注冊(cè)才能使用。
// App.vue中
// 導(dǎo)入組件
import Header from './header'
import Footer from './footer'
new Vue({
// 組件需要注冊(cè)之后才能使用
components:{
Header, Footer
}
})
// 在App.vue中
<header></header>
<footer></footer>
- 組件間通信 --- props (父組件給子組件傳參)
組件實(shí)例的作用域是孤立的。這意味著不能 (也不應(yīng)該) 在子組件的模板內(nèi)直接引用父組件的數(shù)據(jù)。要讓子組件使用父組件的數(shù)據(jù),我們需要通過子組件的 props 選項(xiàng)。
// header.vue 子組件
new Vue({
props: ['message'], // 不同組件中的數(shù)據(jù)操作()
methods: {
doThis: function(){ // 子組件獲取到父組件傳遞的參數(shù)this.message
console.log(this.message);
}
}
})
// props可以其他寫法
props:{
seller:{ // 即是設(shè)置接收參數(shù)的數(shù)據(jù)類型
type: Object, // 參數(shù)的類型
// default 是設(shè)置默認(rèn)值的
}
}
// app.vue 父組件
// 將字符串內(nèi)容'hello world!'傳遞給子組件
<header message='hello world!'></header>
// 綁定data屬性值
// <header :message='title'></header>
- 組件間通信 --- 自定義事件(子組件給父組件傳參)
// app.vue 父組件
// 自定義事件v-on: child-tell-me, 事件名為'child-tell-me'
<component-b v-on:child-tell-me='getMsg'></component-b>
new Vue({
// ...
methods: {
// 'child-tell-me'對(duì)應(yīng)觸發(fā)的方法,即父組件獲取子組件傳遞的參數(shù)msg
getMsg: function(msg){
console.log(msg)
}
}
})
// footer.vue 子組件
new Vue({
// ...
methods: {
// 在sendMsg方法中,即觸發(fā)'child-tell-me'方法,并傳遞參數(shù)
sendMsg: function(msg){
this.$emit('child-tell-me', '你收到我發(fā)送的消息了嗎?【componentB】')
}
}
})
六、Vue路由
對(duì)于前端來說,其實(shí)瀏覽器配合超級(jí)連接就很好的實(shí)現(xiàn)了路由功能。但是對(duì)于單頁面應(yīng)用來說,瀏覽器和超級(jí)連接的跳轉(zhuǎn)方式已經(jīng)不能適用, 所以各大框架紛紛給出了單頁面應(yīng)用的解決路由跳轉(zhuǎn)的方案。
Vue框架的兼容性非常好,可以很好的跟其他第三方的路由框架進(jìn)行結(jié)合。當(dāng)然官方也給出了路由的方案:vue-router; 建議還是用官方的最好,使用量也是最大,相對(duì)來說Vue框架的升級(jí)路由組件升級(jí)也會(huì)及時(shí)跟上,所以為了以后的維護(hù)和升級(jí)方便還是使用Vue自家的東西最好。
-
vue-router的安裝使用
1.CDN連接方式<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
2.npm 安裝
npm install vue-router
-
vue-router 入門
1.引入vue和vue-router(如果配合npm和webpack的話可以直接作為一個(gè)模塊導(dǎo)入即可)<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
2.定義路由跳轉(zhuǎn)的組件(或?qū)虢M件)
const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' }
定義路由規(guī)則對(duì)象
// 每個(gè)路由path應(yīng)該映射一個(gè)組件
const routes = [
{path: '/foo', component: Foo},
{path: '/Bar', component: Bar}
];
- 創(chuàng)建路由器對(duì)象
// 創(chuàng)建 router 實(shí)例,然后傳 `routes` 配置
const router = new VueRouter({
routes // (縮寫)相當(dāng)于 routes: routes,es6的新語法
});
- 創(chuàng)建和掛載根實(shí)例
const app = new Vue({
router
}).$mount('#app');
- 模板中編寫路由跳轉(zhuǎn)鏈接
<div id="app">
<p>
<!-- 使用 router-link 組件來導(dǎo)航. -->
<!-- 通過傳入 `to` 屬性指定鏈接. -->
<!-- <router-link> 默認(rèn)會(huì)被渲染成一個(gè) `<a>` 標(biāo)簽 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的組件將渲染在這里 -->
<router-view></router-view>
</div>
注意: vue-router@2.x 只適用于 Vue 2.x 版本。 vue-router@1.x 對(duì)應(yīng)于Vue1.x版本。
用 Vue.js + vue-router 創(chuàng)建單頁應(yīng)用,是非常簡單的。使用 Vue.js ,我們已經(jīng)可以通過組合組件來組成應(yīng)用程序,當(dāng)你要把 vue-router 添加進(jìn)來,我們需要做的是,將組件(components)映射到路由(routes),然后告訴 vue-router 在哪里渲染它們。
七、視頻學(xué)習(xí)
如果想要對(duì)Vue做進(jìn)一步的學(xué)習(xí),可以查看視頻課程,后續(xù)還會(huì)有vue進(jìn)階的實(shí)戰(zhàn)視頻喔!
vue入門基礎(chǔ)