vue筆記

ゐ葉う楓ゆ發表於2023-04-10

1. 邂逅Vuejs

1.1 簡單認識一下Vuejs

Vue是一個漸進式的框架,什麼是漸進式呢?

  • 漸進式意味著你可以將Vue作為應用的一部分嵌入其中,帶來更豐富的互動體驗
  • 或者你希望將更多的業務邏輯使用Vue實現,那麼Vue核心庫以及其生態系統。
  • 比如Core+Vue-router-Vuex,也可以滿足你各種各樣的需求。

Vue有很多特點和Web開發中常見的高階功能

  • 解耦試圖的資料
  • 可複用的元件
  • 前端路由技術
  • 狀態管理
  • 虛擬Dom

這些特點,你不需要一個個去記住,我們在後面的學習和開發中都會慢慢體會到的

學習Vuejs的前提?

  • 從零學習Vue,並不需要你具備其他類似與Angular、React,甚至JQuery的經驗
  • 但是你需要具備一定的HTML、CSS、JavaScript基礎

1.2 安裝Vuejs

安裝Vue的方式有很多:

  1. 直接CDN引入

    • CDN

      對於製作原型或學習,你可以這樣使用最新版本:
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      對於生產環境,我們推薦連結到一個明確的版本號和構建檔案,以避免新版本造成的不可預期的破壞:
      <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
      
    • 你可以選擇引入開發環境版還是生成環境版本

      <!-- 開發環境版本,包含了有幫助的命令列警告 -->
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      <!-- 生產環境版本,最佳化了尺寸和速度 -->
      <script src="https://cdn.jsdelivr.net/npm/vue"></script>
      
    • NPM安裝

      後續透過webpack和CLI的使用,我們使用改方式

1.3. Hello Vuejs

我們來做一個Vue程式,體驗一下Vue的響應式

我們來閱讀JavaScript程式碼,會發現建立了一個Vue物件

建立Vue物件的時候,傳入了一些options:{}

  • {}中包含了el屬性:該屬性決定了這個Vue物件掛載到了哪一個元素上,很明顯,我們這裡掛載了id為app的元素上
  • {}中包含了data屬性:該屬性中通常會儲存一些資料
    • 這些資料可以是我們直接定義出來的,比如想上面這樣。
    • 也可能來自網路,伺服器載入的

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">{{messages}}</div>
<script src="../js/vue.js"></script>
<script>
    <!--  程式設計方式:宣告式程式設計  -->
    let app = new Vue({
        el: '#app', // 用於掛載管理的元素
        data: {
            message: 'Hello Vue js!'
        }
    });
//    元素js的做法(程式設計方式:指令式程式設計)
//    1.建立div元素,設定id屬性
//    2.定一個變數叫message
//    3.將message變數放在前面的div元素中顯示
</script>
</body>
</html>

瀏覽器顯示

image-20210512220500740

什麼是指令式程式設計和宣告式程式設計:

指令式程式設計:命令“機器”如何去做事情(how),這樣不管你想要的是什麼(what),它都會按照你的命令實現。

宣告式程式設計:告訴“機器”你想要的是什麼(what),讓機器想出如何去做(how)。

詳細:https://www.cnblogs.com/sirkevin/p/8283110.html

1.4. 建立Vue例項傳入的Options

你會發現,我們在建立Vue例項的時候,傳入了一個物件options

詳細請訪問:https://cn.vuejs.org/v2/api/#選項-DOM

目前掌握這些選項:

  • el:
    • 型別string | Element
    • 限制:只在用 new 建立例項時生效。
    • 作用:決定之後Vue例項會管理哪一個DOM
    • 詳細https://cn.vuejs.org/v2/api/#el
  • data:
    • 型別Object | Function
    • 限制:元件的定義只接受 function
  • methods:
    • 型別{ [key: string]: Function }
    • 作用:定義屬於Vue的一些方法,可以在其他地方呼叫,也可以在指令中使用
    • 詳細https://cn.vuejs.org/v2/api/#methods

