Vue.js 誕生及發展史


前言

前端現在可以說是百花齊放,開發的效率是不斷的提升,前端的三大主流框架 Vue 、Angular 、React 其中 Angular 是2009年誕生的,一開始出來挺火的,后面隨着版本的升級,Angular的變化比較大,增加了使用學習的成本,漸漸的失去了優勢,React和Vue的原理基本上是一樣的,誕生比Vue早,所以Vue結合了Angular和React的優勢,占據了江山。

提高開發效率的發展歷程:

  • 原生的JS 》 JQuery 類庫 》 前端模板引擎 》 Vue.js / Angular.js / React.js ( Vue 減少了DOM操作 虛擬DOM 提高了渲染效率 數據雙向綁定)

Vue

Vue 只做 Html + css + js : 視圖

網絡通信: axios前端通信框架

頁面跳轉:vue-router

狀態管理: vuex

UI 框架

ElementUI 、iview、ice

Vue的發展史:

  • 2013年底尤雨溪個人實驗項目開始開發
  • 2014年2月公開發布
  • 2014年11月發布0.11版本
  • 2016年10月發布2.0版本

Vue 基於 MVVM 模式設計的, MVVM (Model View ViewMolde)
MVVM模式:

  • Model 數據模型
  • View 負責頁面展示
  • ViewModel 對數據進行處理后再交給頁面展示

ViewModel是Vue.js的核心,它是一個Vue的實例

從 View 側看 ViewModel中的DOM Listeners 會幫我們監測頁面上DOM元素的變化,如果有變化,則會更改Model中的數據;

從 Model 側看 當我們更新 Model 中的數據時 ,Data Bingings 會幫我們更新頁面中DOM元素;

提高開發效率的發展歷程:
最開始的原生 JS (操作DOM元素) 》 Jquery 類庫 》前端模板引擎 》 Vue.js / Angular.js / React.js (其中Vue減少DOM操作,虛擬DIM, 提高了頁面渲染效率,實現了數據的雙向綁定)
Vue.10 是沒有虛擬DOM 在 Vue.2.0改成了虛擬DOM

Vue 生命周期

beforeCreate(){
    console.log("beforeCreate")
    // 此時數據data和事件方法methods還未綁定到app對象上
},
created(){
    console.log("create")
  // 數據data和事件方法methods綁定到app對象上
},
beforeMount(){
  console.log("beforeMount")
  // 渲染之前,根據數據生成的DOM對象是獲取不到的
},
mounted(){
  console.log("mounted")
  // 渲染之后,可以獲取數據生成的DOM對象。
},
beforeUpdate(){
  // 數據更改, 但內容未更改之前
  console.log("beforeUpdate")
},
update(){
  // 內容已更改完畢
  console.log("update")
},
beforeDestroy(){
  // 應用銷毀之前
  console.log("beforeDestroy")
},
destroyed(){
    // 應用銷毀之后
  console.log("destroyed")
}

Vue 模板語法

插值

  • 文本

    <span>Message: {{ msg }}</span>
    

    通過使用 v-once 指令可以一次性的插值,當數據改變時,此處內容不會更新。

    <span v-once>這個將不會改變: {{ msg }}</span>
    
  • 原始 HTML v-html 指令

    <div id="app">
            <p>Using mustaches: {{ rawHtml }}</p>
            <p>Using v-html directive: <span v-html="rawHtml"></span></p>
        </div>
    
        <script type="text/javascript">
            let app = new Vue({
                el:"#app",
                data:{
                  rawHtml:"<span style='color: red;'>This should be red</span>"
                }
            })
        </script>
    
    結果: 
    
    Using mustaches: <span style='color: red;'>This should be red</span>
    
    Using v-html directive: This should be red
    

    支持使用 Javascript 表達式

    {{ number + 1 }}
    
    {{ ok ? 'YES' : 'NO' }}
    
    {{ message.split('').reverse().join('') }}
    
    <div v-bind:id="'list-' + id"></div>
    

指令

​ 是帶有 v- 前綴的特殊屬性。

  1. 參數

    在指令名之后以冒號表示,eg:

    <a v-bind:href="url">...</a>
    

    這里 href是參數 , 告知 v-bind 指令將該元素的 href 屬性與表達式 url 的值綁定。

    v-on指令用來監聽DOM事件:

    <a v-on:click="doSomething" >....... </a>
    
  2. 動態參數

    2.6.0 新增

    從2.6.0開始 ,指令的參數可以用方括號括起來的表達式了。

<a v-bind:[attributeName]="url">.....</a>

如果Vue的實例中 data 的attributeName的值為href ,那么這個就為 v-bind:href="url"

v-bind指令的縮寫 :

<!-- 完整語法 -->
<a v-bind:href="url">...</a>

<!-- 縮寫 -->
<a :href="url">...</a>

<!-- 動態參數的縮寫 (2.6.0+) -->
<a :[key]="url"> ... </a>

v-on指令的縮寫 @

<!-- 完整語法 -->
<a v-on:click="doSomething">...</a>

