VUE2.0學習總結

VUE2.0學習javascript

vue介紹

vue是什麼?

  • https://vuefe.cn/guide
  • vue也是一個數據驅動框架,作spa頁面的
  • vue若是不作頁面能夠當作一個單獨使用的js庫,作雙向數據綁定用
  • Vue的核心庫只關注視圖層,可是vue並不僅關注視圖,和angular同樣也有指令,過濾器這些東西
  • vue有很是強大的單文件組件
    • 就是css+html+js都寫在一個.vue文件中,這樣定義的組件很簡潔,清晰,組件化分的很完全
    • 而angular中的js文件只能寫js
    • 雖然react中能夠寫css-in-js,可是缺少選擇器功能,即使能夠在js中引入css文件,但仍是不方便
  • vue融合了react和angular的優勢,而且解決了react和angualr的痛點

vue學習地址和技術棧

  • Vue2.0中文網:https://vuefe.cn/
  • vue全家桶變爲vue2.0+vue-router+fetch+vuex
  • 咱們下文中所出現的vue都指代vue2.0

vue和其餘框架的對比

vue快速開始

用vue-cli開始

# 全局安裝 vue-cli
$ npm install --global vue-cli
# 建立一個基於 webpack 模板的新項目
$  vue init webpack my-project
# 安裝依賴,走你
$ cd my-project
$ npm install
$ npm run dev
  • 你只須要關注你配置的東西就能夠了,不須要關注webpack的配置項,由於webpack的配置很難,不少人不會,也是爲了簡便開發

本身建立Vue的開發環境

準備工做

  • 升級webstorm到最新版本,老版本對.vue文件的開發是有bug的
  • 下載webstorm爲Vue提供的插件vue-for-idea,這個插件可讓webstorm支持以.vue結尾的文件可以運行
  • 下載vuenpm install vue -save
  • 下載編譯模塊npm install vue-template-compiler -save
  • src/js文件中建立main.js
import Vue from 'vue'
import AppContainer from '../containers/AppContainer'

const app = new Vue({
    render: h => h(AppContainer),
}).$mount('#app')


// new Vue({
//     el:'#app',
//     render: h => h(App)
// })
  • 在src/container中建立AppContainer.vue文件
<template>
    <div>
        {{msg}}
    </div>
</template>
<style>
    body{
        background-color:#ff0000;
    }
</style>
<script>
    export default{
        data(){
            return{
                msg:'hello vue'
            }
        }
    }
</script>
  • 當你第一次建立.vue文件的時候IDE會問你用什麼語法去解析,你選擇html語法
  • 接下來就能夠直接運行npm run develop了
  • 你能夠去google中搜索vue-devtools下載並安裝,用於幫你監聽組件的data屬性變化

vue中的基礎知識點

Vue實例

屬性與方法

  • 咱們自定義的一些數據和方法是要綁定到實例的不一樣屬性上面去的
    • 例如數據都要綁定要data屬性,方法都要綁定到methods方法
  • 實例上的data和methods裏面的key值會自動掛載到vue實例上,咱們管他們叫動態屬性,獲取方式直接使實例.動態屬性名
  • vue實例上的實例屬性要經過實例.$實例屬性名獲取
  • 在vue實例裏面用this,this指向的是vue實例
    • 能夠經過this.a去獲取動態屬性
    • 能夠經過this.$data去獲取實例屬性
  • 實例上有一個$watch方法能夠監聽data屬性裏面的數據的變化,data一變會自動觸發監聽事件的執行
var data = {a: 1}
    const app = new Vue({
        // 和數據相關的都掛載到data上
        data: data,
        // 和方法相關的都掛載到methods上
        methods: {
            // this和$的使用
            func1: function () {
                console.log(this.a);
                console.log(this.$data.a);
            },
            changeData:function () {
                this.a=2
            }
        }
    })

    // 先監聽再改變
    app.$watch('a', function (newVal, oldVal) {
        console.log(newVal)
        console.log(oldVal)
    })
    // 值改變以後會自動執行監聽方法
    // data的值是能夠直接改變的,和react的setState方法不同,由於vue裏面用了set和get方法,能夠起到自動監聽的做用
    app.a=3


    // 動態屬性和實例屬性
