Last active
April 30, 2017 14:55
-
-
Save pjchender/063aff2b057374e3eac4eb4f6ebb89ec to your computer and use it in GitHub Desktop.
[Vue] 生命週期與 AJAX 使用說明
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Demo Vue</title> | |
| <script src="https://unpkg.com/vue@2.3.0/dist/vue.js"></script> | |
| <script src="https://unpkg.com/axios@0.16.1/dist/axios.js"></script> | |
| </head> | |
| <body> | |
| <div id="app"> | |
| <h1>{{ posts[currentId].title }}</h1> | |
| <h2>{{ posts[currentId].body }}</h2> | |
| <h3>{{ id }}</h3> | |
| </div> | |
| <script> | |
| const vm = new Vue({ | |
| el: '#app', | |
| data: { | |
| // 這時候因為 posts 沒有資料,但是 render 要顯示,所以會出現錯誤 | |
| // TypeError: Cannot read property 'title' of undefined | |
| currentId: 0, | |
| body: '', | |
| title: '', | |
| posts: [] | |
| }, | |
| computed: { | |
| // computed 的屬性在 vm 初次 create 時不會先被執行一次, | |
| id () { | |
| console.log('id computed') | |
| return `post${this.currentId}` | |
| } | |
| }, | |
| methods: { | |
| getCurrentId () { | |
| console.log('getCurrentId', this.currentId) | |
| } | |
| }, | |
| beforeCreate () { | |
| // 在 berforeCrate 資料沒 bind 上 vm,所以 this 拿不到資料 | |
| console.log('beforeCreate') | |
| }, | |
| created () { | |
| // created 之後可以 data bind 上 vm ,可以透過 this 拿到資料 | |
| console.log('created') | |
| let self = this | |
| // 這裡面用 AJAX 取得資料 | |
| axios({ | |
| method: 'get', | |
| url: 'https://jsonplaceholder.typicode.com/posts/' | |
| }) | |
| .then(function (response) { | |
| // 把 AJAX 取得的資料代入 Vue 中 | |
| self.posts = response.data | |
| console.log('getResponse') | |
| }) | |
| .catch(function (error) { | |
| console.log('err', error) | |
| }) | |
| }, | |
| beforeMount () { | |
| console.log('beforeMount') | |
| }, | |
| mounted () { | |
| // vm 初次 create 時,會從 beforeCreate 執行到這裡(mounted) | |
| console.log('mounted') | |
| }, | |
| beforeUpdate () { | |
| console.log('beforeUpdate') | |
| }, | |
| updated () { | |
| console.log('updated') | |
| } | |
| }) | |
| </script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Demo Vue</title> | |
| <script src="https://unpkg.com/vue@2.3.0/dist/vue.js"></script> | |
| <script src="https://unpkg.com/axios@0.16.1/dist/axios.js"></script> | |
| </head> | |
| <body> | |
| <div id="app"> | |
| <!-- title 和 body 是透過 computed 取得, | |
| - 使得 computed 會在 beforeMount 和 mounted 被觸發, | |
| - 但是這時候 this.posts 仍然還沒有資料 | |
| --> | |
| <h1>{{ title }}</h1> | |
| <h2>{{ body }}</h2> | |
| <h3>{{ id }}</h3> | |
| </div> | |
| <script> | |
| const vm = new Vue({ | |
| el: '#app', | |
| data: { | |
| // 這時候因為 posts 沒有資料,但是 render 要顯示,所以會出現錯誤 | |
| // TypeError: Cannot read property 'title' of undefined | |
| currentId: 0, | |
| posts: [] | |
| }, | |
| computed: { | |
| // computed 的屬性在 vm 初次 create 時不會先被執行一次, | |
| id () { | |
| console.log('id computed') | |
| return `post${this.currentId}` | |
| }, | |
| /** | |
| * 因為在 template 中有 {{ title }} | |
| * 促使 computed 在 beforeMount 和 mounted 之間執行 | |
| * 但這時候 this.posts 仍沒有資料,出現錯誤 | |
| * Error in render function: "TypeError: Cannot read property 'title' of undefined" | |
| **/ | |
| title () { | |
| console.log('title computed') | |
| return this.posts[this.currentId].title | |
| }, | |
| body () { | |
| console.log('body computed') | |
| return this.posts[this.currentId].body | |
| } | |
| }, | |
| methods: { | |
| getCurrentId () { | |
| console.log('getCurrentId', this.currentId) | |
| } | |
| }, | |
| beforeCreate () { | |
| // 在 berforeCrate 資料沒 bind 上 vm,所以 this 拿不到資料 | |
| console.log('beforeCreate') | |
| }, | |
| created () { | |
| // created 之後可以 data bind 上 vm ,可以透過 this 拿到資料 | |
| console.log('created') | |
| let self = this | |
| // 這裡面用 AJAX 取得資料 | |
| axios({ | |
| method: 'get', | |
| url: 'https://jsonplaceholder.typicode.com/posts/' | |
| }) | |
| .then(function (response) { | |
| // 把 AJAX 取得的資料代入 Vue 中 | |
| self.posts = response.data | |
| console.log('getResponse') | |
| }) | |
| .catch(function (error) { | |
| console.log('err', error) | |
| }) | |
| }, | |
| beforeMount () { | |
| console.log('beforeMount') | |
| }, | |
| mounted () { | |
| // vm 初次 create 時,會從 beforeCreate 執行到這裡(mounted) | |
| console.log('mounted') | |
| }, | |
| beforeUpdate () { | |
| console.log('beforeUpdate') | |
| }, | |
| updated () { | |
| console.log('updated') | |
| } | |
| }) | |
| </script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Demo Vue</title> | |
| <script src="https://unpkg.com/vue@2.3.0/dist/vue.js"></script> | |
| <script src="https://unpkg.com/axios@0.16.1/dist/axios.js"></script> | |
| </head> | |
| <body> | |
| <div id="app"> | |
| <h1>{{ title }}</h1> | |
| <h2>{{ body }}</h2> | |
| <h3>{{ id }}</h3> | |
| </div> | |
| <script> | |
| const vm = new Vue({ | |
| el: '#app', | |
| data: { | |
| currentId: 0, | |
| posts: [], | |
| title: '', | |
| body: '' | |
| }, | |
| computed: { | |
| // 除非有需要,否則 computed 的屬性在 vm 初次 create 時不會先被執行一次 | |
| // 如果有需要,則 computed 會在 beforeMound 和 mounted 之間執行 | |
| id () { | |
| console.log('id computed') | |
| return `post${this.currentId}` | |
| } | |
| }, | |
| methods: { | |
| getCurrentId () { | |
| console.log('getCurrentId', this.currentId) | |
| } | |
| }, | |
| beforeCreate () { | |
| // 在 berforeCrate 資料沒 bind 上 vm,所以 this 拿不到資料 | |
| console.log('beforeCreate') | |
| }, | |
| created () { | |
| // created 之後可以 data bind 上 vm ,可以透過 this 拿到資料 | |
| console.log('created') | |
| let self = this | |
| // 這裡面用 AJAX 取得資料 | |
| axios({ | |
| method: 'get', | |
| url: 'https://jsonplaceholder.typicode.com/posts/' | |
| }) | |
| .then(function (response) { | |
| // 把 AJAX 取得的資料代入 Vue 中 | |
| self.posts = response.data | |
| // 更新需要初始化的資料 | |
| self.title = self.posts[self.currentId].title | |
| self.body = self.posts[self.currentId].body | |
| console.log('getResponse') | |
| }) | |
| .catch(function (error) { | |
| console.log('err', error) | |
| }) | |
| }, | |
| beforeMount () { | |
| console.log('beforeMount') | |
| }, | |
| mounted () { | |
| // vm 初次 create 時,會從 beforeCreate 執行到這裡(mounted) | |
| console.log('mounted') | |
| }, | |
| beforeUpdate () { | |
| console.log('beforeUpdate') | |
| }, | |
| updated () { | |
| console.log('updated') | |
| } | |
| }) | |
| </script> | |
| </body> | |
| </html> |
Author
Author
搭配 AJAX 較好的使用方法
在 template 中寫每次 render 時要顯示的資料
<div id="app">
<h1>{{ title }}</h1>
<h2>{{ body }}</h2>
<h3>{{ id }}</h3>
</div>把 template 有用到的 data 直接寫到 vm.data 中
- 在 created 拿到 request 回來的資料後,若有需要,把 request 取得的資料寫入 vm.data 中
- 更新需要透過 AJAX 取的資料後,才能初始化的資料。這時候因為我們有更新資料的關係(原本在 data 已經有給值),因此 vm 在建立時,除了從
beforeCreate跑到mounted之外,會進一步促發beforeUpdate和updated的 hook
const vm = new Vue({
el: '#app',
data: {
currentId: 0,
posts: [],
title: '',
body: ''
},
// ...
created () {
// created 之後可以 data bind 上 vm ,可以透過 this 拿到資料
console.log('created')
let self = this
// 這裡面用 AJAX 取得資料
axios({
method: 'get',
url: 'https://jsonplaceholder.typicode.com/posts/'
})
.then(function (response) {
// STEP1: 把 AJAX 取得的資料代入 Vue 中
self.posts = response.data
// STEP2: 更新需要透過 AJAX 資料才能初始化的資料,如此將進一步促發 `beforeUpdate` 和 `updated`
self.title = self.posts[self.currentId].title
self.body = self.posts[self.currentId].body
console.log('getResponse')
})
.catch(function (error) {
console.log('err', error)
})
}
})
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
生命週期基本概念
created: 一般會把 AJAX 取得的資料的過程寫在created的時候,在這把取得的資料存到 vm,並且更新相關需要透過 AJAX 資料才能正確初始化的資料。beforeMount: 這時候還沒有 $parent ,組件還沒綁上去mounted: 的時候則可以開始綁事件,上場,有可能是進到 document 或其他的 component 中beforeDestroy: 要把自己加上的一些事件清除〈例如,requestAnimatinoFrame〉,還可以拿到 this。destroyed: 已經拿不到 this[示範] 程式碼與畫面
相關事件執行時間
created後才會 bind 上去,因此要透過this使用 vm 內的 data 或 vm 內的 methods 時,需要在created之後才可以取得this。beforeCreate到mounted,不會自動進入beforeUpdate。beforeUpdate和updated的 hook。載入時要 render 被 computed 的屬性
{{ id }},則 computed 會在 beforeMound 和 mounted 之間執行Vue Life Cycle Map