Vue.js 學習記錄
一、Vue起步
Vue:構建用戶界面的漸進式框架。
1.helloworld
<div id="app">{{content}}</div>
原生方法:
<script> var dom = document.getElementById(‘app‘); dom.innerHTML = ‘helloworld‘; </script>
Vue 方法:
<script> //創建Vue實例 var app = new Vue({ //el項 :Vue實例接管的區域 el: "#app",//定義數據 data: { content: "helloworld!" } }); </script>
2.兩秒後修改文字
<div id="app">{{content}}</div>
原生方法:
var dom = document.getElementById(‘app‘); dom.innerHTML = ‘helloworld‘; setTimeout(function() { dom.innerHTML = ‘byeworld‘; },2000)
Vue 方法:
var app = new Vue({ el: "#app", data: { content: "helloworld!" } }); setTimeout(function() { //$data 是 data的別名,指 data 對象 app.$data.content = "byeworld!"; },2000);
當書寫 vue 時,不需要關註DOM操作,而是要註重數據的管理,當數據發生變化時,頁面就會跟著變。
3.Vue實現簡單的TodoList
<div id="app"> <!-- v-model 雙向綁定,當表單框內容發生改變時,對應的data內的數據也會發生改變,反之同理--> <input type="text" v-model="inputValue"/> <!-- v-on綁定事件--> <button v-on:click="handleBtnClick">提交</button> <ul> <!-- 循環 list 數據,循環的每一項都放到 item 內,list有幾項就會循環出幾個 li 標簽 --> <li v-for="item in list">{{item}}</li> </ul> </div> <script type="text/javascript"> var app = new Vue({ el: ‘#app‘, data: { // 但是頁面一開始都是幹凈的 // list: [‘第一課內容‘, ‘第二課內容‘,‘2333333‘] list: [], inputValue: ‘‘ }, // 方法都放在 methods 裏 methods: { handleBtnClick: function() { // 因為 li 遍歷 list,每次點擊獲取input中的內容添加到 list 數組內 this.list.push(this.inputValue); this.inputValue = ‘‘; } } }); </script>
4.MVVM模式
傳統的MVP設計模式:面向DOM開發
Model —— Presenter —— View
模型層(數據層) —— 業務邏輯控制層 —— 視圖層
jQuery 實現 todolist
當按鈕點擊時視圖被操作,控制器會執行,通過DOM操作改變視圖
<div> <input id="input" type="text" /> <button id="btn">提交</button> <ul id="list"></ul> </div> <script> // 構造函數 function Page() { } /* $.extend()函數用於將一個或多個對象的內容合並到目標對象, 此處給顯示原型添加init方法 */ $.extend(Page.prototype,{ init: function() { this.bindEvents(); }, bindEvents: function() { var btn = $(‘#btn‘); // $.proxy() 用來改變 this 將上下文環境的this,改變為要執行函數內的this // 也可以用 btn.on(‘click‘,this.handleBtnClick),因為handleBtnClick內部不需要 this btn.on(‘click‘,$.proxy(this.handleBtnClick, this)); }, handleBtnClick: function() { var inputElem = $(‘#input‘); var inputValue = inputElem.val(); var ulElem = $(‘#list‘); ulElem.append(‘<li>‘+ inputValue +‘</li>‘); inputElem.val(‘‘); } }) var page = new Page(); page.init(); </script>
MVVM 設計模式:面向數據開發
無需任何DOM 操作,全部操作數據(M層),V層自動改變,由VM層來實現。
VM層:
Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。
虛擬DOM。
5.使用組件化思想修改TodoList
<div id="app"> <input type="text" v-model="inputValue"/> <button v-on:click="handleBtnClick">提交</button> <ul> <!--使用組件--> <!--向子組件傳入一個綁定值--> <!--循環list 每一項,通過content變量傳給了 todo-item 子組件 --> <todo-item v-bind:content="item" v-for="(item, index) in list" v-bind:index="index" @delete="handleItemDelete"> </todo-item> </ul> </div> <script type="text/javascript"> // 定義全局組件 Vue.component(‘todo-item‘,{ // 從父組件接收一個 content參數 props: [‘content‘,‘index‘], // 依然用插值符接收 template: "<li @click=‘handleItemClick‘>{{content}}</li>", methods: { handleItemClick: function() { //點擊子組件,子組件會向外觸發一個 delete 事件 this.$emit("delete") } } }); /* 定義局部組件 var TodoItem = { props: [‘content‘], template: "<li>{{content}}</li>" } */ // Vue實例 其實就是父組件 // #app 標簽下的所有內容實際上就是父組件的模板 var app = new Vue({ el: ‘#app‘, /* 在實例中使用局部組件 components: { // 組件名:變量名 ‘todo-item‘: TodoItem }, */ data: { list: [], inputValue: ‘‘ }, methods: { handleBtnClick: function() { this.list.push(this.inputValue); this.inputValue = ‘‘; }, handleItemDelete: function(index) { this.list.splice(index,1); } } }); </script>
6.簡單的組件間傳值
父組件向子組件傳值:在子組件用 v-bind 動態綁定一個變量 ,把對應的值傳給該變量。
子組件向父組件傳值:通過 $emit() 的方式自定義事件,子組件觸發父子間設置事件監聽。
二、Vue 基礎
1.Vue 實例
一個程序進行加載的時候,入口點是 new Vue() 實例,也叫根實例,其次Vue 中的每一個組件也是一個實例。
一個Vue 項目是由無數個實例組成的。
Vue的實例屬性由 $ 符開頭,如:vm.$data vm.$el
vm.$destroy() :作用是銷毀vue 實例
2.生命周期鉤子
beforeCreate
在實例初始化之後,數據觀測(data observer) 和 event/watcher 事件配置之前被調用。
created
實例已經創建完成之後被調用。在這一步,實例已完成以下的配置:數據觀測(data observer),屬性和方法的運算, watch/event 事件回調。然而,掛載階段還沒開始,$el 屬性目前不可見。
beforeMount
在掛載開始之前被調用:相關的 render 函數首次被調用。
mounted
el 被新創建的 vm.$el 替換,並掛載到實例上去之後調用該鉤子。
beforeUpdate
數據更新時調用,發生在虛擬 DOM 重新渲染和打補丁之前。 你可以在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。
updated
由於數據更改導致的虛擬 DOM 重新渲染和打補丁,在這之後會調用該鉤子。
當這個鉤子被調用時,組件 DOM 已經更新,所以你現在可以執行依賴於 DOM 的操作。然而在大多數情況下,你應該避免在此期間更改狀態,因為這可能會導致更新無限循環。
該鉤子在服務器端渲染期間不被調用。
beforeDestroy
實例銷毀之前調用。在這一步,實例仍然完全可用。
destroyed
Vue 實例銷毀後調用。調用後,Vue 實例指示的所有東西都會解綁定,所有的事件監聽器會被移除,所有的子實例也會被銷毀。 該鉤子在服務器端渲染期間不被調用。
3.Vue 的模板語法
{{}} :插值表達式
Vue 指令對應的內容都是JS表達式
v-text :讓該元素的innerText 內容變成綁定的變量所對應的值,功能同 {{}}
v-html :讓該元素的innerHTML 內容變成綁定的變量所對應的HTML內容
v-on :事件綁定
v-bind :屬性動態綁定
4.計算屬性,方法和偵聽器
<div id="app"> <!--最好不要在模板上出現邏輯--> <!-- {{firstName + ‘ ‘ + lastName}} --> {{fullName}} {{age}} </div> <script> var vm = new Vue({ el: "#app", data: { firstName: ‘Anqw‘, lastName: ‘Joe‘, fullName: ‘Anqw Joe‘, age: 25 }, // 方法一:偵聽器,內置緩存,但是代碼復雜很多 watch: { // 當firstName 發生改變時 firstName: function() { console.log("計算了一次"); this.fullName = this.firstName + ‘ ‘ + this.lastName; }, //當 lastName 發生改變時 lastName: function() { console.log("計算了一次"); this.fullName = this.firstName + ‘ ‘ + this.lastName; } } // 方法二:計算屬性,內置緩存,簡潔性能高,優先推薦 /*computed: { fullName: function() { fullName 依賴 firstName 與 lastName , 當這二者沒有發生改變時,計算屬性就不會重新計算, 繼續使用上次計算結果 console.log("計算了一次"); return this.firstName + ‘ ‘ + this.lastName; } }*/ /* // 方法三:定義方法函數,每次都會重新執行一次 methods: { fullName: function() { console.log("計算了一次"); return this.firstName + ‘ ‘ + this.lastName; } } */ }); </script>
5.計算屬性的 setter 和 getter
<div id="app"> <!--這裏 fullName 也會跟著改變--> {{fullName}} </div> <script> var vm = new Vue({ el: "#app", data: { firstName: ‘Anqw‘, lastName: ‘Joe‘ }, computed: { fullName: { // 讀取時會走 get 方法 get: function() { // 執行set()後值會改變,因此重新計算 fullName return this.firstName +‘ ‘+ this.lastName; }, // 設置屬性值走 set 方法 set: function(value) { // 設置 fullName 值,value會被打印出來 //console.log(value); var arr = value.split(‘ ‘); this.firstName = arr[0]; this.lastName = arr[1]; } } } }); </script>
6.Vue 的樣式綁定
<div id="app"> <!--動態的向一個DOM元素 去添加或刪除一個類,實現頁面效果的變更--> <!--方法一:class的對象綁定--> <!--isActivated 為 true時,activated的樣式名字就會顯示--> <div @click="handleDivClick1" :class="{activated: isActivated}"> hello world </div> <!--方法二:class和數組綁定--> <!--把樣式名傳入變量中以數組的形式綁定給 class--> <div @click="handleDivClick2" :class="[activated, activatedOne]"> bye world </div> <!--用style 改變樣式--> <!--方法三:把樣式對象直接傳入變量中,與style綁定--> <div :style="styleObj" @click="handleDivClick3">touch world</div> <!--方法四: 把樣式變量直接傳入數組中,或直接把樣式寫進去--> <div :style="[styleObj,{fontSize: ‘20px‘}]" @click="handleDivClick3">love world</div> </div> <script> var vm = new Vue({ el: "#app", data: { //變量存放布爾值 isActivated: false, //變量存放 class名 activated: ‘‘, activatedOne: ‘activated-one‘, //變量存放樣式 styleObj: { color: "black" } }, methods: { handleDivClick1: function() { //點擊改變 class名綁定的布爾值 this.isActivated = !this.isActivated; }, handleDivClick2: function() { //點擊改變 class名 this.activated = this.activated === ‘activated‘ ? ‘‘ : ‘activated‘; }, handleDivClick3: function() { //點擊直接改變樣式 this.styleObj.color = this.styleObj.color ===‘black‘ ? ‘red‘ : ‘black‘ } } }); </script>
class 綁定:
- 將 布爾值 賦給變量,變量 與 class樣式名 以對象形式綁定
- 將 class 樣式名賦給變量,變量以數組形式綁定
style 綁定
- 將 樣式 賦給變量,變量直接綁定,多個變量要用數組
- 將 樣式 直接以對象的形式綁定,多個對象要用數組
7.Vue 中的條件渲染
<div id="app"> <!--顯示隱藏--> <!-- v-if 對應的變量如果是 false 就不會存在DOM上 --> <div v-if="show">{{message}}</div> <!--v-if 條件不滿足時 執行 v-else,需要緊貼使用--> <div v-else>bye world</div> <!-- v-show 對應的變量如果是 false DOM依然存在,只是display:none 如果需要經常改變元素的顯示隱藏 用v-show 性能會高一些 --> <div v-show="show">{{message}}</div> <!--條件判斷--> <div v-if="letter === ‘a‘">This is a</div> <div v-else-if="letter === ‘b‘">This is b</div> <div v-else>This is other</div> </div> <script> var vm = new Vue({ el: "#app", data: { message: ‘hello world‘, show: false, letter: ‘g‘ } }); </script>
關於Key 值:
當給某個元素標簽加Key 值時,Vue 會知道是頁面上唯一的元素,如果兩個相同元素Key值不一樣,就不會嘗試復用以前的標簽。
Vue.js 學習記錄