溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

發(fā)布時(shí)間:2020-09-29 00:08:06 來(lái)源:腳本之家 閱讀:368 作者:張果 欄目:web開(kāi)發(fā)

一、Vue的實(shí)例

1.1、創(chuàng)建一個(gè) Vue 的實(shí)例

每個(gè) Vue 應(yīng)用都是通過(guò) Vue 函數(shù)創(chuàng)建一個(gè)新的 Vue 實(shí)例開(kāi)始的:

var vm = new Vue({// 選項(xiàng)})

雖然沒(méi)有完全遵循 MVVM 模型,Vue 的設(shè)計(jì)無(wú)疑受到了它的啟發(fā)。因此在文檔中經(jīng)常會(huì)使用 vm (ViewModel 的簡(jiǎn)稱) 這個(gè)變量名表示 Vue 實(shí)例。

1、vue.js就是一個(gè)構(gòu)造器,通過(guò)構(gòu)造器Vue來(lái)實(shí)例化一個(gè)對(duì)象;例如:var vm = new Vue({});

2、實(shí)例化Vue時(shí),需要傳入一個(gè)參數(shù)(選項(xiàng)對(duì)象);

3、參數(shù):選項(xiàng)對(duì)象可以包含,數(shù)據(jù)(data)、掛載元素(el)、方法(methods)、模版(template)、生命周期函數(shù)等等;

4、擴(kuò)展構(gòu)造器Vue,從而用預(yù)定義選項(xiàng)創(chuàng)建可復(fù)用的組件構(gòu)造器,所有組件都是被擴(kuò)展的Vue的實(shí)例,使用Vue.extend({})來(lái)擴(kuò)展;

注意:盡管可以命令式地創(chuàng)建擴(kuò)展實(shí)例,不過(guò)在多數(shù)情況下建議將組件構(gòu)造器注冊(cè)為一個(gè)自定義元素,然后聲明式地用在模板中。

當(dāng)創(chuàng)建一個(gè) Vue 實(shí)例時(shí),你可以傳入一個(gè)選項(xiàng)對(duì)象。這篇教程主要描述的就是如何使用這些選項(xiàng)來(lái)創(chuàng)建你想要的行為。作為參考,你也可以在 API 文檔 中瀏覽完整的選項(xiàng)列表。

一個(gè) Vue 應(yīng)用由一個(gè)通過(guò) new Vue 創(chuàng)建的根 Vue 實(shí)例,以及可選的嵌套的、可復(fù)用的組件樹(shù)組成。舉個(gè)例子,一個(gè) todo 應(yīng)用的組件樹(shù)可以是這樣的:

Root Instance
└─ TodoList
├─ TodoItem
│ ├─ DeleteTodoButton
│ └─ EditTodoButton
└─ TodoListFooter
├─ ClearTodosButton
└─ TodoListStatistics

我們會(huì)在稍后的組件系統(tǒng)章節(jié)具體展開(kāi)。不過(guò)現(xiàn)在,你只需要明白所有的 Vue 組件都是 Vue 實(shí)例,并且接受相同的選項(xiàng)對(duì)象即可 (一些根實(shí)例特有的選項(xiàng)除外)。

1.2、數(shù)據(jù)與方法

當(dāng)一個(gè) Vue 實(shí)例被創(chuàng)建時(shí),它向 Vue 的響應(yīng)式系統(tǒng)中加入了其 data 對(duì)象中能找到的所有的屬性。當(dāng)這些屬性的值發(fā)生改變時(shí),視圖將會(huì)產(chǎn)生“響應(yīng)”,即匹配更新為新的值。

// 我們的數(shù)據(jù)對(duì)象
var data = { a: 1 }
// 該對(duì)象被加入到一個(gè) Vue 實(shí)例中
var vm = new Vue({
 data: data
})
// 他們引用相同的對(duì)象!
vm.a === data.a // => true
// 設(shè)置屬性也會(huì)影響到原始數(shù)據(jù)
vm.a = 2
data.a // => 2
// ... 反之亦然
data.a = 3
vm.a // => 3

當(dāng)這些數(shù)據(jù)改變時(shí),視圖會(huì)進(jìn)行重渲染。 值得注意的是只有當(dāng)實(shí)例被創(chuàng)建時(shí) data 中存在的屬性是響應(yīng)式的 。也就是說(shuō)如果你添加一個(gè)新的屬性,像:

vm.b = 'hi'

那么對(duì) b 的改動(dòng)將不會(huì)觸發(fā)任何視圖的更新。

示例:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>vue2實(shí)例</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}
  //實(shí)例
  var vm = new Vue({
  el: "#app1",
  data:data,
  updated:function(){
   console.log("實(shí)例被更新了!");
  }
  });
 </script>
 </body>
</html>

結(jié)果:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

如果你知道你會(huì)在晚些時(shí)候需要一個(gè)屬性,但是一開(kāi)始它為空或不存在,那么你僅需要設(shè)置一些初始值。比如:

data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null
}