<!-- 縮寫 -->
<a @click="doSomething">...</a>

<!-- 動態參數的縮寫 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>

計算屬性

vue的計算屬性對於任何復雜的邏輯都可以使用計算屬性 computed 。

計算屬性默認只有 getter , 可以設置一個 setter

// ...
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
// ...
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 計算屬性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 實例
      return this.message.split('').reverse().join('')
    }
  }
})

計算屬性的緩存

計算屬性是基於響應式依賴進行的緩存,只在相關的依賴發生改變時,才會重新求值。也就是說依賴不發生改變,不會執行函數。會存緩存中獲取。

如果不需要緩存,可用方法替換。

computed依賴於data中的變量,只有在它的相關依賴數據發生改變時才會重新求值

    <div id="app">
        <div>{{Name}}</div>
    </div>

    <script type="text/javascript">
        let app = new Vue({
            el:"#app",
            data(){
              return{
                num:0,
                lastname:'',
                firstname:''
              }
           },
          //當num的值發生變化時,就會調用num的方法,方法里面的形參對應的是num的新值和舊值  watch 也可以監聽computed 中的變量,也可以監聽data中定義的變量
          watch:{
            num:function(val,oldval){
              console.log(val,oldval);
            }
          },
          //計算屬性computed,計算的是Name依賴的值,它不能計算在data中已經定義過的變量。
          computed:{
            Name:function(){
              alert(123);
              return this.firstname+this.lastname;
            }
          }
        })
   </script>

watch 只有當監聽的變量發生改變的時候才能觸發。

Class 綁定

  • class 對象綁定

    寫法一:

<div v-bing:class="{active: isActive}"></div>

如下data中:

data:{
	isActive: true
}

​ 寫法二:

<div :class="classObject"></div>


data:{
	classObject: {
		active:true,
		'text-danger':false
	}
}
  • class 數組綁定
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

渲染為:

<div class="active text-danger"></div>

Style 內聯樣式綁定

  • style 對象語法

    <div :style="{color: activeColor, fontSize: fontSize + 'px'}"></div>
    
    data: {
    	activeColor: 'red',
    	fontSize: 30
    }
    

    直接綁定一個樣式對象,會更方便

    <div v-bing:style="styleObject"></div>
    
    data: {
    	activeColor: 'red',
    	fontSize: 30
    }
    

    同樣的,對象語法常常結合返回對象的計算屬性使用。

  • style 數組語法

<div v-bind:style="[baseStyles, overridingStyles]"></div>

Vue條件渲染

<h1 v-if="age >18">成年人</h1> 
<!-- 在 v-if 與 v-else-if 與 v-else 中間不可以有其它元素,否則會報錯 , 必須緊跟在 v-if 或者 v-else-if 的元素之后-->
<!-- <div id="test"></div>  -->
<h2 v-else-if="age > 60">老年人</h2>
<h3 v-else >小孩子</h3>

<!-- 
   v-else-if  2.1.0 新增
-->

指令 v-if 與 v-show 區別:

  • v-if =“表達式” , 表達式為false 時,移除DOM中的元素
  • v-show="表達式" , 表達式為false 時, 會將DOM元素設置為display:none
  • 性能上 v-if 相比 v-show 更消耗性能 ,如果需要頻繁切換使用 v-show

列表渲染

v-for 指令基於一個數組來渲染列表。 v-for 指令需要使用 item in itmes 形式的是特殊語法 items 是源數據數組 item 是被迭代數組元素的別名。

v-for 遍歷數組

<lu id="example-l">
	<li v-for=“item in items” :key=“item.message" >
		{{item.message}}
	</li>
</lu>


var example = new Vue(){
	el: 'example-l',
	data: {
		items: [
			{message: 'Foo'},
			{message: 'Bar'}
		]
	}
}

結果:

Foo

Bar

在 v-for 代碼塊中,還可以訪問所有父作用域中的屬性,v-for 的第二個參數為索引。

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

結果:

Parent-0-Foo

Parent-1-Bar

v-for 遍歷對象

<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})

結果:

How to do lists in Vue

Jane Doe

2016-04-10

將屬性名稱和值都遍歷出來

