Vue的實例、生命周期與Vue腳手架(vue-cli)實例詳解
一、Vue的實例
1.1、創(chuàng)建一個 Vue 的實例
每個 Vue 應用都是通過 Vue 函數(shù)創(chuàng)建一個新的 Vue 實例開始的:
var vm = new Vue({// 選項})
雖然沒有完全遵循 MVVM 模型,Vue 的設計無疑受到了它的啟發(fā)。因此在文檔中經(jīng)常會使用 vm (ViewModel 的簡稱) 這個變量名表示 Vue 實例。
1、vue.js就是一個構(gòu)造器,通過構(gòu)造器Vue來實例化一個對象;例如:var vm = new Vue({});
2、實例化Vue時,需要傳入一個參數(shù)(選項對象);
3、參數(shù):選項對象可以包含,數(shù)據(jù)(data)、掛載元素(el)、方法(methods)、模版(template)、生命周期函數(shù)等等;
4、擴展構(gòu)造器Vue,從而用預定義選項創(chuàng)建可復用的組件構(gòu)造器,所有組件都是被擴展的Vue的實例,使用Vue.extend({})來擴展;
注意:盡管可以命令式地創(chuàng)建擴展實例,不過在多數(shù)情況下建議將組件構(gòu)造器注冊為一個自定義元素,然后聲明式地用在模板中。
當創(chuàng)建一個 Vue 實例時,你可以傳入一個選項對象。這篇教程主要描述的就是如何使用這些選項來創(chuàng)建你想要的行為。作為參考,你也可以在 API 文檔 中瀏覽完整的選項列表。
一個 Vue 應用由一個通過 new Vue 創(chuàng)建的根 Vue 實例,以及可選的嵌套的、可復用的組件樹組成。舉個例子,一個 todo 應用的組件樹可以是這樣的:
Root Instance └─ TodoList ├─ TodoItem │ ├─ DeleteTodoButton │ └─ EditTodoButton └─ TodoListFooter ├─ ClearTodosButton └─ TodoListStatistics
我們會在稍后的組件系統(tǒng)章節(jié)具體展開。不過現(xiàn)在,你只需要明白所有的 Vue 組件都是 Vue 實例,并且接受相同的選項對象即可 (一些根實例特有的選項除外)。
1.2、數(shù)據(jù)與方法
當一個 Vue 實例被創(chuàng)建時,它向 Vue 的響應式系統(tǒng)中加入了其 data 對象中能找到的所有的屬性。當這些屬性的值發(fā)生改變時,視圖將會產(chǎn)生“響應”,即匹配更新為新的值。
// 我們的數(shù)據(jù)對象
var data = { a: 1 }
// 該對象被加入到一個 Vue 實例中
var vm = new Vue({
data: data
})
// 他們引用相同的對象!
vm.a === data.a // => true
// 設置屬性也會影響到原始數(shù)據(jù)
vm.a = 2
data.a // => 2
// ... 反之亦然
data.a = 3
vm.a // => 3
當這些數(shù)據(jù)改變時,視圖會進行重渲染。 值得注意的是只有當實例被創(chuàng)建時 data 中存在的屬性是響應式的 。也就是說如果你添加一個新的屬性,像:
vm.b = 'hi'
那么對 b 的改動將不會觸發(fā)任何視圖的更新。
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue2實例</title>
</head>
<body>
<div id="app1">
<input type="text" v-model="a"/>
</div>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var data={a:1}
//實例
var vm = new Vue({
el: "#app1",
data:data,
updated:function(){
console.log("實例被更新了!");
}
});
</script>
</body>
</html>
結(jié)果:

如果你知道你會在晚些時候需要一個屬性,但是一開始它為空或不存在,那么你僅需要設置一些初始值。比如:
data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null
}
除了 data 屬性,Vue 實例暴露了一些有用的實例屬性與方法。它們都有前綴 $,以便與用戶定義的屬性區(qū)分開來。例如:
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一個實例方法
vm.$watch('a', function (newValue, oldValue) {
// 這個回調(diào)將在 `vm.a` 改變后調(diào)用
})
在未來,你可以在 API 參考查閱到完整的實例屬性和方法的列表 。
1.3、實例屬性


解釋
vm._uid // 自增的id vm._isVue // 標示是vue對象,避免被observe vm._renderProxy // Proxy代理對象 vm._self // 當前vm實例 vm.$parent // 用于自定義子組件中,指向父組件的實例 vm.$root // 指向根vm實例 vm.$children // 當前組件的子組件實例數(shù)組 vm.$refs vm._watcher = null vm._inactive = null vm._directInactive = false vm._isMounted = false // 標識是否已掛載 vm._isDestroyed = false // 標識是否已銷毀 vm._isBeingDestroyed = false // 標識是否正在銷毀 vm._events // 當前元素上綁定的自定義事件 vm._hasHookEvent // 標示是否有hook:開頭的事件 vm.$vnode // 當前自定義組件在父組件中的vnode,等同于vm.$options._parentVnode vm._vnode // 當前組件的vnode vm._staticTrees // 當前組件模板內(nèi)分析出的靜態(tài)內(nèi)容的render函數(shù)數(shù)組 vm.$el // 當前組件對應的根元素 vm.$slots // 定義在父組件中的slots,是個對象鍵為name,值為響應的數(shù)組 vm.$scopedSlots = emptyObject // 內(nèi)部render函數(shù)使用的創(chuàng)建vnode的方法 vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false) // 用戶自定義render方法時,傳入的參數(shù) vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true) vm._props // 被observe的存儲props數(shù)據(jù)的對象 vm._data // 被observe的存儲data數(shù)據(jù)的對象 vm._computedWatchers // 保存計算屬性創(chuàng)建的watcher對象
1.4、實例方法
1.5、實例參數(shù)vm.$options
vm.$options其實也就是我們new Vue(options)options這個選項對象可傳入的屬性
declare type ComponentOptions = {
// data
data: Object | Function | void; // 傳入的data數(shù)據(jù)
props?: { [key: string]: PropOptions }; // props傳入的數(shù)據(jù)
propsData?: ?Object; // 對于自定義組件,父級通過`props`傳過來的數(shù)據(jù)
computed?: { // 傳入的計算屬性
[key: string]: Function | {
get?: Function;
set?: Function;
cache?: boolean
}
};
methods?: { [key: string]: Function }; // 傳入的方法
watch?: { [key: string]: Function | string }; // 傳入的watch
// DOM
el?: string | Element; // 傳入的el字符串
template?: string; // 傳入的模板字符串
render: (h: () => VNode) => VNode; // 傳入的render函數(shù)
renderError?: (h: () => VNode, err: Error) => VNode;
staticRenderFns?: Array<() => VNode>;
// 鉤子函數(shù)
beforeCreate?: Function;
created?: Function;
beforeMount?: Function;
mounted?: Function;
beforeUpdate?: Function;
updated?: Function;
activated?: Function;
deactivated?: Function;
beforeDestroy?: Function;
destroyed?: Function;
// assets
directives?: { [key: string]: Object }; // 指令
components?: { [key: string]: Class<Component> }; // 子組件的定義
transitions?: { [key: string]: Object };
filters?: { [key: string]: Function }; // 過濾器
// context
provide?: { [key: string | Symbol]: any } | () => { [key: string | Symbol]: any };
inject?: { [key: string]: string | Symbol } | Array<string>;
// component v-model customization
model?: {
prop?: string;
event?: string;
};
// misc
parent?: Component; // 父組件實例
mixins?: Array<Object>; // mixins傳入的數(shù)據(jù)
name?: string; // 當前的組件名
extends?: Class<Component> | Object; // extends傳入的數(shù)據(jù)
delimiters?: [string, string]; // 模板分隔符
// 私有屬性,均為內(nèi)部創(chuàng)建自定義組件的對象時使用
_isComponent?: true; // 是否是組件
_propKeys?: Array<string>; // props傳入對象的鍵數(shù)組
_parentVnode?: VNode; // 當前組件,在父組件中的VNode對象
_parentListeners?: ?Object; // 當前組件,在父組件上綁定的事件
_renderChildren?: ?Array<VNode>; // 父組件中定義在當前元素內(nèi)的子元素的VNode數(shù)組(slot)
_componentTag: ?string; // 自定義標簽名
_scopeId: ?string;
_base: Class<Component>; // Vue
_parentElm: ?Node; // 當前自定義組件的父級dom結(jié)點
_refElm: ?Node; // 當前元素的nextSlibing元素,即當前dom要插入到_parentElm結(jié)點下的_refElm前
}
1.5.1、computed計算屬性
在模板中綁定表達式是非常便利的,但是它們實際上只用于簡單的操作。在模板中放入太多的邏輯會讓模板過重且難以維護。例如:
<span>{{msg.split('').reverse().join('')}}</span>
使用計算屬性定義成一個方法可以復用且模板會更加簡潔:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue2實例</title>
</head>
<body>
<div id="app1">
<p>
<input type="text" v-model="msg" />
<span>{{msg.split('').reverse().join('')}}</span>
</p>
<p>
<input type="text" v-model="msg" />
<span>{{revMsg}}</span>
</p>
</div>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app1 = new Vue({
el: "#app1",
data: {
msg: "hello"
},
computed: {
revMsg: function() {
return this.msg.split('').reverse().join('');
}
}
});
</script>
</body>
</html>
結(jié)果:

注意:
1、computed中定義的方法只允許當著屬性用,不能帶參數(shù),這限制它的復用性。
2、當方法中的屬性發(fā)生變化時方法將重新調(diào)用
3、不應該使用箭頭函數(shù)來定義計算屬性函數(shù)
4、 computed計算屬性可以對屬性進行緩存的,計算屬性只有當該屬性發(fā)生變化的時候才會重新計算值
5、如果一個屬性不能完成需要的功能時可以考慮轉(zhuǎn)成計算
1.5.2、watch計算屬性
一個對象,鍵是需要觀察的表達式,值是對應回調(diào)函數(shù)。值也可以是方法名,或者包含選項的對象。Vue 實例將會在實例化時調(diào)用 $watch(),遍歷 watch 對象的每一個屬性。
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue2實例</title>
</head>
<body>
<div id="app1">
<p>
a:
<input type="text" v-model="a" />{{a}}<br/> b:
<input type="text" v-model="b" />{}<br/> c:
<input type="text" v-model="c.x.y.z" />{{c.x.y.z}}<br/> d:
<input type="text" v-model="d" />{ublnpf9mb}<br/>
</p>
<p>
n:<input type="text" v-model="c.x.y.n" />{{c.x.y.n}}
</p>
</div>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app1 = new Vue({
el: "#app1",
data: {
a: 1,
b: 2,
c: {
x: {
y: {
z: 3,
n: 3
}
}
},
d: 4
},
watch: {
a: function(val, oldVal) {
console.log('a新: %5s, 原: %5s', val, oldVal);
},
// 方法名
b: 'watchb',
//對象,深度監(jiān)視
c: {
handler: function(val, oldVal) {
console.log('c新: %5s, 原: %5s', JSON.stringify(val),JSON.stringify(oldVal));
},
deep:true
},
//立即監(jiān)視
d: {
handler: function(val, oldVal) {
console.log('c新: %5s, 原: %5s', val,oldVal);
},
immediate:true //設置初始值時也將調(diào)用
}
},
methods: {
watchb: function(val, oldVal) {
console.log('b新: %5s, 原: %5s', val, oldVal);
}
}
});
var watchb = function(val, oldVal) {
console.log('b新: %5s, 原: %5s', val, oldVal);
}
</script>
</body>
</html>
結(jié)果:

注意:不應該使用箭頭函數(shù)來定義 watcher 函數(shù)、對象類型時并非深拷貝的,只是引用。
1.5.3、方法methods
methods 將被混入到 Vue 實例中??梢灾苯油ㄟ^ VM 實例訪問這些方法,或者在指令表達式中使用。方法中的 this 自動綁定為 Vue 實例。
var vm = new Vue({
data: { a: 1 },
methods: {
plus: function () {
this.a++
}
}
})
vm.plus()
vm.a // 2
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue2實例</title>
</head>
<body>
<div id="app1">
<button type="button" v-on:click="add(2)">{{msg}}</button>
</div>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app1 = new Vue({
el: "#app1",
data:{
msg:"vue"
},
methods:{
add:function(str){
return this.msg+=str;
}
}
});
console.log(app1.add(3));
</script>
</body>
</html>
結(jié)果:

注意,不應該使用箭頭函數(shù)來定義 method 函數(shù) (例如 plus: () => this.a++)。理由是箭頭函數(shù)綁定了父級作用域的上下文,所以 this 將不會按照期望指向 Vue 實例,this.a 將是 undefined。
1.5.4、小結(jié)
computed是計算屬性的,methods是計算方法的,最主要的區(qū)別是 computed計算屬性可以對
屬性進行緩存的,計算屬性只有當該屬性發(fā)生變化的時候才會重新計算值,只要值沒有改變,它是不會重新渲染的,但是methods方法不同,每次調(diào)用該方法的時候,都會重新執(zhí)行的。
1、每個Vue的實例都會代理其data對象里的所有屬性,被代理的屬性是響應的;
2、如果實例創(chuàng)建之后添加新的屬性到實例上,不會觸發(fā)視圖更新;
3、不要在實例屬性或者回調(diào)函數(shù)中(如 vm.$watch('a', newVal => this.myMethod()))使用箭頭函數(shù)。因為箭頭函數(shù)綁定父上下文,所以 this 不會像預想的一樣是 Vue 實例,而是 this.myMethod 未被定義。
4、Vue實例暴露了一些有用的實例屬性和方法,帶有前綴 $ 便于與代理的data區(qū)分
a、vm.$el:類型(HTMLElement)掛載元素,Vue實例的DOM根元素;
b、vm.$data:類型(Object),Vue實例觀察的數(shù)據(jù)對象
c、vm.$props:類型(Object),屬性
d、vm.$options:類型(Object),用于當前Vue實例的初始化選項,在選項中需要包含自定義屬性的時候很有用。
e、vm.$parent:類型(Vue實例),父實例。
f、vm.$root:類型(Vue實例),當前組件樹的根Vue實例,如果沒有父實例,就是實例本身。
h、vm.$children:類型(Array(Vue實例)),當前實例的直接子組件
需要注意 $children 并不保證順序,也不是響應式的。如果你發(fā)現(xiàn)自己正在嘗試使用 $children 來進行數(shù)據(jù)綁定,考慮使用一個數(shù)組配合 v-for 來生成子組件,并且使用 Array 作為真正的來源。
i、vm.$slots:類型({ [name: string]: ?Array<VNode> }),用來訪問被 slot 分發(fā)的內(nèi)容。每個具名 slot 有其相應的屬性(例如:slot="foo" 中的內(nèi)容將會在 vm.$slots.foo 中被找到)。default 屬性包括了所有沒有被包含在具名 slot 中的節(jié)點。
k、vm.$refs:類型(Object),一個對象,其中包含了所有擁有 ref 注冊的子組件;
l、vm.$isServer:類型(boolean),當前Vue實例是否運行于服務器;
官網(wǎng)對應
1.5.5、箭頭函數(shù)
箭頭函數(shù)是ES6引入的一種語法糖,使得寫函數(shù)更加簡便,類似Lambda表達式,基本格式如下:
()=>{}
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue2實例</title>
</head>
<body>
<div id="app1">
</div>
<script type="text/javascript">
var m1=a=>a+1;
console.log(m1(100));
//類似
var m2=function(a){
return a+1;
}
console.log(m2(100));
var m3=(a,b)=>a+b;
console.log(m3(100,200));
var m4=(a,b)=>{a++; b++; return a+b;}; //如果方法體中有多個表達式,則需要大括號與return
console.log(m4(100,200));
</script>
</body>
</html>
結(jié)果:

二、生命周期 2.1、實例生命周期
每個 Vue 實例在被創(chuàng)建之前都要經(jīng)過一系列的初始化過程。例如需要設置數(shù)據(jù)監(jiān)聽、編譯模板、掛載實例到 DOM、在數(shù)據(jù)變化時更新 DOM 等。同時在這個過程中也會運行一些叫做生命周期鉤子的函數(shù),給予用戶機會在一些特定的場景下添加他們自己的代碼。
比如 created 鉤子可以用來在一個實例被創(chuàng)建之后執(zhí)行代碼:
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 實例
console.log('a is: ' + this.a)
}
})
// => "a is: 1"
也有一些其它的鉤子,在實例生命周期的不同場景下調(diào)用,如 mounted、updated、destroyed。鉤子的 this 指向調(diào)用它的 Vue 實例。
不要在選項屬性或回調(diào)上使用箭頭函數(shù),比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。因為箭頭函數(shù)是和父級上下文綁定在一起的,this 不會是如你所預期的 Vue 實例,經(jīng)常導致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之類的錯誤。
2.2、生命周期圖示
下圖說明了實例的生命周期。你不需要立馬弄明白所有的東西,不過隨著你的不斷學習和使用,它的參考價值會越來越高。