除了 data 屬性,Vue 實(shí)例暴露了一些有用的實(shí)例屬性與方法。它們都有前綴 $,以便與用戶定義的屬性區(qū)分開(kāi)來(lái)。例如:

var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一個(gè)實(shí)例方法
vm.$watch('a', function (newValue, oldValue) {
// 這個(gè)回調(diào)將在 `vm.a` 改變后調(diào)用
})

在未來(lái),你可以在 API 參考查閱到完整的實(shí)例屬性和方法的列表 。

1.3、實(shí)例屬性

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

解釋

vm._uid // 自增的id
vm._isVue // 標(biāo)示是vue對(duì)象,避免被observe
vm._renderProxy // Proxy代理對(duì)象
vm._self // 當(dāng)前vm實(shí)例
vm.$parent // 用于自定義子組件中,指向父組件的實(shí)例
vm.$root // 指向根vm實(shí)例
vm.$children // 當(dāng)前組件的子組件實(shí)例數(shù)組
vm.$refs 
vm._watcher = null
vm._inactive = null
vm._directInactive = false
vm._isMounted = false // 標(biāo)識(shí)是否已掛載
vm._isDestroyed = false // 標(biāo)識(shí)是否已銷毀
vm._isBeingDestroyed = false // 標(biāo)識(shí)是否正在銷毀
vm._events // 當(dāng)前元素上綁定的自定義事件
vm._hasHookEvent // 標(biāo)示是否有hook:開(kāi)頭的事件
vm.$vnode // 當(dāng)前自定義組件在父組件中的vnode,等同于vm.$options._parentVnode
vm._vnode // 當(dāng)前組件的vnode
vm._staticTrees // 當(dāng)前組件模板內(nèi)分析出的靜態(tài)內(nèi)容的render函數(shù)數(shù)組
vm.$el // 當(dāng)前組件對(duì)應(yīng)的根元素
vm.$slots // 定義在父組件中的slots,是個(gè)對(duì)象鍵為name,值為響應(yīng)的數(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í),傳入的參數(shù)
vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
vm._props // 被observe的存儲(chǔ)props數(shù)據(jù)的對(duì)象
vm._data // 被observe的存儲(chǔ)data數(shù)據(jù)的對(duì)象
vm._computedWatchers // 保存計(jì)算屬性創(chuàng)建的watcher對(duì)象

1.4、實(shí)例方法

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解 

1.5、實(shí)例參數(shù)vm.$options

vm.$options其實(shí)也就是我們new Vue(options)options這個(gè)選項(xiàng)對(duì)象可傳入的屬性

declare type ComponentOptions = {
 // data
 data: Object | Function | void; // 傳入的data數(shù)據(jù)
 props?: { [key: string]: PropOptions }; // props傳入的數(shù)據(jù)
 propsData?: ?Object; // 對(duì)于自定義組件,父級(jí)通過(guò)`props`傳過(guò)來(lái)的數(shù)據(jù)
 computed?: { // 傳入的計(jì)算屬性
 [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 }; // 過(guò)濾器
 // 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; // 父組件實(shí)例
 mixins?: Array<Object>; // mixins傳入的數(shù)據(jù)
 name?: string; // 當(dāng)前的組件名
 extends?: Class<Component> | Object; // extends傳入的數(shù)據(jù)
 delimiters?: [string, string]; // 模板分隔符
 // 私有屬性,均為內(nèi)部創(chuàng)建自定義組件的對(duì)象時(shí)使用
 _isComponent?: true; // 是否是組件
 _propKeys?: Array<string>; // props傳入對(duì)象的鍵數(shù)組
 _parentVnode?: VNode; // 當(dāng)前組件,在父組件中的VNode對(duì)象
 _parentListeners?: ?Object; // 當(dāng)前組件,在父組件上綁定的事件
 _renderChildren?: ?Array<VNode>; // 父組件中定義在當(dāng)前元素內(nèi)的子元素的VNode數(shù)組(slot)
 _componentTag: ?string; // 自定義標(biāo)簽名
 _scopeId: ?string;
 _base: Class<Component>; // Vue
 _parentElm: ?Node; // 當(dāng)前自定義組件的父級(jí)dom結(jié)點(diǎn)
 _refElm: ?Node; // 當(dāng)前元素的nextSlibing元素,即當(dāng)前dom要插入到_parentElm結(jié)點(diǎn)下的_refElm前
}

1.5.1、computed計(jì)算屬性

在模板中綁定表達(dá)式是非常便利的,但是它們實(shí)際上只用于簡(jiǎn)單的操作。在模板中放入太多的邏輯會(huì)讓模板過(guò)重且難以維護(hù)。例如:

<span>{{msg.split('').reverse().join('')}}</span>

使用計(jì)算屬性定義成一個(gè)方法可以復(fù)用且模板會(huì)更加簡(jiǎn)潔:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>vue2實(shí)例</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é)果:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

注意:

1、computed中定義的方法只允許當(dāng)著屬性用,不能帶參數(shù),這限制它的復(fù)用性。

2、當(dāng)方法中的屬性發(fā)生變化時(shí)方法將重新調(diào)用

3、不應(yīng)該使用箭頭函數(shù)來(lái)定義計(jì)算屬性函數(shù)

4、 computed計(jì)算屬性可以對(duì)屬性進(jìn)行緩存的,計(jì)算屬性只有當(dāng)該屬性發(fā)生變化的時(shí)候才會(huì)重新計(jì)算值

5、如果一個(gè)屬性不能完成需要的功能時(shí)可以考慮轉(zhuǎn)成計(jì)算

1.5.2、watch計(jì)算屬性

一個(gè)對(duì)象,鍵是需要觀察的表達(dá)式,值是對(duì)應(yīng)回調(diào)函數(shù)。值也可以是方法名,或者包含選項(xiàng)的對(duì)象。Vue 實(shí)例將會(huì)在實(shí)例化時(shí)調(diào)用 $watch(),遍歷 watch 對(duì)象的每一個(gè)屬性。

示例:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>vue2實(shí)例</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" />{ntzjxxb}<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',
   //對(duì)象,深度監(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 //設(shè)置初始值時(shí)也將調(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é)果:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

注意:不應(yīng)該使用箭頭函數(shù)來(lái)定義 watcher 函數(shù)、對(duì)象類型時(shí)并非深拷貝的,只是引用。

1.5.3、方法methods

methods 將被混入到 Vue 實(shí)例中??梢灾苯油ㄟ^(guò) VM 實(shí)例訪問(wèn)這些方法,或者在指令表達(dá)式中使用。方法中的 this 自動(dòng)綁定為 Vue 實(shí)例。

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實(shí)例</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é)果:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

注意,不應(yīng)該使用箭頭函數(shù)來(lái)定義 method 函數(shù) (例如 plus: () => this.a++)。理由是箭頭函數(shù)綁定了父級(jí)作用域的上下文,所以 this 將不會(huì)按照期望指向 Vue 實(shí)例,this.a 將是 undefined。