<div v-for="(value, name) in object">
  {{ name }}: {{ value }
</div>

結果:

title: How to do lists in Vue

author: Jane Doe

publishedAt: 2016-04-10

<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>

v-for 的默認行為會嘗試原地修改元素而不是移動它們, 要強制其重新排序元素, 需要使用 特殊屬性 key 來提供一個排序提示

事件處理

  • 監聽事件 可以用 v-on 指令監聽DOM事件

用表達式直接進行計算

eg:

<h1>點擊次數:{{count}}</h1>
<button @click="count+=1">點擊</button>
<script>

  var app = new Vue({
    el: '#app',
    data: {
      count: 0
    }
  })
</script>

事件修飾符

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止單擊事件繼續傳播  防止冒泡事件向上傳遞-->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重載頁面  阻止默認事件-->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修飾符可以串聯 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件監聽器時使用事件捕獲模式 -->
<!-- 即內部元素觸發的事件先在此處理,然后才交由內部元素進行處理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只當在 event.target 是當前元素自身時觸發處理函數 -->
<!-- 即事件不是從內部元素觸發的 -->
<div v-on:click.self="doThat">...</div>

<!-- 點擊事件將只會觸發一次 2.14新增-->
<a v-on:click.once="doThis"></a>

<!-- 滾動事件的默認行為 (即滾動行為) 將會立即觸發 -->
<!-- 而不會等待 `onScroll` 完成  -->
<!-- 這其中包含 `event.preventDefault()` 的情況 -->
<div v-on:scroll.passive="onScroll">...</div>

使用修飾符時,順序很重要;相應的代碼會以同樣的順序產生。因此,用 v-on:click.prevent.self 會阻止所有的點擊,而 v-on:click.self.prevent 只會阻止對元素自身的點擊。

鍵修飾符

<!-- 只有在 `key` 是 `Enter` 時調用 `vm.submit()` -->
<input v-on:keyup.enter="submit">

<input v-on:keyup.page-down="onPageDown">

系統修飾符

  • .ctrl
  • .alt
  • .shift
  • .meta
<!-- Alt + C -->
<input v-on:keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Do something</div>

.exact修飾符

2.5.0 新增

.exact 修飾符允許你控制精確的系統修飾符組合觸發的事件。

<!-- 即使 Alt 或 Shift 被一同按下時也會觸發 -->
<button v-on:click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的時候才觸發 -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>

<!-- 沒有任何系統修飾符被按下的時候才觸發 -->
<button v-on:click.exact="onClick">A</button>

表單輸入綁定

v-model 指令在 表單 input 、textarea、select 、radio、checkbox 元素上創建雙向數據綁定。

v-model 會忽略所有表單元素的 value、checked、selected attribute 的初始值而總是將 Vue 實例的數據作為數據來源。你應該通過 JavaScript 在組件的 data 選項中聲明初始值。

修飾符

.lazy

v-model 在每次 input 事件觸發后將輸入框的值與數據進行同步 (除了上述輸入法組合文字時)。你可以添加 lazy 修飾符,從而轉為在 change 事件_之后_進行同步

<!-- 在“change”時而非“input”時更新 -->
<input v-model.lazy="msg">

.number

如果想自動將用戶的輸入值轉為數值類型,可以給 v-model 添加 number 修飾符:

<input v-model.number="age" type="number">

這通常很有用,因為即使在 type="number" 時,HTML 輸入元素的值也總會返回字符串。如果這個值無法被 parseFloat() 解析,則會返回原始的值。

.trim

如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符:

<input v-model.trim="msg">

修飾符可以多個一起使用

Vue組件

組件是可復用的 Vue 實例,且帶有一個名字:在這個例子中是 <button-counter>。我們可以在一個通過 new Vue 創建的 Vue 根實例中,把這個組件作為自定義元素來使用:

// 定義一個名為 button-counter 的新組件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
<div id="components-demo">
  <button-counter></button-counter>
</div>

組件中的data 必須是一個函數

data: function(){
	return {
		
	}
}

組件與組件之間傳值

  • 父組件給子組件傳值

通過 Props 向子組件傳遞數據

<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>

子組件

Vue.component('blog-post', {
  // 定義 props 中的屬性 
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

動態傳遞Props

new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})
<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
></blog-post>
  • 子組件給父組件傳值

子組件傳父組件需要自定義觸發事件 $emit,實現數據的傳輸
當父級組件監聽這個事件時,可以通過 $event 訪問拋出的這個值;且必須是用 $event 接收

<blog-post
  ...
  v-on:enlarge-text="postFontSize += $event"
></blog-post>
<div id="app">
    <h2>父組件的count : {{count}}</h2>
    <!--
        :aaa="post"
        這里的  aaa 傳入子組件的變量 與 props: ["aaa"] 中的變量一致
        post 為父組件data中定義的變量

        @add-test="add"
        這里的 add-test 是子組件觸發的事件名  add 是父組件的方法
    -->
    <blog-post v-for="post,index in posts" :key="post.id" :aaa="post" @add-test="add">

    </blog-post>
</div>
<script>

    Vue.component('blog-post',{
        data: function () {
          return {
            count: 0
          }
        },
        props: ["aaa"],
        template: `
            <div>
                <h1>{{aaa.id}}</h1>
                <h1>{{aaa.title}}</h1>
                <button @click="$emit('add-test', aaa.id)">You clicked me times.</button>
            </div>
        `
    });

  var app = new Vue({
    el: '#app',
    data: {
      count: 0,
      posts: [
        {id: '1', title: 'My journey with Vue'}
//        {id: '2', title: 'Blogging with Vue'},
//        {id: '3', title: 'Why Vue is so fun'}
      ]
    },
    methods:{
      // add 方法 對應 @add-test="add"
      add: function(data){
        this.count = data
      }
    }
  })
</script>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM