1. 程式人生 > 其它 >CSRF Failed: CSRF token missing or incorrect

CSRF Failed: CSRF token missing or incorrect

Vue學習筆記

一切Vue專案都從一個vue例項開始

var vm = new Vue()

<body>
    <div id="app">
      {{ message }} {{ date }}
    </div>
  </body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: "#app",
      data() {
        return {
          message: 'Hello Imooc !'
        }
      }
    })
  </script>

1.指令都帶有 v- 字首

<div v-text="message"></div>
var vm = new Vue({
	el: '#app',
  data: {
  	message: "Hello!"
  },
})

<div v-html="message"></div>
var vm = new Vue({
    el: '#app',
    data: {
    	message: "<div>您好,我是小慕!</div>",
    }
  })

v-bind後面是 :屬性名=[變數名]。例如:v-bind:title="message"

v-bind 的簡寫方式,可以直接通過:屬性名的方式

<div>
      <img :src="src"/>
    </div>

v-for 對陣列

<ul>
      <li v-for="item in music">{{item.name}}</li>
 </ul>

  • v-for="(value, name, index) in object"

    value為值,name為key,index為索引

    為了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一 key

    attribute:

    <div v-for="item in items" v-bind:key="item.id">
      <!-- 內容 -->
    </div>
    

    建議儘可能在使用 v-for 時提供 key attribute,除非遍歷輸出的 DOM 內容非常簡單,或者是刻意依賴預設行為以獲取效能上的提升。

    從 2.6.0 開始,可以用方括號括起來的 JavaScript 表示式作為一個指令的引數:

    <!--
    注意,引數表示式的寫法存在一些約束,如之後的“對動態引數表示式的約束”章節所述。
    -->
    <a v-bind:[attributeName]="url"> ... </a>
    

    <a v-bind:[someAttr]="value"> ...


    vue提供了v-ifv-show兩個指令來控制頁面元素的顯示和隱藏

    不同點v-if:根據表示式的值在 DOM 中生成或移除一個元素。

    v-show:根據表示式的值通過樣式的改變來顯示或者隱藏 HTML 元素。


    <div v-if="number === 1">
          A
    </div>
    <div v-else-if="number === 2">
          B
    </div>
    <div v-else>
         C
    </div>
    

    vue 中提供了指令 v-on 來進行事件的繫結。用法:v-on:事件名="方法",例如:v-on:click=“alert”。

     <button v-on:click="hello">hello</button>
    

    v-on提供了簡寫方式,只需要通過@事件型別的方式就可以了。例如:@click="hello"

    可一次執行多個方法

    @click="add,delete"


    vue通過了指令v-model來實現資料的雙向繫結

     <div id="app">
        <div>
          <label>年齡:</label>
          <input v-model="age"/>
        </div>
        <div>當前輸入的年齡是: {{age}}</div>
        <button @click="add">加一歲</button>
        <button @click="alertYear">彈出年齡</button>
      </div>
    
    var vm = new Vue({
    	el: '#app',
      data: {
      	age: 10
      },
      methods: {
        add(){
        	this.age = this.age + 1;
        },
        alertYear() {
        	alert(this.age)
        }
      }
    })
    

    使用 Object.freeze(),這會阻止修改現有的 property,也意味著響應系統無法再追蹤變化。

    v-pre

    該指令會跳過所在元素和它的子元素的編譯過程,也就是把這個節點及其子節點當作一個靜態節點來處理,

    也就是說不進行Vue的分析,只是單純的html語句

    <div v-pre>當前輸入的年齡是: {{age}}</div>
    <div>當前輸入的年齡是: {{age}}</div>
    

    當前輸入的年齡是: {{age}}
    當前輸入的年齡是: 10


    v-once

    模板只會在第一次更新時顯示資料,此後再次更新該DOM裡面引用的資料時,內容不會自動更新

    通過使用 v-once 指令,你也能執行一次性地插值,當資料改變時,插值處的內容不會更新。但請留心這會影響到該節點上的其它資料繫結:

    <span v-once>這個將不會改變: {{ msg }}</span>
    

    通過傳給 v-bind:class 一個物件,以動態地切換 class:

    <div v-bind:class="{ show: isShow }"></div>
    

    show 這個 class 存在與否將取決於資料屬性 isShow 是否為真值。

    與angular類似

    <div [ngClass]="{'active': isActive, 'primary': isFocus}">ngClass</div>
    

    2.樣式繫結

    逗號分隔

    <div v-bind:style="{ backgroundColor: backgroundColor, width: width + 'px' }"></div>
    
    <div v-bind:style="[stylesA, stylesB]"></div>
    
    stylesA: {
          "background-color": 'red',
          width: '300px'
        },
        stylesB: {
          color: '#fff',
          height: '300px'
        }
    

    3.計算屬性

    每一個計算屬性都包含一個 getter 和一個 setter

    計算屬性預設只有 getter,不過在需要時你也可以提供一個 setter

    當手動修改計算屬性的值就像修改一個普通資料那樣時,就會觸發 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]
        }
      }
    }
    // ...
    

    既然 methods 同樣可以解決模板中複雜邏輯計算的問題,那麼為什麼還需要使用計算屬性呢?

    原因就是:計算屬性是基於它的依賴快取的。前面我們介紹過,計算屬性的改變取決於其所依賴資料的變化,所以只要依賴資料不發生改變,計算屬性就不會更新。當我們重複獲取計算屬性時它也不會重複計算,只會獲取快取的值。而我們每次呼叫 methods 都會重新計算一遍,這樣將會消耗一部分效能。當然,如何你不希望對資料進行快取,那麼可以用方法來代替。

     <h1>商品總價:{{totalPrice()}} 元</h1> 
     methods: {
      	totalPrice() {
      		return this.count * this.unitPrice
      	}
      }
    
    <h1>商品總價:{{totalPrice}} 元</h1> 
     computed: {
      	totalPrice() {
      		return this.count * this.unitPrice
      	}
      }
    

    4.例項 property 與方法

    Vue 例項還暴露了一些有用的例項 property 與方法。它們都有字首 $,以便與使用者定義的 property 區分開來。例如:

    var data = { a: 1 }
    var vm = new Vue({
      el: '#example',
      data: data
    })
    
    vm.$data === data // => true
    vm.$el === document.getElementById('example') // => true
    
    // $watch 是一個例項方法
    vm.$watch('a', function (newValue, oldValue) {
      // 這個回撥將在 `vm.a` 改變後呼叫
    })
    

    5.監聽器

    var vm = new Vue({
      el: '#app',
      data() {
        return {
          count: 0
        }
      },
      watch: {
        count: function(newVal, oldVal) {
          // 具體處理邏輯
        },
      }
    })
    
    <div>商品名稱:<input v-model="product.name"/></div>
    
    watch: {
            product: function(newValue){
              console.log(newValue)
            }
          }
    

    或者使用handle處理

     watch: {
    	      name: {
    	        handler(newVal, oldVal) {
    	          console.log(newVal)
    	        }
    	      }
    	    }
    

    在偵聽器最初繫結的時候就觸發一次

    watch: {
            name: {
              handler(newVal, oldVal) {
                console.log(newVal)
              },
              // 代表在wacth裡聲明瞭name這個方法之後立即先去執行一次handler方法
              immediate: true
            }
          }
    

    deep 屬性代表是否深度監聽,預設值是 false。當設定為 true 時,會對物件裡面的每個屬性進行偵聽。

     watch: {
            product: {
              handler: function(newVal) {
                console.log(newVal)
              },
              deep: true
            }
          }
    

    監聽器會一層層的往下遍歷,給物件的所有屬性都加上這個監聽器,修改物件裡面任何一個屬性都會觸發這個監聽器裡的 handler。

    通常更好的做法是使用計算屬性而不是命令式的 watch 回撥

    事件修飾符

    Vue 提供了以下事件修飾符:

    1. .stop: 阻止單擊事件繼續傳播;例如內部button點選觸發事件,不會傳播給父按鈕

    2. .prevent: 只有修飾符,提交事件不再過載頁面。

    3. .capture: 新增事件監聽器時使用事件捕獲模式,即元素自身觸發的事件先在自身處理,然後交由內部元素進行處理;子按鈕點選,先出觸發父元素的點選事件,再觸發子按鈕的點選事件

    4. .self: 只有在event.target是當前元素自身時觸發處理函式,即事件不是從內部元素觸發的;

    5. .once: 點選事件將只在最開始時觸發一次

    6. .passive: 滾動事件會立即觸發,不會等待其他串聯事件。即prevent會失效。

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

      不要把 .passive.prevent 一起使用,因為 .prevent 將會被忽略,同時瀏覽器可能會向你展示一個警告。請記住,.passive 會告訴瀏覽器你不想阻止事件的預設行為。

    按鍵修飾符

    在監聽鍵盤事件時,我們經常需要檢查詳細的按鍵

    <!-- 只有在 `key` 是 `Enter` 時呼叫 `vm.submit()` -->
    <input @keyup.enter="submit" />
    

    Vue 為最常用的鍵提供了別名:

    • .enter
    • .tab
    • .delete (捕獲“刪除”和“退格”鍵)
    • .esc
    • .space
    • .up
    • .down
    • .left
    • .right

    系統修飾鍵

    可以用如下修飾符來實現僅在按下相應按鍵時才觸發滑鼠或鍵盤事件的監聽器。

    • .ctrl
    • .alt
    • .shift
    • .meta

    .exact 修飾符

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

    <!-- 即使 Alt 或 Shift 被一同按下時也會觸發 -->
    <button @click.ctrl="onClick">A</button>
    
    <!-- 有且只有 Ctrl 被按下的時候才觸發 -->
    <button @click.ctrl.exact="onCtrlClick">A</button>
    
    <!-- 沒有任何系統修飾符被按下的時候才觸發 -->
    <button @click.exact="onClick">A</button>
    

    滑鼠按鈕修飾符

    • .left
    • .right
    • .middle

    這些修飾符會限制處理函式僅響應特定的滑鼠按鈕。

    2.動畫

    <style>
        .fade-enter-active, .fade-leave-active {
          transition: opacity 3s
        }
        .fade-enter, .fade-leave-to {
          opacity: 0
        }
    </style>
    
     <transition name="fade">
          <p v-show = "show" >hello !</p>
        </transition>
    

    3.生命週期

    • beforeCreate(建立前)
    • created(建立後)
    • beforeMount(載入前)
    • mounted(載入後)
    • beforeUpdate(更新前)
    • updated(更新後)
    • beforeDestroy(銷燬前)
    • destroyed(銷燬後)

    3.1. 建立前(beforeCreate)

    在例項初始化之後,此時的資料觀察和事件機制都未形成,不能獲得 DOM節點。

    3.2. 建立後(created)

    例項已經建立完成之後被呼叫。在這一步,例項已完成以下的配置:資料觀測(data observer),屬性和方法的運算, watch/event 事件回撥。然而,掛載階段還沒開始。

    3.3. 載入前(beforeMount)

    在掛載開始之前被呼叫:這個過程是在模版已經在記憶體中編譯完成, render 函式首次被呼叫,此時完成了虛擬 DOM 的構建,但並未被渲染

    3.4. 載入後(mounted)

    這個過程在模版掛載之後被呼叫,頁面完成渲染,在這之後所以我們可以操作和訪問 DOM 元素

    3.5. 更新前(beforeUpdate)

    當資料更新時呼叫,在這一階段 DOM 會和更改過的內容同步

    3.6. 更新後(updated)

    由於資料更改導致的虛擬 DOM 重新渲染和打補丁,在這之後會呼叫該鉤子。

    當這個鉤子被呼叫時,元件 DOM 已經更新,所以你現在可以執行依賴於 DOM 的操作。然而在大多數情況下,你應該避免在此期間更改狀態,因為這可能會導致更新無限迴圈。

    3.7. 銷燬前(beforeDestroy)

    例項銷燬之前呼叫。在這一步,例項仍然完全可用。

    3.8. 銷燬後(destroyed)

    Vue 例項銷燬後呼叫。呼叫後,Vue 例項指示的所有東西都會解繫結,所有的事件監聽器會被移除,所有的子例項也會被銷燬。

    例子

    {{ name }}

    4.元件

    全域性註冊

      <div id="app">
        <my-component></my-component>
        <my-component /> 
      </div>
    
    <script type="text/javascript">
      Vue.component('myComponent', {
        template: '<div>Hello !</div>'
      })
      var vm = new Vue({
        el: '#app',
        data() {
        	return {}
        }
      }
    </script>
    

    3.0版本

    const app = Vue.createApp({})
    
    app.component('component-a', {
      /* ... */
    })
    

    區域性註冊

    可以通過一個普通的 JavaScript 物件來定義元件:

    const ComponentA = {
      /* ... */
    }
    const ComponentB = {
      /* ... */
    }
    const ComponentC = {
      /* ... */
    }
    

    然後在 components 選項中定義你想要使用的元件:

    const app = Vue.createApp({
      components: {
        'component-a': ComponentA,
        'component-b': ComponentB
      }
    })
    

    真實情況:

    <template>
      <img alt="Vue logo" src="./assets/logo.png">
      <HelloWorld msg="Welcome to Your Vue.js App"/>
    </template>
    
    <script>
    import HelloWorld from './components/HelloWorld.vue'
    
    export default {
      name: 'App',
      components: {//引入元件
        HelloWorld
      }
    }
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    
    

    5.父元件傳值給子元件

    1.通過 props 傳遞資料給子元件(單向)

    父元件通過 props 屬性向子元件傳遞資料。子元件利用元件例項的 props 屬性定義元件需要接收的引數,在使用元件時通過 attribute的方式傳入引數,也可以直接將整個父元件傳入子元件

    // 在子元件內定義元件接收一個引數 name
    {
      props: ['name',"home"]
    }
    // 父元件使用元件時傳遞引數 name
    <child :name="name" :home="this"></child>
    
    props: {
          name: {
            type: String,
            default: '句號'
          }
        }
    

    2.parent獲取父元件資料(可以修改子元件的資料)

    this.$parent.屬性/方法
    

    6.子元件傳值給父元件

    1.通過 $emit 傳遞資料給父元件

    子元件通過 $emit 傳遞事件給父元件,父元件通過 $on 監聽事件:

    // 子元件定義事件
    this.$emit('事件名稱', '傳遞的引數') //例: this.$emit('add', 111)
    
    // 父元件監聽事件的觸發
    <child  @事件名稱="事件觸發的方法"/>//<child  @add="change"/>  change(number){this.a+=number}
        //<child  @add="a+=$event"/>
    

    或者 父級元件可以像處理 native DOM 事件一樣通過 v-on@ 監聽子元件例項的任意事件:

    1.1驗證丟擲的事件

    要新增驗證,將為事件分配一個函式,該函式接收傳遞給 $emit 呼叫的引數,並返回一個布林值以指示事件是否有效。

    注意:驗證是否有效並不能阻止子元件將資料傳入父元件

    app.component('custom-form', {
      emits: {
        // 沒有驗證
        click: null,
    
        // 驗證submit 事件
        submit: ({ email, password }) => {
          if (email && password) {
            return true
          } else {
            console.warn('Invalid submit event payload!')
            return false
          }
        }
      },
      methods: {
        submitForm() {
          this.$emit('submit', { email, password })
        }
      }
    })
    

    2.呼叫子元件時通過ref(可以修改父元件的資料)

    <componenta ref="a"><componenta />
    

    父元件獲取

    this.$refs.a.屬性/方法
    

    3.v-model在元件上的使用

    app.component('custom-input', {
      props: ['modelValue'],
      template: `
        <input
          :value="modelValue"
          @input="$emit('update:modelValue', $event.target.value)"
        >
      `
    })
    
    <custom-input v-model="searchText"></custom-input>
    
    const app = Vue.createApp({})
    
    app.component('my-component', {
      props: {
        foo: String
      },
      template: `
        <input 
          type="text"
          :value="foo"
          @input="$emit('update:foo', $event.target.value)">
      `
    })
    
    <my-component v-model:foo="bar"></my-component>
    

    7.非父子元件間資料傳遞

    • 對於兄弟元件的資料通訊:它們有共同的父元件,我們可以通過父元件傳遞的方式實現資料通訊。

    • 對於子孫元件的資料通訊:可以通過 props 的方式向下逐層傳遞下去,也可以通過 $emit 將事件向上逐層傳遞。

    • 對於非關係元件的資料通訊:通過使用一個空的Vue例項作為中央事件匯流排。

    // 定義事件匯流排
    let bus = new Vue()
    Vue.prototype.bus = bus
    
    // 定義傳送事件
    this.bus.$emit('事件名稱', data)
    
    // 定義接收事件 並在回撥中接收引數
    this.bus.$on('事件名稱', (data) => {      
    })
    
    

    8.動態元件如何使用

    通過使用保留的 <component> 元素,動態地把元件名稱繫結到它的 is 特性,可以實現動態元件:

    <component :is="currentView"></component>
    <button @click="changeView('A')">切換到A</button>
    <button @click="changeView('B')">切換到B</button>
    <button @click="changeView('C')">切換到C</button>
    

    keep-alive

    keep-aliveVue 提供的一個抽象元件,用來對元件進行快取,從而節省效能,由於是一個抽象元件,所以在頁面渲染完畢後不會被渲染成一個 DOM 元素。被 keep-alive 快取的元件只有在初次渲染時才會被建立(若該元件是第一次渲染,會觸發 created 事件,當再次切換顯示該元件時,created 事件不會再次觸發。),並且當元件切換時不會被銷燬(通過修改 currentView 切換元件時,元件的 beforeDestroy 事件不會觸發)。

     <keep-alive>
          <component :is="currentView"></component>
    </keep-alive>
    

    activated 和 deactivated 生命週期

    activated 和 deactivated 和我們之學習的生命週期函式一樣,也是元件的生命週期函式。不過, activateddeactivated 只在 <keep-alive> 內的所有巢狀元件中觸發。activated:進入元件時觸發。deactivated:退出元件時觸發。

    include 和 exclude

    includeexclude 是 keep-alive 的兩個屬性,允許元件有條件地快取。
    include: 可以是字串或正則表示式,用來表示只有名稱匹配的元件會被快取
    exclude: 可以是字串或正則表示式,用來表示名稱匹配的元件不會被快取

    <keep-alive include="ComponentA,ComponentB">
          <component :is="currentView"></component>
    </keep-alive>
    

    9.key管理複用元素

    Vue 為你提供了一種方式來表達“這兩個元素是完全獨立的,不要複用它們”。只需新增一個具有唯一值的 key attribute 即可:

    <template v-if="loginType === 'username'">
      <label>Username</label>
      <input placeholder="Enter your username" key="username-input">
    </template>
    <template v-else>
      <label>Email</label>
      <input placeholder="Enter your email address" key="email-input">
    </template>
    

    現在,每次切換時,輸入框都將被重新渲染

    VUE3

    1.建立

    const App = {
      data() {
        return {
          groceryList: [
            { id: 0, text: 'Vegetables' },
            { id: 1, text: 'Cheese' },
            { id: 2, text: 'Whatever else humans are supposed to eat' }
          ]
        }
      }
    }
    
    const app = Vue.createApp(App)//建立vue例項
    //新增元件
    app.component('todo-item', {
      props: ['todo'],
      template: `<li>{{ todo.text }}</li>`
    })
    
    const vm=app.mount('#components-app')//返回的是 根元件例項
    

    2.防抖

    可以在生命週期鉤子的 created 裡新增該防抖函式:

    app.component('save-button', {
      created() {
        // 用 Lodash 的防抖函式
        this.debouncedClick = _.debounce(this.click, 500)
      },
      unmounted() {
        // 移除元件時,取消定時器
        this.debouncedClick.cancel()
      },
      methods: {
        click() {
          // ... 響應點選 ...
        }
      },
      template: `
        <button @click="debouncedClick">
          Save
        </button>
      `
    })
    

    3.陣列更新檢測

    #變更方法

    Vue 將被偵聽的陣列的變更方法進行了包裹,所以它們也將會觸發檢視更新。這些被包裹過的方法包括:

    • push()
    • pop()
    • shift()
    • unshift()
    • splice()
    • sort()
    • reverse()

    你可以開啟控制檯,然後對前面例子的 items 陣列嘗試呼叫變更方法。比如 example1.items.push({ message: 'Baz' })

    #替換陣列

    變更方法,顧名思義,會變更呼叫了這些方法的原始陣列。相比之下,也有非變更方法,例如 filter()concat()slice()。它們不會變更原始陣列,而總是返回一個新陣列。當使用非變更方法時,可以用新陣列替換舊陣列:

    example1.items = example1.items.filter(item => item.message.match(/Foo/))
    

    你可能認為這將導致 Vue 丟棄現有 DOM 並重新渲染整個列表。幸運的是,事實並非如此。Vue 為了使得 DOM 元素得到最大範圍的重用而實現了一些智慧的啟發式方法,所以用一個含有相同元素的陣列去替換原來的陣列是非常高效的操作。

    4.v-for

    方法

    在計算屬性不適用的情況下 (例如,在巢狀 v-for 迴圈中) 你可以使用一個方法:

    <ul v-for="numbers in sets">
      <li v-for="n in even(numbers)">{{ n }}</li>
    </ul>
    
    data() {
      return {
        sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
      }
    },
    methods: {
      even(numbers) {
        return numbers.filter(number => number % 2 === 0)
      }
    }
    

    v-for 裡使用值的範圍

    v-for 也可以接受整數。在這種情況下,它會把模板重複對應次數。

    <div id="range" class="demo">
      <span v-for="n in 10">{{ n }} </span>
    </div>
    

    v-forv-if 一同使用

    當它們處於同一節點,v-if 的優先順序比 v-for 更高,這意味著 v-if 將沒有許可權訪問 v-for 裡的變數

    多事件處理器

    事件處理程式中可以有多個方法,這些方法由逗號運算子分隔:

    <!-- 這兩個 one() 和 two() 將執行按鈕點選事件 -->
    <button @click="one($event), two($event)">
      Submit
    </button>
    

    5.表單輸入繫結

    v-model 在內部為不同的輸入元素使用不同的 property 並丟擲不同的事件:

    • text 和 textarea 元素使用 value property 和 input 事件;
    • checkbox 和 radio 使用 checked property 和 change 事件;
    • select 欄位將 value 作為 prop 並將 change 作為事件。

    在文字區域插值不起作用,應該使用 v-model 來代替。

    <!-- bad -->
    <textarea>{{ text }}</textarea>
    
    <!-- good -->
    <textarea v-model="text"></textarea>
    

    修飾符

    #.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" />
    

    6.Props傳值

    給 prop 傳入一個靜態的值:

    <blog-post title="My journey with Vue"></blog-post>
    

    通過 v-bind 或簡寫 : 動態賦值(JavaScript表示式),例如:

    <!-- 動態賦予一個變數的值 -->
    <blog-post :title="post.title"></blog-post>
    
    <!-- 動態賦予一個複雜表示式的值 -->
    <blog-post :title="post.title + ' by ' + post.author.name"></blog-post>
    

    7.Prop 驗證

    app.component('my-component', {
      props: {
        // 基礎的型別檢查 (`null` 和 `undefined` 會通過任何型別驗證)
        propA: Number,
        // 多個可能的型別
        propB: [String, Number],
        // 必填的字串
        propC: {
          type: String,
          required: true
        },
        // 帶有預設值的數字
        propD: {
          type: Number,
          default: 100
        },
        // 帶有預設值的物件
        propE: {
          type: Object,
          // 物件或陣列預設值必須從一個工廠函式獲取
          default: function() {
            return { message: 'hello' }
          }
        },
        // 自定義驗證函式
        propF: {
          validator: function(value) {
            // 這個值必須匹配下列字串中的一個
            return ['success', 'warning', 'danger'].indexOf(value) !== -1
          }
        },
        // 具有預設值的函式
        propG: {
          type: Function,
          // 與物件或陣列預設值不同,這不是一個工廠函式 —— 這是一個用作預設值的函式
          default: function() {
            return 'Default function'
          }
        }
      }
    })
    

    type 可以是下列原生建構函式中的一個:

    • String
    • Number
    • Boolean
    • Array
    • Object
    • Date
    • Function
    • Symbol

    type 還可以是一個自定義的建構函式,並且通過 instanceof 來進行檢查確認

     author: Person
    

    8.自定義處理 v-model 修飾符

    新增到元件 v-model 的修飾符將通過 modelModifiers prop 提供給元件

    v-model.capitalize="myText"自動分配到input元素的text上

    <div id="app">
      <my-component v-model.capitalize="myText">
        </my-component>
      {{ myText }}
    </div>
    
    const app = Vue.createApp({
      data() {
        return {
          myText: ''
        }
      }
    })
    
    app.component('my-component', {
      props: {
        modelValue: String,
        modelModifiers: {
          default: () => ({})
        }
      },
      methods: {
        emitValue(e) {
          let value = e.target.value
          if (this.modelModifiers.capitalize) {
            value = value.charAt(0).toUpperCase() + value.slice(1)
          }
          this.$emit('update:modelValue', value)
        }
      },
      template: `<input
        type="text"
        :value="modelValue"
        @input="emitValue">`
    })
    
    app.mount('#app')
    

    對於帶引數的 v-model 繫結,生成的 prop 名稱將為 arg + "Modifiers"

    <my-component v-model:foo.capitalize="bar"></my-component>
    

    9.獲取DOM節點

    js方法

    var usernameObject= document.querySelector("#username");
    

    Vue方法

    <p ref="pa">huhu<p>
        
        
    console.log(this.$refs.pa.value);
    

    10.支援sass

    安裝sass-loader node-loader

    node install -D sass-loader node-sass
    

    配置

    <style lang ="scss" scoped>
    </style>
    

    如果不新增scoped,則所定義的樣式會被所有元件使用

    11.setup函式以及ref函式

    <script lang="ts">
    import { defineComponent, ref } from "vue";
    export default defineComponent({
      name: "App",
      setup() {
        const girls = ref(["大腳", "劉英", "曉紅"]);
        const selectGirl = ref("");
        const selectGirlFun = (index: number) => {
          selectGirl.value = girls.value[index];
        };
        //因為在模板中這些變數和方法都需要條用,所以需要return出去。
        return {
          girls,
          selectGirl,
          selectGirlFun,
        };
      },
    });
    </script>
    
    <template>
      <img alt="Vue logo" src="./assets/logo.png" />
      <div>
        <h2>歡迎光臨紅浪漫洗浴中心</h2>
        <div>請選擇一位美女為你服務</div>
      </div>
      <div>
        <button
          v-for="(item, index) in girls"
          v-bind:key="index"
          @click="selectGirlFun(index)"
        >
          {{ index }} : {{ item }}
        </button>
      </div>
      <div>你選擇了【{{ selectGirl }}】為你服務</div>
    </template>
    
    • setup 函式的用法,可以代替 Vue2 中的 date 和 methods 屬性,直接把邏輯解除安裝 setup 裡就可以
    • ref 函式的使用,它是一個神奇的函式,我們這節只是初次相遇,要在template中使用的變數,必須用ref包裝一下。
    • return出去的資料和方法,在模板中才可以使用,這樣可以精準的控制暴漏的變數和方法。

    12.reactive函式

     setup() {
        const data = reactive({ //對比ref()函式
          girls: ["大腳", "劉英", "曉紅"],
          selectGirl: "",
          selectGirlFun: (index: number) => {
            data.selectGirl = data.girls[index];
          },
        });
    
        return {
          data,
        };
      },
    

    修改完成<script>部分的程式碼後,還需要修改template部分的程式碼,因為我們這時候返回的只有data,所以模板部分的字面量前要加入data

    <div>
        <button
          v-for="(item, index) in data.girls"
          v-bind:key="index"
          @click="data.selectGirlFun(index)"
        >
          {{ index }} : {{ item }}
        </button>
      </div>
      <div>你選擇了【{{ data.selectGirl }}】為你服務</div>
    
    

    13.Vue3 的生命週期

    Vue3 的生命週期比較多,我們需要一個個給大家講。

    • setup() :開始建立元件之前,在beforeCreatecreated之前執行。建立的是datamethod
    • onBeforeMount() : 元件掛載到節點上之前執行的函式。
    • onMounted() : 元件掛載完成後執行的函式。
    • onBeforeUpdate(): 元件更新之前執行的函式。
    • onUpdated(): 元件更新完成之後執行的函式。
    • onBeforeUnmount(): 元件解除安裝之前執行的函式。
    • onUnmounted(): 元件解除安裝完成後執行的函式
    • onActivated(): 被包含在<keep-alive>中的元件,會多出兩個生命週期鉤子函式。被啟用時執行。
    • onDeactivated(): 比如從 A 元件,切換到 B 元件,A 元件消失時執行。
    • onErrorCaptured(): 當捕獲一個來自子孫元件的異常時啟用鉤子函式(以後用到再講,不好展現)。

    注:使用<keep-alive>元件會將資料保留在記憶體中,比如我們不想每次看到一個頁面都重新載入資料,就可以使用<keep-alive>元件解決。