1.5.4、小結(jié)

computed是計(jì)算屬性的,methods是計(jì)算方法的,最主要的區(qū)別是 computed計(jì)算屬性可以對(duì)

屬性進(jìn)行緩存的,計(jì)算屬性只有當(dāng)該屬性發(fā)生變化的時(shí)候才會(huì)重新計(jì)算值,只要值沒(méi)有改變,它是不會(huì)重新渲染的,但是methods方法不同,每次調(diào)用該方法的時(shí)候,都會(huì)重新執(zhí)行的。

1、每個(gè)Vue的實(shí)例都會(huì)代理其data對(duì)象里的所有屬性,被代理的屬性是響應(yīng)的;

2、如果實(shí)例創(chuàng)建之后添加新的屬性到實(shí)例上,不會(huì)觸發(fā)視圖更新;

3、不要在實(shí)例屬性或者回調(diào)函數(shù)中(如 vm.$watch('a', newVal => this.myMethod()))使用箭頭函數(shù)。因?yàn)榧^函數(shù)綁定父上下文,所以 this 不會(huì)像預(yù)想的一樣是 Vue 實(shí)例,而是 this.myMethod 未被定義。

4、Vue實(shí)例暴露了一些有用的實(shí)例屬性和方法,帶有前綴 $ 便于與代理的data區(qū)分

a、vm.$el:類型(HTMLElement)掛載元素,Vue實(shí)例的DOM根元素;

b、vm.$data:類型(Object),Vue實(shí)例觀察的數(shù)據(jù)對(duì)象

c、vm.$props:類型(Object),屬性

d、vm.$options:類型(Object),用于當(dāng)前Vue實(shí)例的初始化選項(xiàng),在選項(xiàng)中需要包含自定義屬性的時(shí)候很有用。

e、vm.$parent:類型(Vue實(shí)例),父實(shí)例。

f、vm.$root:類型(Vue實(shí)例),當(dāng)前組件樹(shù)的根Vue實(shí)例,如果沒(méi)有父實(shí)例,就是實(shí)例本身。

h、vm.$children:類型(Array(Vue實(shí)例)),當(dāng)前實(shí)例的直接子組件

需要注意 $children 并不保證順序,也不是響應(yīng)式的。如果你發(fā)現(xiàn)自己正在嘗試使用 $children 來(lái)進(jìn)行數(shù)據(jù)綁定,考慮使用一個(gè)數(shù)組配合 v-for 來(lái)生成子組件,并且使用 Array 作為真正的來(lái)源。

i、vm.$slots:類型({ [name: string]: ?Array<VNode> }),用來(lái)訪問(wèn)被 slot 分發(fā)的內(nèi)容。每個(gè)具名 slot 有其相應(yīng)的屬性(例如:slot="foo" 中的內(nèi)容將會(huì)在 vm.$slots.foo 中被找到)。default 屬性包括了所有沒(méi)有被包含在具名 slot 中的節(jié)點(diǎn)。

k、vm.$refs:類型(Object),一個(gè)對(duì)象,其中包含了所有擁有 ref 注冊(cè)的子組件;

l、vm.$isServer:類型(boolean),當(dāng)前Vue實(shí)例是否運(yùn)行于服務(wù)器;

官網(wǎng)對(duì)應(yīng)

1.5.5、箭頭函數(shù)

箭頭函數(shù)是ES6引入的一種語(yǔ)法糖,使得寫(xiě)函數(shù)更加簡(jiǎn)便,類似Lambda表達(dá)式,基本格式如下:

()=>{}

示例:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>vue2實(shí)例</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;}; //如果方法體中有多個(gè)表達(dá)式,則需要大括號(hào)與return
  console.log(m4(100,200));
 </script>
 </body>
</html>

結(jié)果:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

二、生命周期 2.1、實(shí)例生命周期

每個(gè) Vue 實(shí)例在被創(chuàng)建之前都要經(jīng)過(guò)一系列的初始化過(guò)程。例如需要設(shè)置數(shù)據(jù)監(jiān)聽(tīng)、編譯模板、掛載實(shí)例到 DOM、在數(shù)據(jù)變化時(shí)更新 DOM 等。同時(shí)在這個(gè)過(guò)程中也會(huì)運(yùn)行一些叫做生命周期鉤子的函數(shù),給予用戶機(jī)會(huì)在一些特定的場(chǎng)景下添加他們自己的代碼。

比如 created 鉤子可以用來(lái)在一個(gè)實(shí)例被創(chuàng)建之后執(zhí)行代碼:

new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 實(shí)例
console.log('a is: ' + this.a)
}
})
// => "a is: 1"

也有一些其它的鉤子,在實(shí)例生命周期的不同場(chǎng)景下調(diào)用,如 mounted、updated、destroyed。鉤子的 this 指向調(diào)用它的 Vue 實(shí)例。

不要在選項(xiàng)屬性或回調(diào)上使用箭頭函數(shù),比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。因?yàn)榧^函數(shù)是和父級(jí)上下文綁定在一起的,this 不會(huì)是如你所預(yù)期的 Vue 實(shí)例,經(jīng)常導(dǎo)致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之類的錯(cuò)誤。

2.2、生命周期圖示

下圖說(shuō)明了實(shí)例的生命周期。你不需要立馬弄明白所有的東西,不過(guò)隨著你的不斷學(xué)習(xí)和使用,它的參考價(jià)值會(huì)越來(lái)越高。

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

中文版:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

1. beforeCreate

在實(shí)例初始化之后,數(shù)據(jù)觀測(cè)(data observer) 和 event/watcher 事件配置之前被調(diào)用。

2. created

實(shí)例已經(jīng)創(chuàng)建完成之后被調(diào)用。在這一步,實(shí)例已完成以下的配置:數(shù)據(jù)觀測(cè)(data observer),屬性和方法的運(yùn)算, watch/event 事件回調(diào)。然而,掛載階段還沒(méi)開(kāi)始,$el 屬性目前不可見(jiàn)。 可以在組件的這個(gè)期間請(qǐng)求數(shù)據(jù),如果是keep-alive組件會(huì)被緩存起來(lái),生命周期不會(huì)再次觸發(fā),如果需要更新數(shù)據(jù)可以watch當(dāng)前router變化,如果router是當(dāng)前組件所在的router則請(qǐng)求數(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

在掛載開(kāi)始之前被調(diào)用:相關(guān)的 render 函數(shù)首次被調(diào)用。

4. mounted

vm.$el已掛載在文檔內(nèi),對(duì)已有dom節(jié)點(diǎn)的操作可以在這期間進(jìn)行。

5. beforeUpdate

數(shù)據(jù)更新時(shí)調(diào)用,發(fā)生在虛擬 DOM 重新渲染和打補(bǔ)丁之前。

可以在這個(gè)鉤子中進(jìn)一步地更改狀態(tài),這不會(huì)觸發(fā)附加的重渲染過(guò)程。

6.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)致更新無(wú)限循環(huán)。

7.activated

keep-alive 組件激活時(shí)調(diào)用。

8.deactivated

keep-alive 組件停用時(shí)調(diào)用。

9.beforeDestroy

實(shí)例銷毀之前調(diào)用。在這一步,實(shí)例仍然完全可用。

10.destroyed

Vue 實(shí)例銷毀后調(diào)用。調(diào)用后,Vue 實(shí)例指示的所有東西都會(huì)解綁定,所有的事件監(jiān)聽(tīng)器會(huì)被移除,所有的子實(shí)例也會(huì)被銷毀。

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生命周期","開(kāi)始了");
  
  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("實(shí)例更新前:");
   console.log(this.msg);
   console.log(this.$el);
  },
  updated:function(){
   console.log("實(shí)例更新后:");
   console.log(this.msg);
   console.log(this.$el);
  },
  beforeDestroy:function(){
   console.log("實(shí)例銷毀前:");
   console.log(this.msg);     
  },
  destroyed:function(){
   console.log("實(shí)例銷毀后:");
   console.log(this.msg);
  }
  });
  
  function destroy(){
  app1.$destroy();
  }
 </script>
 </body>
</html>

初始化結(jié)果1:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

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

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

執(zhí)行銷毀:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

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é)果:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

更新message的值:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

手動(dòng)銷毀實(shí)例:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

2.5、手動(dòng)掛載與調(diào)用事件 2.5.1、手動(dòng)掛載

vm.$mount( [elementOrSelector] ) 如果 Vue 實(shí)例在實(shí)例化時(shí)沒(méi)有收到 el 選項(xiàng),則它處于“未掛載”狀態(tài),沒(méi)有關(guān)聯(lián)的 DOM 元素??梢允褂?vm.$mount() 手動(dòng)地掛載一個(gè)未掛載的實(shí)例。

如果沒(méi)有提供 elementOrSelector 參數(shù),模板將被渲染為文檔之外的的元素,并且你必須使用原生 DOM API 把它插入文檔中。

這個(gè)方法返回實(shí)例自身,因而可以鏈?zhǔn)秸{(diào)用其它實(shí)例方法。

var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
})
// 創(chuàng)建并掛載到 #app (會(huì)替換 #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()">手動(dòng)掛載1</button>
 <button type="button" onclick="loaddata2()">手動(dòng)掛載2</button>
 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
 <script type="text/javascript">
  var app1 = new Vue({
  template: "<h3>{{msg}}</h3>",
  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é)果:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

2.5.2、銷毀實(shí)例

vm.$destroy() 完全銷毀一個(gè)實(shí)例。清理它與其它實(shí)例的連接,解綁它的全部指令及事件監(jiān)聽(tīng)器。

2.5.3、強(qiáng)制更新

vm.$forceUpdate() 迫使 Vue 實(shí)例重新渲染。注意它僅僅影響實(shí)例本身和插入插槽內(nèi)容的子組件,而不是所有子組件。

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

三、Vue腳手架(vue-cli)

單頁(yè)Web應(yīng)用(single page web application,SPA),就是只有一張Web頁(yè)面的應(yīng)用,是加載單個(gè)HTML 頁(yè)面并在用戶與應(yīng)用程序交互時(shí)動(dòng)態(tài)更新該頁(yè)面的Web應(yīng)用程序。

提供一個(gè)官方命令行工具,可用于快速搭建大型單頁(yè)應(yīng)用(SPA)。該工具為現(xiàn)代化的前端開(kāi)發(fā)工作流提供了開(kāi)箱即用的構(gòu)建配置。只需幾分鐘即可創(chuàng)建并啟動(dòng)一個(gè)帶熱重載、保存時(shí)靜態(tài)檢查以及可用于生產(chǎn)環(huán)境的構(gòu)建配置的項(xiàng)目:

# 全局安裝 vue-cli
$ npm install --global vue-cli
# 創(chuàng)建一個(gè)基于 webpack 模板的新項(xiàng)目
$ vue init webpack my-project
# 安裝依賴,走你
$ cd my-project
$ npm install
$ npm run dev

注意:CLI 工具假定用戶對(duì) Node.js 和相關(guān)構(gòu)建工具有一定程度的了解。如果你是新手,我們強(qiáng)烈建議先在不用構(gòu)建工具的情況下通讀指南,在熟悉 Vue 本身之后再使用 CLI。

3.1、環(huán)境搭建 3.1.1、安裝node.js

從n ode.js官網(wǎng) 下載并安裝node,安裝過(guò)程很簡(jiǎn)單,一路“下一步”就可以了。安裝完成之后,打開(kāi)命令行工具(win+r,然后輸入cmd),輸入 node -v,如下圖,如果出現(xiàn)相應(yīng)的版本號(hào),則說(shuō)明安裝成功。

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

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

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

這里需要說(shuō)明下,因?yàn)樵诠倬W(wǎng)下載安裝node.js后,就已經(jīng)自帶npm(包管理工具)了,另需要注意的是npm的版本最好是3.x.x以上,以免對(duì)后續(xù)產(chǎn)生影響。