1.5. Vue的生命週期

生命週期:事物從誕生到消亡的整個過程

vue每個元件都是獨立的,每個元件都有一個屬於它的生命週期,從一個元件建立、資料初始化、掛載、更新、銷燬,這就是一個元件所謂的生命週期。在元件中具體的方法有:

beforeCreate

created

beforeMount

mounted

(

​ beforeUpdate

​ updated

)

beforeDestroy

destroyed

生命週期流程圖:

img

詳細:https://www.jianshu.com/p/410b6099be69

1.6 設定Vue的template(模板)

  1. 開啟Webstorm

    image-20210513133634369

  2. 找到Editor-> Live Template - >Vue

    image-20210513133746863

  3. 進行設定 (Abbreviation: 縮寫詞, Description: 說明)

    image-20210513133835115

    <div id="app">{{message}}</div>
    <script src="../js/vue.js"></script>
    <script>
      let app = new Vue({
        el: '#app', 
        data: {
          message: 'Hello Vue js!'
        }
      });
    </script>
    
  4. 點選Change

    image-20210513134030331

  5. OK

2. 基本語法

2.1 插值操作

如何將data中的檔案資料,插入到HTML中呢?

  • 可以透過Mustache語法(也就是雙大括號)
  • Mustache:鬍子/鬍鬚
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <p>{{message}}</p>
  <p>{{firstName}} {{lastName}}</p>
  <p>{{firstName + lastName}}</p>

</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      firstName: '不能說的秘密',
      lastName: '周杰倫'
    }
  });
</script>
</body>
</html>

image-20210513192402503

image-20210513192018658

2.2 指令

v-once

在某些情況下,我們可能不希望介面隨意的隨意改變

  • 這個時候,我們就可以使用Vue的指令

v-once:

  • 改指令後面不需要跟如何表示式
  • 該指令表達元素和其他元件只渲染一次,不會隨著資料改變而改變

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <p v-once>{{message}}</p>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
    }
  });
</script>
</body>
</html>

v-html

某些情況下,我們從伺服器請求到的資料本身就是一個HTML程式碼

  • 如果我們直接透過{{}}來輸出,會將HTML程式碼也一起輸出
  • 但是我們可能希望的是按照HTML進行解析,並且顯示對應的資料內容

如果我們希望解析出HTML展示可以使用v-html指令

  • 該指令後面往往會將跟上一個string型別
  • 會將string的html解析出來並且進行渲染

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <p v-once>{{message}}</p>
  <p>{{url}}</p>
    // 使用v-html進行渲染
  <p v-html="url"></p>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      url: '<a href="https://cn.vuejs.org/v2/guide/">官網</a>'
    }
  });
</script>
</body>
</html>

image-20210513193725507

v-text

v-pre

v-cloak(cloak:斗篷)

3. 繫結屬性

3.1 v-bind

某些屬性我們也希望動態來繫結。

  • 比如動態繫結a元素的href屬性
  • 比如動態繫結img元素的src屬性

這個時候,我們可以使用v-bind指令:

  • 作用:動態繫結屬性
  • 縮寫::
  • 預期: any fwith argument)I Object(without argument)
  • 引數:attrOrProp(optional)

我們如果直接使用musttache語法進行繫結的話,會出現下面的情況

image-20210513195244662

image-20210513195412087

正確的使用方式是透過v-bind,讓標籤進行進行動態繫結達到我們想要的效果

image-20210513200212672

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <!-- 錯誤的做法:這裡不能使用mustache語法 -->
<!--  <img src="{{img}}" alt="">-->
  <!-- 正確的使用方式 -->
  <img v-bind:src="img" alt=""><br>
  <a v-bind:href="href">嗶哩嗶哩</a>
<!-- 語法糖使用方式 -->
  <a :href="href"></a>
  <img :src="img" alt="">
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      img: "https://cn.vuejs.org/images/logo.png",
      href: "https://www.bilibili.com/"
    }
  });
</script>
</body>
</html>

動態繫結class

當然我們也可以使用v-bind進行動態繫結class

image-20210513201902662

效果:

image-20210513201951496

透過console來更改Boolean值

image-20210513202005639

上面那種寫法會讓人感覺到不是很友好,我們可以使用函式來封裝

image-20210513203120591

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    .active{
        color: skyblue;
    }
  </style>
</head>
<body>
<div id="app">
  <!--
      {}表示是一個物件
      {key1: value1, key2: value2}
      {類名1:boolean, 型別2: boolean}
   -->
  <!-- 兩個標量都為true時,樣式才會生效 -->
  <h2 v-bind:class="{active: isActive, line: isLine}">{{message}}</h2>
  <!-- 上面那種寫法會讓人感覺到不是很友好,我們可以使用函式來封裝 -->
  <h2 v-bind:class="">{{message}}</h2>
  <!-- 使用v-on指令進行動態繫結事件,後面我們會學習到 -->
  <button v-on:click="btnClick">按鈕</button>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      isActive: true,
      isLine: true
    },

    methods: {
      btnClick: function(){
        this.isActive = !this.isActive
      },
      getClass: function() {
        return {active: this.isActive, line: this.isLine}
      }

    }
  });
</script>
</body>
</html>

image-20210513204809830

動態繫結style

在寫CSS屬性的時候,比如font-size

  • 我們可以使用駝峰式
  • 或者短橫線分隔font-size(但是記得加單引號括起來)

例項圖:

image-20210513204918506

效果圖:

image-20210513204937059

也可以使用變數名來進行

image-20210513205336218

效果圖:

image-20210513205358168

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
<!--  <h2 :style="{key(屬性名): value(屬性值)}"></h2>-->
  <!-- 50px必須加單引號, 否則當做一個變數去解析 -->
  <h2 :style="{fontSize: '50px'}">{{message}}</h2>
  <!-- 使用font-size必須加單引號 -->
  <h2 :style="{'fontSize': '50px'}">{{message}}</h2>
  <!-- finalSize當成一個變數使用 -->
  <h2 :style="{fontSize: finalSize + 'px'}">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      finalSize: 100
    }
  });
</script>
</body>
</html>

3.2 計算屬性

基本使用

我們知道,在模板中可以直接透過插值語法顯示一些data中的資料。

但是在某些情況,我們可能需要對資料進行一些轉化後再顯示,或者需要將多個資料結合起來進行顯示

  • 比如我們有firstName和lastName兩個變數,我們需要顯示完整的名稱。

  • 但是如果多個地方都需要顯示完整的名稱,我們就需要寫多個

基本使用:

image-20210513211216765

效果圖:

image-20210513211228456

複雜操作:

image-20210513212220412

結果:

image-20210513212247646

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  {{totalPrice}}
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      books:[
        {id:110, name: 'Java', price: 100},
        {id:111, name: 'Python', price: 100},
        {id:112, name: 'Vue', price: 100},
        {id:113, name: 'C', price: 100},
      ]
    },
    // computed: 計算機屬性()
    computed:{
      totalPrice: function (){
        let result = 0
        for (let i = 0; i < this.books.length; i++) {
           result += this.books[i].price;
        }
        return resultA
        // 這兩種是es6語法當中的
      //   for (let i in this.books) {
      //     result += this.books[i].price
      //   }
      //   for (let book of this.books) {
      //     result += book.price
      //   }
      }
    }
  });
</script>
</body>
</html>

3.3 computed和methods的對比

你可能已經注意到我們可以透過在表示式中呼叫方法來達到同樣的效果:

<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在元件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

我們可以將同一函式定義為一個方法而不是一個計算屬性。兩種方式的最終結果確實是完全相同的。然而,不同的是計算屬性是基於它們的響應式依賴進行快取的。只在相關響應式依賴發生改變時它們才會重新求值。這就意味著只要 message 還沒有發生改變,多次訪問 reversedMessage 計算屬性會立即返回之前的計算結果,而不必再次執行函式。

這也同樣意味著下面的計算屬性將不再更新,因為 Date.now() 不是響應式依賴:

computed: {
  now: function () {
    return Date.now()
  }
}

相比之下,每當觸發重新渲染時,呼叫方法將總會再次執行函式。

我們為什麼需要快取?假設我們有一個效能開銷比較大的計算屬性 A,它需要遍歷一個巨大的陣列並做大量的計算。然後我們可能有其他的計算屬性依賴於 A。如果沒有快取,我們將不可避免的多次執行 A 的 getter!如果你不希望有快取,請用方法來替代。

總結:

computed:會進行快取,如果多次使用時,計算屬性只會呼叫一次。

methods: 呼叫一次執行一次

3.4 v-on

概述:
在前端開發中,我們需要經常和用於互動。

  • 這個時候,我們就必須監聽使用者發生的時間,比如擊、拖拽、鍵盤事件等等
  • 在Vue中如何監聽事件呢?使用v-on指令v-on介紹

v-on介紹:

  • 作用:繫結事件監聽器
  • 縮寫:@
  • 預期:Function |Inline Statement|Object
  • 引數:event

基本使用

image-20210514152517666

上面這種方法,適合簡單的事件繫結,如果我們有其他的功能實現這種寫法就不太好,所以我推薦下面這種寫法

image-20210514152900191

當然,也可以用語法糖的方式進行編寫

image-20210514152957124

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h2>{{number}}</h2>
  <!-- 簡單的使用 click:滑鼠點選事件 -->
<!--  <button v-on:click="number++">+</button>-->
<!--  <button v-on:click="number&#45;&#45;">-</button>-->
<!--  <button v-on:click="increment">+</button>-->
<!--  <button v-on:click="decrement">-</button>-->
  <button @:click="increment">+</button>
  <button @:click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      number: 10 // 定義一個引數
    },
    methods:{
      increment() {
        this.number++
      },
      decrement() {
        this.number--
      }
    }
  });
</script>
</body>
</html>

v-on還可以進行傳引數

image-20210514154932579

如果你需要傳遞引數就記得新增(),如果你不需要傳遞引數就不用新增()

image-20210514155154847

如果不知道什麼是MouseEvent物件的話:

https://blog.csdn.net/claroja/article/details/103990202

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <!-- 傳遞引數 -->
  <button @click="btnClick(123)">按鈕1</button>
<!-- 如果方法定義了一個引數,我們這裡不傳遞引數的話,它會傳遞一個MouseEvent物件 -->
  <button @click="btnClick">按鈕2</button>
  <!-- 我們這裡加了括號沒有傳遞引數的話,形參就是undefined-->
  <button @click="btnClick()">按鈕3</button>

</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    methods: {
      btnClick(name) {
        console.log(name)
      }
    }
  });
</script>
</body>
</html>

v-on的修飾符:

  • .stop - 呼叫event.stopPropagation()
  • .prevent - 呼叫event.preventDefault()
  • .{keyCode | keyAlias} 只當時間是從特定鍵觸發時才觸發回撥
  • .native - 監聽元件根元素的原生事件
  • .once - 只觸發一次回撥

基本使用:

image-20210514161424397

效果圖:

image-20210514161509466

如果我們想組織這種冒泡事件可以使用.stop

image-20210514161611243

效果圖:

image-20210514161621844

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <div @click="divClick">
    aaa
    <!--  當我們點選這個按鈕時,它會出現冒泡事件  -->
    <button @click.stop="btnClick">按鈕</button>
  </div>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    methods: {
      btnClick() {
        console.log("btnClick")
      },
      divClick() {
        console.log("divClick")
      }
    }
  });
</script>
</body>
</html>

4. 條件判斷

4.1 v-if v-else-if v-else

v-if 指令用於條件性地渲染一塊內容。這塊內容只會在指令的表示式返回true 值的時候被渲染。

基本使用:

image-20210514162527417

效果圖:

image-20210514162855046

image-20210514162913593

v-else的使用

image-20210514163151073

效果圖:

image-20210514163202247

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h1 v-if="isShow">{{message}}</h1>
  <h1 v-else>isShow為false的時候你才能看到我</h1>
  <button @click="isShow_function">按鈕</button>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      isShow: true
    },
    methods: {
      isShow_function() {
        this.isShow = !this.isShow
        console.log(this.isShow)
      }
    }
  });
</script>
</body>
</html>

4.2 v-show

v-show和v-if非常相似,也用於決定一個元素是否渲染

v-if和v-show對比

  • v-if和v-show都可以決定一個元素是否渲染,那麼開發中我們如何選擇?

    • v-if當條件為false時,壓根不會有對應的元素在DOM中
    • v-show當條件為false時,僅僅是將元素的display屬性設定為none而已
  • 開發中如何選擇?

    • 當需要在顯示與隱藏之間切片很頻繁時,使用v-show
    • 但只有一次切換時,使用v-if

    基本使用:

    image-20210514164411046

效果圖:

image-20210514164425942

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <!-- v-if當條件為false時,壓根不會有對應的元素在DOM中 -->
  <p v-if="isShow">{{message}} v-if</p>
  <!-- v-show為false時,僅僅是將元素的display屬性設定為none而已 -->
  <p v-show="isShow">{{message}} v-show</p>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      isShow: true
    }
  });
</script>
</body>
</html>

5. 迴圈遍歷

5.1 v-for

當我們有一組資料需要渲染時,我們就可以使用v-for

  • v-for的語法類似於JavaScript中的for迴圈
  • 格式:item in itmes的形式

如果在遍歷的過程中,我們需要拿到元素在陣列的中的索引值

  • 語法格式: v-for = (item, index) in items
  • 其中的index就代表了取出的item在原陣列中的索引值

基本使用:

image-20210514165328625

效果圖:

image-20210514165339356

當然也可以遍歷物件

image-20210514165820453

效果圖:

image-20210514165832190

如果想拿到key的話,可以這樣:

image-20210514170030270

效果圖:

image-20210514170038110

注意:遍歷陣列拿下標,item在前,index在後, 遍歷物件拿key的話, values在前, key在後

6.表單繫結

6.1 v-model

Vue中使用v-model指令來實現表單元素和資料的雙向繫結

image-20210514205554777

效果圖:

image-20210514205604277

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="text" v-model="message">
  {{message}}
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    }
  });
</script>
</body>
</html>

v-model其實是一個語法糖,他的背後本質上是包含兩個操作:

  • v-bind繫結一個value屬性
  • v-on指令給當前元素繫結input事件

image-20210514205927500

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="text" v-bind:value="message" v-on:input="message=$event.target.value">
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    }
  });
</script>
</body>
</html>

我們可以使用v-model結合radio使用:

image-20210514210438944

效果圖:

image-20210514210450467

也可以配合checkbox:

image-20210514210933800

效果圖:

image-20210514210949517

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="checkbox" value="LXL" v-model="hobbies">LXL
  <input type="checkbox" value="LOL" v-model="hobbies">LOL
  <input type="checkbox" value="LkL" v-model="hobbies">LKL
  <input type="checkbox" value="LPL" v-model="hobbies">LPL
  <br>
  <h2>你的愛好:{{hobbies}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      hobbies: []
    }
  });
</script>
</body>
</html>

6.2 值繫結

值繫結的意思就是給value賦值

  • 我們前面的value中的值,可以回頭看一下,都是在定義input的時候直接給定的
  • 但是真實開發中,這些input的值可能是從網路獲取或定義data中的
  • 所以我們可以透過v-bind:value動態給value繫結值

image-20210514212235158

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="checkbox" value="LXL" v-model="hobbies">LXL
  <input type="checkbox" value="LOL" v-model="hobbies">LOL
  <input type="checkbox" value="LkL" v-model="hobbies">LKL
  <input type="checkbox" value="LPL" v-model="hobbies">LPL
  <br>
  <h2>你的愛好:{{hobbies}}</h2>
<!-- 我們透過v-for迴圈遍歷my_hobbies並且生成input標籤 在透過v-bind繫結值 -->
  <label v-for="item in my_hobbies" :for="item">
    <!--  我們在透過v-bind繫結item所遍歷的值, 在透過v-model進行雙向繫結  -->
    <input type="checkbox" :value="item" v-model="hobbies">{{item}}
  </label>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      hobbies: [],
      my_hobbies: ['LXL', 'LOL', 'LKL', 'LPL']
    }
  });
</script>
</body>
</html>

6.3 修飾符

lazy修飾符:

  • lazy修飾符可以讓資料在失去焦點或者回車時才會更新

number修飾符:

  • number修飾符可以讓在輸入框中輸入的內容自動轉成數字型別

trim修飾符:

  • trim修飾符可以過濾內容左右兩邊的空格

7. 元件化開發

7.1 什麼是元件化?

人面對複雜問題的處理方式:

  • 任何一個人處理資訊的邏輯能力都是有限的
  • 所以,當面對一個非常複雜的問題時,我們不太可能一次性搞定一大堆的內容。
  • 但是,我們人有一種天生的能力,就是將問題進行拆解。
  • 如果將一個複雜的問題,拆分成很多個可以處理的小問題,再將其放在整體當中,你會發現大的問題也會迎刃而解。

元件化也是類似的思想:

  • 如果我們將一個頁面中所有的處理邏輯全部放在一起,處理起來就會變得非常複雜,而且不利於後續的管理以及擴充套件。
  • 但如果,我們講一個頁面拆分成一個個小的功能塊,每個功能塊完成屬於自己這部分獨立的功能,那麼之後整個頁面的管理和維護就變得非常容易了。

image-20210514213558620

7.2 Vue元件化思想

元件化是Vue.js中的重要思想

  • 他提供了一中抽象,讓我們可以開發出一個個獨立可複用的小元件來構造我們的應用

  • 任何的應用都會被抽象成一顆元件樹

    Component Tree

元件化思想的應用:

  • 有了元件化的思想,我們在之後的開發中就要充分的利用它
  • 儘可能的將頁面拆分成一個個小的、可複用的元件
  • 這樣讓我們的程式碼更加方便組織和管理,並且擴充套件性也更強

7.3 元件化的基本步驟

  1. 建立元件構造器

    Vue.extend0:

    • 呼叫Vue.extend0建立的是一個元件構造器。
    • 通常在建立元件構造器時,傳入template代表我們自定義元件的模板。
    • 該模板就是在使用到元件的地方,要顯示的HTML程式碼。
    • 事實上,這種寫法在Vue2.x的檔案中幾乎已經看不到了,它會直接使用下面我們會講到的語法糖,但是在很多資料還是會提到這種方式,而且這種方式是學習後面方式的基礎。
  2. 註冊元件

    Vue.component():

    • 呼叫Vue.component0是將剛才的元件構造器註冊為一個元件,並且給它起一個元件的標籤名稱。

    • 所以需要傳遞兩個引數:1、註冊元件的標籤名 2、元件構造器

  3. 使用元件

    • 元件必須掛載在某個Vue例項下,否則它不會生效。

image-20210514214218082

image-20210514221232821

效果圖:

image-20210514221245174

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
<!-- 使用元件 -->
  <my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
<!-- 1.建立元件構造器物件 -->
  const cpnC = Vue.extend({
    template: `
    <div>
      <h2>我是標題</h2>
      <p>我是內容1</p>
      <p>我是內容2</p>
    </div>
    `
  })
  // 2. 註冊元件
  Vue.component('my-cpn', cpnC)
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    }
  });
</script>
</body>
</html>

7.4 全域性元件和區域性元件

我們上面建立的就是全域性元件,全域性元件就是可以在多個Vue例項裡面使用

image-20210515104805783

效果圖:

image-20210515104918977

那麼我們如何建立區域性元件? 其實建立區域性元件也很簡單,把要註冊的元件放到某個Vue例項裡面註冊就好了

image-20210515105554781

效果圖:

image-20210515105614009

我們會發現標籤只在

裡面有效,這就是區域性元件

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <cpn></cpn>
  <cpn></cpn>
</div>

<div id="app1">
  <cpn></cpn>
</div>
<script src="../js/vue.js"></script>
<script>
  <!-- 1.建立元件構造器物件 -->
  const cpnC = Vue.extend({
    template: `
    <div>
      <h2>我是標題</h2>
      <p>我是內容1</p>
      <p>我是內容2</p>
    </div>
    `
  })
  // 註冊元件(意味著可以在多個Vue例項中使用)
  // Vue.component("my-cpn", cpnC)

  // 如何註冊區域性元件?
  // 我們只需要在某個Vue例項裡面註冊即可
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    // components:元件,component的複數,表示可以使用多次
    components: {
      // cpn:使用元件的標籤名
      cpn: cpnC
    }
  });
  // 建立一個vue例項
  let app1 = new Vue({
    el: '#app1'
  })
</script>
</body>
</html>

7.5 父元件和子元件

什麼是父元件,什麼又是子元件。簡單來說:我們把某段程式碼封裝成了一個元件,而這個段元件裡面又引入另一個元件,我們把引入封裝的元件叫做父元件,把被引入的元件叫做子元件

image-20210515112959373

效果圖:

image-20210515113026145

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <cpn></cpn>
</div>
<script src="../js/vue.js"></script>
<script>
<!-- 註冊子元件 -->
  const cpnC2 = Vue.extend({
    template: `
     <div>
      <h2>我是子元件</h2>
      <p>我是子元件的內容</p>
    </div>
    `
  })
  // 註冊父元件
  const cpnC1 = Vue.extend({
    template: `
    <div>
      <h2>我是父元件</h2>
      <p>我是父元件的內容</p>
<!--  // 但解析到這一步的時候,它會先去你Vue例項components裡面找你是否註冊了cpn2-->
<!--  // 如果沒有找到他才會在cpnC1components去找-->
      <cpn2></cpn2>
    </div>
    `,
    // 把子元件註冊到父元件
    components: {
      cpn2: cpnC2
    },
  })
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    components: {
      cpn: cpnC1
    }
  });
</script>
</body>
</html>

7.6 註冊元件的語法糖方式

我們之前註冊元件的方式,會覺得有些繁瑣

  • Vue為了簡化這個過程,提供了註冊的語法糖
  • 主要是省去了調傭Vue.extend()的步驟,而是可以直接使用一個物件來替換

image-20210515114939573

效果圖:

image-20210515114949705

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <!-- 使用元件 -->
  <cpn></cpn>
</div>
<script src="../js/vue.js"></script>
<script>
  // component會跳用Vue.extend來建立元件
  // 所以我們以後可以使用這種語法糖模式來建立全域性元件
  Vue.component('my-cpn', {
    template: `
    <div>
      <h2>元件</h2>
      <p>元件的內容</p>
    </div>
    `
  })
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    //  區域性元件
    components: {
      cpn:{
        template: `
        <div>
          <h2>元件</h2>
          <p>元件的內容</p>
        </div>
    `
      }
    }
  });
</script>
</body>
</html>

7.7 元件模板抽離

我們之前雖然簡化了Vue元件的註冊過程,另外還有一個地方的寫法比較麻煩,就是template模板的寫法

如果我們能將其中的html分離出來寫,然後掛載到對應的元件上,必然結構會變得非常清晰

Vue提供了兩種方案來定義HTML模組內容:

  • 使用標籤
  • 使用

相關文章