中文版:

1. beforeCreate
在實例初始化之后,數(shù)據(jù)觀測(data observer) 和 event/watcher 事件配置之前被調(diào)用。
2. created
實例已經(jīng)創(chuàng)建完成之后被調(diào)用。在這一步,實例已完成以下的配置:數(shù)據(jù)觀測(data observer),屬性和方法的運算, watch/event 事件回調(diào)。然而,掛載階段還沒開始,$el 屬性目前不可見。 可以在組件的這個期間請求數(shù)據(jù),如果是keep-alive組件會被緩存起來,生命周期不會再次觸發(fā),如果需要更新數(shù)據(jù)可以watch當前router變化,如果router是當前組件所在的router則請求數(shù)據(jù)。
methods : {
getData : function(id){
...
this.content = 'test';
}
},
created : function(){
this.getData(this.id);
}
...
watch : {
$route : function(){
if(this.$route.name == 'xxx'){
this.getData(this.id);
}
}
}
3. beforeMount
在掛載開始之前被調(diào)用:相關(guān)的 render 函數(shù)首次被調(diào)用。
4. mounted
vm.$el已掛載在文檔內(nèi),對已有dom節(jié)點的操作可以在這期間進行。
5. beforeUpdate
數(shù)據(jù)更新時調(diào)用,發(fā)生在虛擬 DOM 重新渲染和打補丁之前。
可以在這個鉤子中進一步地更改狀態(tài),這不會觸發(fā)附加的重渲染過程。
6.updated
由于數(shù)據(jù)更改導致的虛擬 DOM 重新渲染和打補丁,在這之后會調(diào)用該鉤子。
當這個鉤子被調(diào)用時,組件 DOM 已經(jīng)更新,所以你現(xiàn)在可以執(zhí)行依賴于 DOM 的操作。然而在大多數(shù)情況下,你應該避免在此期間更改狀態(tài),因為這可能會導致更新無限循環(huán)。
7.activated
keep-alive 組件激活時調(diào)用。
8.deactivated
keep-alive 組件停用時調(diào)用。
9.beforeDestroy
實例銷毀之前調(diào)用。在這一步,實例仍然完全可用。
10.destroyed
Vue 實例銷毀后調(diào)用。調(diào)用后,Vue 實例指示的所有東西都會解綁定,所有的事件監(jiān)聽器會被移除,所有的子實例也會被銷毀。
2.3、生命周期示例一
示例1:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue2生命周期</title>
</head>
<body>
<div id="app1">
<input v-model="msg" /> {{msg}}
</div>
<button type="button" onclick="destroy()">銷毀</button>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
//格式化輸出
console.log("示例:%c%s","background:red;color:#fff","vue2生命周期","開始了");
var app1 = new Vue({
el: "#app1",
data:{
msg:"vue"
},
beforeCreate:function(){
console.log("創(chuàng)建前:"+this.msg);
},
created:function(){
console.log("創(chuàng)建后:"+this.msg+","+this.$el);
},
beforeMount:function(){
console.log("掛載前:");
console.log(this.$el);
},
mounted:function(){
console.log("掛載后:");
console.log(this.$el);
},
beforeUpdate:function(){
console.log("實例更新前:");
console.log(this.msg);
console.log(this.$el);
},
updated:function(){
console.log("實例更新后:");
console.log(this.msg);
console.log(this.$el);
},
beforeDestroy:function(){
console.log("實例銷毀前:");
console.log(this.msg);
},
destroyed:function(){
console.log("實例銷毀后:");
console.log(this.msg);
}
});
function destroy(){
app1.$destroy();
}
</script>
</body>
</html>
初始化結(jié)果1:

修改msg的值為vue2后的結(jié)果:

執(zhí)行銷毀:

2.4、生命周期示例二
示例2:
<!DOCTYPE html>
<html>
<head>
<title>Vue2生命周期</title>
</head>
<body>
<div id="app">{{ message }}</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: "South IT College!"
},
beforeCreate: function() {
console.group('beforeCreate 創(chuàng)建前狀態(tài)===============》');
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //undefined
console.log("%c%s", "color:red", "message: " + this.message)
},
created: function() {
console.group('created 創(chuàng)建完畢狀態(tài)===============》');
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeMount: function() {
console.group('beforeMount 掛載前狀態(tài)===============》');
console.log("%c%s", "color:red", "el : " + (this.$el)); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
mounted: function() {
console.group('mounted 掛載結(jié)束狀態(tài)===============》');
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeUpdate: function() {
console.group('beforeUpdate 更新前狀態(tài)===============》');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
updated: function() {
console.group('updated 更新完成狀態(tài)===============》');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
beforeDestroy: function() {
console.group('beforeDestroy 銷毀前狀態(tài)===============》');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
destroyed: function() {
console.group('destroyed 銷毀完成狀態(tài)===============》');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message)
}
})
</script>
</body>
</html>
初始化結(jié)果:

更新message的值:

手動銷毀實例:

2.5、手動掛載與調(diào)用事件 2.5.1、手動掛載
vm.$mount( [elementOrSelector] ) 如果 Vue 實例在實例化時沒有收到 el 選項,則它處于“未掛載”狀態(tài),沒有關(guān)聯(lián)的 DOM 元素??梢允褂?vm.$mount() 手動地掛載一個未掛載的實例。
如果沒有提供 elementOrSelector 參數(shù),模板將被渲染為文檔之外的的元素,并且你必須使用原生 DOM API 把它插入文檔中。
這個方法返回實例自身,因而可以鏈式調(diào)用其它實例方法。
var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
})
// 創(chuàng)建并掛載到 #app (會替換 #app)
new MyComponent().$mount('#app')
// 同上
new MyComponent({ el: '#app' })
// 或者,在文檔之外渲染并且隨后掛載
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue2生命周期</title>
<style>
#app1 {
color: red;
}
#app2 {
color: blue;
}
</style>
</head>
<body>
<div id="app1">
</div>
<div id="app2">
</div>
<button type="button" onclick="loaddata1()">手動掛載1</button>
<button type="button" onclick="loaddata2()">手動掛載2</button>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app1 = new Vue({
template: "<h2>{{msg}}</h2>",
data: {
msg: "Hello Vue2!"
}
});
function loaddata1() {
app1.$mount("#app1");
document.getElementById("app1").appendChild(app1.$el);
}
function loaddata2() {
app1.$mount();
document.getElementById("app2").appendChild(app1.$el);
}
</script>
</body>
</html>
結(jié)果:

2.5.2、銷毀實例
vm.$destroy() 完全銷毀一個實例。清理它與其它實例的連接,解綁它的全部指令及事件監(jiān)聽器。
2.5.3、強制更新
vm.$forceUpdate() 迫使 Vue 實例重新渲染。注意它僅僅影響實例本身和插入插槽內(nèi)容的子組件,而不是所有子組件。

三、Vue腳手架(vue-cli)
單頁Web應用(single page web application,SPA),就是只有一張Web頁面的應用,是加載單個HTML 頁面并在用戶與應用程序交互時動態(tài)更新該頁面的Web應用程序。
提供一個官方命令行工具,可用于快速搭建大型單頁應用(SPA)。該工具為現(xiàn)代化的前端開發(fā)工作流提供了開箱即用的構(gòu)建配置。只需幾分鐘即可創(chuàng)建并啟動一個帶熱重載、保存時靜態(tài)檢查以及可用于生產(chǎn)環(huán)境的構(gòu)建配置的項目:
# 全局安裝 vue-cli $ npm install --global vue-cli # 創(chuàng)建一個基于 webpack 模板的新項目 $ vue init webpack my-project # 安裝依賴,走你 $ cd my-project $ npm install $ npm run dev
注意:CLI 工具假定用戶對 Node.js 和相關(guān)構(gòu)建工具有一定程度的了解。如果你是新手,我們強烈建議先在不用構(gòu)建工具的情況下通讀指南,在熟悉 Vue 本身之后再使用 CLI。
3.1、環(huán)境搭建 3.1.1、安裝node.js
從n ode.js官網(wǎng) 下載并安裝node,安裝過程很簡單,一路“下一步”就可以了。安裝完成之后,打開命令行工具(win+r,然后輸入cmd),輸入 node -v,如下圖,如果出現(xiàn)相應的版本號,則說明安裝成功。

如果安裝不成功,可以直接把安裝包修改成壓縮包,解壓后配置環(huán)境變量也可以,就成了綠色版。

這里需要說明下,因為在官網(wǎng)下載安裝node.js后,就已經(jīng)自帶npm(包管理工具)了,另需要注意的是npm的版本最好是3.x.x以上,以免對后續(xù)產(chǎn)生影響。
注意版本不能太低,如果您已經(jīng)安裝了低版本的node可以使用npm直接更新。
3.1.2、修改npm為淘寶鏡像
因為npm的倉庫有許多在國外,訪問的速度較慢,建議修改成cnpm,換成taobao的鏡像。
打開命令行工具,復制如下配置:
npm install -g cnpm --registry=https://registry.npm.taobao.org
安裝這里是因為我們用的npm的服務器是外國,有的時候我們安裝“依賴”的時候很很慢很慢超級慢,所以就用這個cnpm來安裝我們說需要的“依賴”。安裝完成之后輸入 cnpm -v,如下圖,如果出現(xiàn)相應的版本號,則說明安裝成功。

版本號:

3.1.3、安裝webpack
安裝webpack,打開命令行工具輸入:
npm install webpack -g

安裝完成之后輸入
webpack -v
如下圖,如果出現(xiàn)相應的版本號,則說明安裝成功。

3.1.4、安裝vue-cli腳手架構(gòu)建工具
打開命令行工具輸入:
cnpm install vue-cli -g
安裝完成之后輸入 vue -V(注意這里是大寫的“V”),如下圖,如果出現(xiàn)相應的版本號,則說明安裝成功。

3.2、構(gòu)建項目
1)、在硬盤上找一個文件夾放工程用的。這里有兩種方式指定到相關(guān)目錄:
①cd 目錄路徑
②如果以安裝git的,在相關(guān)目錄右鍵選擇Git Bash Here
2)、安裝vue腳手架輸入:vue init webpack projectName,注意這里的“projectName” 是項目的名稱可以說是隨便的起名,但是“ 不能用中文 ”。
提示選擇項:
$ vue init webpack exprice --------------------- 這個是那個安裝vue腳手架的命令 This will install Vue 2.x version of the template. ---------------------這里說明將要創(chuàng)建一個vue 2.x版本的項目 For Vue 1.x use: vue init webpack#1.0 exprice ? Project name (exprice) ---------------------項目名稱 ? Project name exprice ? Project description (A Vue.js project) ---------------------項目描述 ? Project description A Vue.js project ? Author Datura --------------------- 項目創(chuàng)建者 ? Author Datura ? Vue build (Use arrow keys) ? Vue build standalone ? Install vue-router? (Y/n) --------------------- 是否安裝Vue路由,也就是以后是spa(但頁面應用需要的模塊) ? Install vue-router? Yes ? Use ESLint to lint your code? (Y/n) n ---------------------是否啟用eslint檢測規(guī)則,這里個人建議選no ? Use ESLint to lint your code? No ? Setup unit tests with Karma + Mocha? (Y/n) ? Setup unit tests with Karma + Mocha? Yes ? Setup e2e tests with Nightwatch? (Y/n) ? Setup e2e tests with Nightwatch? Yes vue-cli · Generated "exprice". To get started: --------------------- 這里說明如何啟動這個服務 cd exprice npm install npm run dev

3)、cd 命令進入創(chuàng)建的工程目錄,首先cd projectName;
4)、安裝項目依賴:npm install,因為自動構(gòu)建過程中已存在package.json文件,所以這里直接安裝依賴就行。不要從國內(nèi)鏡像cnpm安裝(會導致后面缺了很多依賴庫),但是但是如果真的安裝“個把”小時也沒成功那就用:cnpm install 吧
5)、安裝 vue 路由模塊 vue-router 和網(wǎng)絡請求模塊 vue-resource,輸入:cnpm install vue-router vue-resource --save。

目錄:
|-- build // 項目構(gòu)建(webpack)相關(guān)代碼 | |-- build.js // 生產(chǎn)環(huán)境構(gòu)建代碼 | |-- check-version.js // 檢查node、npm等版本 | |-- dev-client.js // 熱重載相關(guān) | |-- dev-server.js // 構(gòu)建本地服務器 | |-- utils.js // 構(gòu)建工具相關(guān) | |-- webpack.base.conf.js // webpack基礎(chǔ)配置 | |-- webpack.dev.conf.js // webpack開發(fā)環(huán)境配置 | |-- webpack.prod.conf.js // webpack生產(chǎn)環(huán)境配置 |-- config // 項目開發(fā)環(huán)境配置 | |-- dev.env.js // 開發(fā)環(huán)境變量 | |-- index.js // 項目一些配置變量 | |-- prod.env.js // 生產(chǎn)環(huán)境變量 | |-- test.env.js // 測試環(huán)境變量 |-- src // 源碼目錄 | |-- components // vue公共組件 | |-- store // vuex的狀態(tài)管理 | |-- App.vue // 頁面入口文件 | |-- main.js // 程序入口文件,加載各種公共組件 |-- static // 靜態(tài)文件,比如一些圖片,json數(shù)據(jù)等 | |-- data // 群聊分析得到的數(shù)據(jù)用于數(shù)據(jù)可視化 |-- .babelrc // ES6語法編譯配置 |-- .editorconfig // 定義代碼格式 |-- .gitignore // git上傳需要忽略的文件格式 |-- README.md // 項目說明 |-- favicon.ico |-- index.html // 入口頁面 |-- package.json // 項目基本信息
3.3、運行項目
6)、啟動項目,輸入:npm run dev。服務啟動成功后瀏覽器會默認打開一個“歡迎頁面”,如下圖:

編譯成功后可以直接在瀏覽器中查看項目:

3.4、Vue-cli HelloWorld
了解了默認的模板內(nèi)容,我們可以開始定義自己的vue程序了,這里寫一個簡單的HelloWorld,在src目錄下創(chuàng)建一個Hi.vue文件,內(nèi)容如下:
<template>
<div id="app1">
<input v-model="msg" v-on:click="sayhi"/>
<p>
<h2>{{msg}}</h2>
</p>
</div>
</template>
<script>
export default {
name: 'Hi',
data() {
return {
msg: 'My First vue-cli app!'
}
},
methods:{
sayhi:function(){
alert(this.msg);
}
}
}
</script>
<style>
#app1 {
font-family: "microsoft yahei";
color: dodgerblue;
font-size: 20px;
}
</style>
修改main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './Hi'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
運行結(jié)果:

四、示例下載
https://git.coding.net/zhangguo5/vue2.git
五、視頻
https://www.bilibili.com/video/av17503637/
六、作業(yè)
1、請定義任意一個Vue實例,觸發(fā)Vue實例中的8個事件,將結(jié)果輸出到控制臺,要求可以觀察到數(shù)據(jù)初始化與掛載情況。
2、請使用vue2+bootstrap完成如下功能:
要求如下:
a)、實現(xiàn)添加功能
b)、實現(xiàn)刪除功能
c)、實現(xiàn)編輯功能,增加按鈕
d)、實現(xiàn)隔行換色
e)、實現(xiàn)按年齡排序

參考 :



總結(jié)
以上所述是小編給大家介紹的Vue的實例、生命周期與Vue腳手架(vue-cli)實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Vue中以HTML形式顯示內(nèi)容并動態(tài)生成HTML代碼的方法
有的時候我們想在vue中直接顯示一個html的網(wǎng)頁,如果用富文本方式,那么內(nèi)容就會太多,那么怎么處理呢?這篇文章主要給大家介紹了關(guān)于Vue中如何以HTML形式顯示內(nèi)容并動態(tài)生成HTML代碼的相關(guān)資料,需要的朋友可以參考下2024-03-03
Vue?nextTick獲取更新后的DOM的實現(xiàn)
本文主要介紹了Vue?nextTick獲取更新后的DOM的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
element中Steps步驟條和Tabs標簽頁關(guān)聯(lián)的解決
這篇文章主要介紹了element中Steps步驟條和Tabs標簽頁關(guān)聯(lián)的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-12-12
Ant design vue中的聯(lián)動選擇取消操作
這篇文章主要介紹了Ant design vue中的聯(lián)動選擇取消操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
cesium開發(fā)之如何在vue項目中使用cesium,使用離線地圖資源
這篇文章主要介紹了cesium開發(fā)之如何在vue項目中使用cesium,使用離線地圖資源問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04