//    console.log(app)
//    console.log(app.a)
//    console.log(app.$data.a)

實例生命週期

  • 和react的生命週期基本思想是同樣的
    • 只不過react中是監聽props和state屬性的變化
    • 而在vue中是隻監聽data屬性的變化
  • vue中的生命週期函數要比react中的方法多
  • 這些生命週期方法只能在spa應用中起做用,單獨做爲雙向數據綁定庫沒法生效
  • vue生命週期圖

模板語法

  • 就是如何在.vue文件的template標籤中書寫內容
  • {{}}(Mustache語法)裏面會按照純文本輸出
  • v-once指令只會執行一次性地插值,當數據改變時,插值處的內容不會更新。但請留心這會影響到該節點上全部的數據綁定:
  • v-html會按照html規則去解析內容
  • 咱們在爲標籤的屬性賦值的時候不能Mustache語法,咱們要用v-bind指令
    • v-bind綁定的屬性必須是data屬性裏面定義的值,若是想寫固定的值加單引號
// 錯誤的寫法
<div id="{{id}}"></div>
// 正確的寫法
<div v-bind:id="id"></div>
  • 在Mustache中能夠處理一些簡單的js表達式,Mustache中的屬性自己有什麼方法,在裏面也是能夠直接使用的
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
  • 在Mustache中可使用自定義過濾器,也能夠多過濾器串聯。可是過濾器不能用在v-bind中,若是想實現相同的效果在v-bind中咱們要用計算屬性
{{ message | capitalize }}

{{ message | filterA | filterB }}

new Vue({
  // ...
  filters: {
    capitalize: function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
})
  • 在dom標籤中可使用指令,如v-if,v-for
    • <a v-on:click="doSomething">
  • 在dom的事件中可使用修飾符去幫你簡化一些操做
    • <form v-on:submit.prevent="onSubmit"></form>
  • v-bind和v-on在模板語法中能夠縮寫
<!-- 完整語法 -->
<a v-bind:href="url"></a>
<!-- 縮寫 -->
<a :href="url"></a>
<!-- 完整語法 -->
<a v-on:click="doSomething"></a>
<!-- 縮寫 -->
<a @click="doSomething"></a>

計算屬性

  • 計算屬性能夠處理模板語法中的複雜業務邏輯,跟Mustache語法比css

  • 計算屬性 vs methodshtml

    • 咱們看到計算屬性和methods的效果基本你同樣,那麼他們的區別是什麼?
    • 計算屬性的依賴若是沒有發生變化,當你再次調用計算屬性的時候,可以當即返回上次緩存的計算值,而不須要重新執行計算屬性的方法
    • 而方法須要重新執行方法體
    • 樣例
    <template>
        <div>
            <p>Original message: "{{ message }}{{name}}"</p>
            <p>Computed reversed message: "{{ reversedMessage }}"</p>
            <p>Computed reversed message: "{{ reverseMessage() }}"</p>
        </div>
    </template>
    <style>
        body{
            background-color:#ff0000;
        }
    </style>
    <script>
        export default{
            data(){
                return{
                    message: 'Hello',
                    name:'a'
                }
            },
            mounted(){
                this.name="b"
            },
            computed: {
                reversedMessage: function () {
                    console.log('計算屬性被調用了')
                    return this.message.split('').reverse().join('')
                }
            },
            methods: {
                reverseMessage: function () {
                    console.log('方法被執行了')
                    return this.message.split('').reverse().join('')
                }
            }
    
        }
    </script>
  • 計算屬性 vs watchvue

    • watch方法每次只能監聽一個data值的變化
    • 而計算屬性能夠同時監聽多個data值的變化
    • 用計算屬性能夠簡化watch中重複的代碼
    <!--頁面-->
    <div id="demo">{{ fullName }}</div>
    //watch寫法
      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
          }
        }
      })
      //計算屬性的寫法
      //本質是你要獲取全名
      var vm = new Vue({
        el: '#demo',
        data: {
          firstName: 'Foo',
          lastName: 'Bar'
        },
        computed: {
          fullName: function () {
            return this.firstName + ' ' + this.lastName
          }
        }
      })
  • 計算setterjava

    • 計算屬性默認是隻有getter的,那麼data屬性裏面你的值發生改變了,計算屬性要重新執行
    • 而setter的做用是調用計算屬性的時候給一個初始值,那麼data屬性裏面的值也會跟着作相應的改變
    // 接上面的代碼段
    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]
        }
      }
    }
  • vue實例上的觀察watch仍是頗有用的,在進行執行異步操做或昂貴操做時,咱們要用watch這個實例屬性react

    • 由於你不要忘記計算屬性出現的緣由是爲了解決mustache語法中有過多的邏輯操做問題,它只能進行一些小型操做的內容

Class與Style綁定

  • 綁定要用v-bind:class和:bind:style
  • v-bind:class指令能夠與普通的class屬性共存
  • 綁定的時候能夠給對象,能夠個數組,還能夠有條件判斷和三元表達式

條件渲染

  • v-if和v-else只能控制一個標籤的渲染,並且v-else要緊跟着v-if
  • 若是想要控制一部分標籤的渲染,須要用<template>標籤包裹,v-if做用在template標籤上
  • v-show也能夠控制標籤的顯示隱藏,不過只是簡單的切換樣式
    • v-show的元素會始終渲染並保持在 DOM 中,v-if的元素會被移除
    • 注意 v-show 不支持 <template> 語法
  • v-if是惰性的,只有在條件第一次爲true的時候才進行局部渲染吧
  • v-if有更高的切換消耗,v-show有更高的初始渲染消耗。所以若是須要頻繁切換使用v-show較好,若是在運行時條件不大可能改變則使用v-if較好。

列表渲染

  • v-for是vue中作循環的,值能夠給數組,對象,數值三種類型
  • 能夠用of替換in
  • 若是想循環渲染一部分標籤,要用template標籤包裹,v-for做用在template標籤上
  • 在循環渲染引入的自定義組件的時候要手動爲組件傳遞item的屬性值
<my-components
      is="todo-item"
      v-for="(item, index) in todos"
      v-bind:title="item"
      v-on:remove="item.splice(index, 1)"
    > 
    </my-components>
  • 在循環渲染的時候要動態的綁定v-bind:key,這樣能夠提高vue的渲染效率
  • Vue 包含一組觀察數組的變異方法,只要調用它們將會觸發視圖更新,而且改變了原數組
    • push() pop() shift() unshift() splice() sort() reverse()
  • 重塑數組不會改變原來的數據,而是返回一個改變以後的新數據
    • filter(), concat(), slice()
    • 重塑數組通常是賦值用,這樣才能觸發vue的從新渲染,而你並不須要擔憂性能問題,由於vue會智能的重用數組
  • 因爲JavaScript 的限制,Vue不能檢測如下變更的數組:
    • 當你直接設置一個項的索引時,例如: vm.items[indexOfItem] = newValue
      • 用Vue.set解決
    • 當你修改數組的長度時,例如: vm.items.length = newLength
      • 用splice解決
  • v-for結合計屬性或者methods時能夠作數據的過濾和排序
// <li v-for="n in evenNumbers">{{ n }}</li>

data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

事件處理器

  • 在v-on:click的時候想既傳遞參數又想傳遞事件對象,那麼你須要手動傳入$event參數
<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
methods: {
  warn: function (message, event) {
    // 如今咱們能夠訪問原生事件對象
    if (event) event.preventDefault()
    alert(message)
  }
}
  • 經常使用事件修飾符
<!-- 阻止單擊事件冒泡 -->
<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>
<!-- 只當事件在該元素自己(而不是子元素)觸發時觸發回調 -->
<div v-on:click.self="doThat">...</div>
<!-- the click event will be triggered at most once -->
<a v-on:click.once="doThis"></a>
  • 常見的按鍵修飾符
<!-- 只有在 keyCode 是 13 時調用 vm.submit() -->
<input v-on:keyup.13="submit">
<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 縮寫語法 -->
<input @keyup.enter="submit">

<!--所有的按鍵別名:-->

    enter
    tab
    delete (捕獲 「刪除」 和 「退格」 鍵)
    esc
    space
    up
    down
    left
    right
    ctrl
    alt
    shift
    meta
  • 經過全局 config.keyCodes自定義按鍵修飾符別名,記住要在new新實例以前註冊
// 可使用 v-on:keyup.f1
Vue.config.keyCodes.f1 = 112

表單控件綁定

  • 表單的雙向綁定用v-model指令
  • 在文本區域插值<textarea></textarea>並不會生效,應用v-model來代替
  • 單個複選按鈕綁定的是選中狀態,多個複選按鈕綁定的是值
  • 列表沒有value值綁定的是標籤內容,有value值綁定的就是value值
  • 若是想讓表單的value屬性綁定到Vue實例的動態屬性上,須要用v-bind:value綁定
<input type="radio" v-model="pick" v-bind:value="a">
  • .lazy修飾符能夠實現單向數據綁定
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >

組件

  • 組件能夠擴展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素, Vue.js 的編譯器爲它添加特殊功能。在有些狀況下,組件也能夠是原生 HTML 元素的形式,以 is 特性擴展。
    • 組件是相似於angualr中自定義指令,是vue中的一種自定義標籤
    • 至關於react中的通用組件,高可複用性的(例如:列表,按鈕,等待器)

組件的使用

全局註冊組件

  • 全局組件的定義必定要在建立根實例以前
  • 在全局註冊的組件能夠在子組件的頁面中隨意使用
Vue.component('soupfree', {
        template: '<div>湯免費</div>'
    })

    const app = new Vue({
        el:'#example'
    })

局部註冊組件

  • 在要使用的組價中增長components屬性,註冊引入的組件並更名,以後才能夠在html代碼中使用
  • 通常局部註冊的組件都是經過.vue文件實現的
<template>
    <div>
       姓名:湯免費,年齡:{{age}},性別:{{genderSex}}
    </div>
</template>
<style scope>
    div{
        background-color:orange;
    }
</style>
<script>
    export default{
        data(){
            return{

            }
        },
        props:['age','genderSex']
    }
</script>
<template>
    <div>
        <soup-free></soup-free>
        {{msg}}
    </div>
</template>
<style>
    body{
        background-color:#ff0000;
    }
</style>
<script>
    import soupfree from '../components/soupfree.vue'
    export default{
        data(){
            return{
                msg:'hello vue'
            }
        },
        components:{
            'soup-free':soupfree
        }
    }
</script>

Dom模板解析問題

  • 當你在一些特殊標籤如table,ul,ol,select中使用自定義組件的時候會有一些限制webpack

    • 例如
    <table>
         <my-row>...</my-row>
    </table>
    • 由於Vue只有在瀏覽器解析和標準化HTML後才能獲取模版內容
    • 再準確的說也就是用Vue.component方法自定義的組件
    • is特性能夠解決這個問題
    <table>
        <tr is="my-row"></tr>
      </table>
  • 應當注意,若是您使用來自如下來源之一的字符串模板,這些限制將不適用:git

    • <script type="text/x-template">
      • 由於這裏面的代碼是內連載頁面中的
    • JavaScript內聯模版字符串
      • 這個就是template屬性
    • .vue 組件
      • 在webpack構建的時候就已經處理了組件內容爲html了
    • 所以,有必要的話請使用字符串模版。
  • ☆在自定義組件中data屬性必須是函數形式☆github

    • 也就是在Vue.component中和.vue文件中的data屬性
  • 若是是父子組件,那麼父組件向子組件傳遞參數用props,子組件向父組件傳遞參數用$emit廣播web

props屬性

  • 參數在傳遞的過程當中,父組件傳遞參數用kebab-case(短橫線隔開),在子組件接收的時候用camelCase
  • 若是傳遞的屬性來自父組件的data屬性,也就是向子組件傳遞動態屬性那麼須要用v-bind去傳遞
  • 如何傳遞的屬性類型是數值型,那麼也須要用v-bind去傳遞把
<!-- 傳遞實際的數字 -->
<comp v-bind:some-prop="1"></comp>
  • ☆注意在JavaScript中對象和數組是引用類型,指向同一個內存空間,若是prop是一個對象或數組,在子組件內部改變它會影響父組件的狀態。

    • 注意通常狀況下不要在子組件中改變父組件中傳遞過來的props,可是有兩種特殊狀況會改變
  • 咱們在傳遞屬性的時候能夠作屬性校驗

    • 當prop驗證失敗了,Vue將拒絕在子組件上設置此值,若是使用的是開發版本會拋出一條警告。

自定義事件

  • 用v-on去綁定自定義事件
    • 使用$on(eventName)監聽事件
    • 使用$emit(eventName)觸發事件
  • 在自定義組件上是不能夠用v-model指令,可是這個效果能夠經過自定義組件在內部用自定義事件模擬實現
Vue.component('currency-input', {
  template: '\
    <span>\
      $\
      <input\
        ref="input"\
        v-bind:value="value"\
        v-on:input="updateValue($event.target.value)"\
      >\
    </span>\
  ',
  props: ['value'],
  methods: {
    // 不是直接更新值,而是使用此方法來對輸入值進行格式化和位數限制
    updateValue: function (value) {
      var formattedValue = value
        // 刪除兩側的空格符
        .trim()
        // 保留 2 小數位
        .slice(0, value.indexOf('.') + 3)
      // 若是值不統一,手動覆蓋以保持一致
      if (formattedValue !== value) {
        this.$refs.input.value = formattedValue
      }
      // 經過 input 事件發出數值
      this.$emit('input', Number(formattedValue))
    }
  }
})
  • 兄弟組件之間的通訊能夠經過bus中央事件總線實現
    • 可是更復雜的數據通訊最好仍是用vuex
// 在根組件中註冊bus屬性
const app = new Vue({
    data:{
        bus:new Vue()
    },
    render: h => h(AppContainer),
}).$mount('#app')
// 在子組件中使用
this.$root.bus.$emit('eventName',2323)

slot分發

  • 在自定義組件使用的時候,若是頁面中有內容,又想讓內容在自定義組件中使用,咱們須要養slot標籤

  • slot標籤在一個html標籤中只能出現一次

  • 做用域插槽是一種特殊類型的插槽,用做使用一個(可以傳遞數據到)可重用模板替換已渲染元素。

    • 通俗的說就是子組件裏面的數據能夠經過做用域插槽用在父組件頁面中的指定區域內

動態組件

  • 組件能夠經過is特性動態加載
  • 你能夠用keep-alive指令緩存組件

雜項

  • 你能夠經過ref屬性標記一個組件,以後能夠用this.$refs.標記的名稱或獲得該組件

    • 當ref和v-for一塊兒使用時,ref是一個數組或對象,包含相應的子組件。
    • $refs只在組件渲染完成後才填充,而且它是非響應式的。它僅僅做爲一個直接訪問子組件的應急方案——應當避免在模版或計算屬性中使用$refs
  • 組件的異步加載

  • 組件命名規範

  • 組件的遞歸調用

    • 組件上的name屬性仍是這個組件在全局註冊時候的名字
<unique-name-of-my-component name="unique-name-of-my-component"></unique-name-of-my-component>
  • 組件的循環引用

    • Vue.component全局註冊組件後,這個問題會自動解決,你要作的就是在寫代碼的時候不要出現組件循環引用
  • 內聯模板

    • 通俗的說就是在定義組件的時候不用給template屬性了
  • x-Templates

相關文章
相關標籤/搜索