created時,可用data和prop中的數據。vue
computed的屬性,當在mounted或者dom中使用到時,纔會屬性的執行代碼。緩存
最後是mouted,可以使用前面的數據,而且此時才能夠操做dom。bash
watch不會再建立階段自動執行,除了添加當即執行這個配置項。app
在官方文檔中,強調了computed區別於method最重要的兩點dom
計算屬性是基於它們的依賴進行緩存的,只有在它的相關依賴發生改變時纔會從新求值。異步
let vm = new Vue({
el: '#app',
data: {
message: '我是消息,'
},
methods: {
methodTest() {
return this.message + '如今我用的是methods'
}
},
computed: {
computedTest() {
return this.message + '如今我用的是computed'
}
}
})
複製代碼
這就意味着只要 message 尚未發生改變,屢次訪問 computedTest計算屬性會當即返回以前的計算結果,而沒必要再次執行函數。ide
相比而言,只要發生從新渲染,method 調用總會執行該函數。函數
<div id="app">
<h1>{{message}}</h1>
<p class="test1">{{methodTest}}</p>
<p class="test2-1">{{methodTest()}}</p>
<p class="test2-2">{{methodTest()}}</p>
<p class="test2-3">{{methodTest()}}</p>
<p class="test3-1">{{computedTest}}</p>
<p class="test3-2">{{computedTest}}</p>
</div>
複製代碼
在HTML的插值裏學習
在上面的例子中,methods定義的方法是以函數調用的形式來訪問的,那麼test2-1,test2-2,test2-3是反覆地將methodTest方法運行了三遍,若是咱們碰到一個場景,須要1000個methodTest的返回值,那麼毫無疑問,這勢必形成大量的浪費 更恐怖的是,若是你更改了message的值,那麼這1000個methodTest方法每個又會從新計算。。。。ui
因此,官方文檔才反覆強調對於任何複雜邏輯,你都應當使用計算屬性
computed依賴於data中的數據,只有在它的相關依賴數據發生改變時纔會從新求值
let vm = new Vue({
el: '#app',
data: {
message: '我是消息,'
},
methods: {
methodTest() {
return this.message + '如今我用的是methods'
}
},
computed: {
computedTest() {
return this.message + '如今我用的是computed'
}
}
})
複製代碼
如上例,在Vue實例化的時候,computed定義computedTest方法會作一次計算,返回一個值,在隨後的代碼編寫中,只要computedTest方法依賴的message數據不發生改變,computedTest方法是不會從新計算的,也就是說test3-1,test3-2是直接拿到了返回值,而非是computedTest方法從新計算的結果。
這樣的好處也是顯而易見的,一樣的,若是咱們碰到一個場景,須要1000個computedTest的返回值,那麼毫無疑問,這相對於methods而言,將大大地節約內存 哪怕你改變了message的值,computedTest也只會計算一次而已
computed的其它說明
Vue 提供了一種更通用的方式來觀察和響應 Vue 實例上的數據變更:watch 屬性,在路由場景有使用:vue學習之router
當你有一些數據須要隨着其它數據變更而變更時,你很容易濫用 watch,更好的想法是使用 computed 屬性而不是命令式的 watch 回調:
<div id="demo">{{ fullName }}</div>
複製代碼
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
複製代碼
上面代碼是命令式的和重複的。將它與 computed 屬性的版本進行比較:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
複製代碼
當須要在數據變化時執行異步或開銷較大的操做時,使用watch比較合適。
總之:儘可能用computed計算屬性來監視數據的變化,由於它自己就這個特性,用watch沒有computed「自動」,手動設置使代碼變複雜。
1.在new Vue()的時候,vue\src\core\instance\index.js裏面的_init()初始化各個功能
function Vue (options) {
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options) //初始化各個功能
}
複製代碼
2.在_init()中有這樣的一個執行順序:其中initState()是在beforeCreate和created之間
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm) //初始化
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
複製代碼
3.在initState()作了這些事情:
if (opts.props) initProps(vm, opts.props)//初始化Props
if (opts.methods) initMethods(vm, opts.methods)//初始化methods
if (opts.data) {
initData(vm)} else {
observe(vm._data = {}, true /* asRootData */)}//初始化data
if (opts.computed) initComputed(vm, opts.computed)//初始化computed
複製代碼
4.因此Props,methods,data和computed的初始化都是在beforeCreated和created之間完成的。