注意版本不能太低,如果您已經(jīng)安裝了低版本的node可以使用npm直接更新。

3.1.2、修改npm為淘寶鏡像

因?yàn)閚pm的倉(cāng)庫(kù)有許多在國(guó)外,訪問(wèn)的速度較慢,建議修改成cnpm,換成taobao的鏡像。

打開(kāi)命令行工具,復(fù)制如下配置:

npm install -g cnpm --registry=https://registry.npm.taobao.org

安裝這里是因?yàn)槲覀冇玫膎pm的服務(wù)器是外國(guó),有的時(shí)候我們安裝“依賴”的時(shí)候很很慢很慢超級(jí)慢,所以就用這個(gè)cnpm來(lái)安裝我們說(shuō)需要的“依賴”。安裝完成之后輸入 cnpm -v,如下圖,如果出現(xiàn)相應(yīng)的版本號(hào),則說(shuō)明安裝成功。

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

版本號(hào):

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

3.1.3、安裝webpack

安裝webpack,打開(kāi)命令行工具輸入:

npm install webpack -g

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

安裝完成之后輸入

webpack -v

如下圖,如果出現(xiàn)相應(yīng)的版本號(hào),則說(shuō)明安裝成功。

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

3.1.4、安裝vue-cli腳手架構(gòu)建工具

打開(kāi)命令行工具輸入:

cnpm install vue-cli -g

安裝完成之后輸入 vue -V(注意這里是大寫(xiě)的“V”),如下圖,如果出現(xiàn)相應(yīng)的版本號(hào),則說(shuō)明安裝成功。

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

3.2、構(gòu)建項(xiàng)目

1)、在硬盤(pán)上找一個(gè)文件夾放工程用的。這里有兩種方式指定到相關(guān)目錄:

①cd 目錄路徑

②如果以安裝git的,在相關(guān)目錄右鍵選擇Git Bash Here

2)、安裝vue腳手架輸入:vue init webpack projectName,注意這里的“projectName” 是項(xiàng)目的名稱可以說(shuō)是隨便的起名,但是“ 不能用中文 ”。

提示選擇項(xiàng):

$ vue init webpack exprice --------------------- 這個(gè)是那個(gè)安裝vue腳手架的命令
This will install Vue 2.x version of the template. ---------------------這里說(shuō)明將要?jiǎng)?chuàng)建一個(gè)vue 2.x版本的項(xiàng)目
For Vue 1.x use: vue init webpack#1.0 exprice
? Project name (exprice) ---------------------項(xiàng)目名稱
? Project name exprice
? Project description (A Vue.js project) ---------------------項(xiàng)目描述
? Project description A Vue.js project
? Author Datura --------------------- 項(xiàng)目創(chuàng)建者
? Author Datura
? Vue build (Use arrow keys)
? Vue build standalone
? Install vue-router? (Y/n) --------------------- 是否安裝Vue路由,也就是以后是spa(但頁(yè)面應(yīng)用需要的模塊)
? Install vue-router? Yes
? Use ESLint to lint your code? (Y/n) n ---------------------是否啟用eslint檢測(cè)規(guī)則,這里個(gè)人建議選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: --------------------- 這里說(shuō)明如何啟動(dòng)這個(gè)服務(wù)
cd exprice
npm install
npm run dev

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

3)、cd 命令進(jìn)入創(chuàng)建的工程目錄,首先cd projectName;

4)、安裝項(xiàng)目依賴:npm install,因?yàn)樽詣?dòng)構(gòu)建過(guò)程中已存在package.json文件,所以這里直接安裝依賴就行。不要從國(guó)內(nèi)鏡像cnpm安裝(會(huì)導(dǎo)致后面缺了很多依賴庫(kù)),但是但是如果真的安裝“個(gè)把”小時(shí)也沒(méi)成功那就用:cnpm install 吧

5)、安裝 vue 路由模塊 vue-router 和網(wǎng)絡(luò)請(qǐng)求模塊 vue-resource,輸入:cnpm install vue-router vue-resource --save。

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

目錄:

|-- build       // 項(xiàng)目構(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)建本地服務(wù)器
| |-- utils.js      // 構(gòu)建工具相關(guān)
| |-- webpack.base.conf.js   // webpack基礎(chǔ)配置
| |-- webpack.dev.conf.js   // webpack開(kāi)發(fā)環(huán)境配置
| |-- webpack.prod.conf.js   // webpack生產(chǎn)環(huán)境配置
|-- config       // 項(xiàng)目開(kāi)發(fā)環(huán)境配置
| |-- dev.env.js     // 開(kāi)發(fā)環(huán)境變量
| |-- index.js      // 項(xiàng)目一些配置變量
| |-- prod.env.js     // 生產(chǎn)環(huán)境變量
| |-- test.env.js     // 測(cè)試環(huán)境變量
|-- src        // 源碼目錄
| |-- components      // vue公共組件
| |-- store       // vuex的狀態(tài)管理
| |-- App.vue      // 頁(yè)面入口文件
| |-- main.js      // 程序入口文件,加載各種公共組件
|-- static       // 靜態(tài)文件,比如一些圖片,json數(shù)據(jù)等
| |-- data       // 群聊分析得到的數(shù)據(jù)用于數(shù)據(jù)可視化
|-- .babelrc       // ES6語(yǔ)法編譯配置
|-- .editorconfig     // 定義代碼格式
|-- .gitignore      // git上傳需要忽略的文件格式
|-- README.md      // 項(xiàng)目說(shuō)明
|-- favicon.ico 
|-- index.html      // 入口頁(yè)面
|-- package.json      // 項(xiàng)目基本信息

3.3、運(yùn)行項(xiàng)目

6)、啟動(dòng)項(xiàng)目,輸入:npm run dev。服務(wù)啟動(dòng)成功后瀏覽器會(huì)默認(rèn)打開(kāi)一個(gè)“歡迎頁(yè)面”,如下圖:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

編譯成功后可以直接在瀏覽器中查看項(xiàng)目:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

3.4、Vue-cli HelloWorld

了解了默認(rèn)的模板內(nèi)容,我們可以開(kāi)始定義自己的vue程序了,這里寫(xiě)一個(gè)簡(jiǎn)單的HelloWorld,在src目錄下創(chuàng)建一個(gè)Hi.vue文件,內(nèi)容如下:

<template>
 <div id="app1">
  <input v-model="msg" v-on:click="sayhi"/>
  <p>
   <h3>{{msg}}</h3>
  </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 }
})

運(yùn)行結(jié)果:

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

四、示例下載

https://git.coding.net/zhangguo5/vue2.git

五、視頻

https://www.bilibili.com/video/av17503637/

六、作業(yè)

1、請(qǐng)定義任意一個(gè)Vue實(shí)例,觸發(fā)Vue實(shí)例中的8個(gè)事件,將結(jié)果輸出到控制臺(tái),要求可以觀察到數(shù)據(jù)初始化與掛載情況。

2、請(qǐng)使用vue2+bootstrap完成如下功能:

要求如下:

a)、實(shí)現(xiàn)添加功能

b)、實(shí)現(xiàn)刪除功能

c)、實(shí)現(xiàn)編輯功能,增加按鈕

d)、實(shí)現(xiàn)隔行換色

e)、實(shí)現(xiàn)按年齡排序

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

參考 :

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解 Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解

總結(jié)

以上所述是小編給大家介紹的Vue的實(shí)例、生命周期與Vue腳手架(vue-cli)實(shí)例詳解,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)億速云網(wǎng)站的支持!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI