vue指令、過濾器、動畫

開篇

  • 1.什么是Vue?

    • Vue.js是一套構建用戶界面的框架,它不僅易于上手,還可以與其它第三方庫整合(Swiper、IScroll、...)。
  • 2.框架和庫的區(qū)別?

    • 框架:是一套完整的解決方案;對項目的侵入性較大,項目如果需要更換框架,則需要重構整個項目。
    • 庫(插件):提供某一個小功能,對項目的侵入性較小,如果某個庫無法完成某些需求,可以很容易切換到其它庫實現(xiàn)需求。
      • 例如: 從jQuery 切換到 Zepto, 無縫切換
      • 從IScroll切換到ScrollMagic, 只需要將用到IScroll的代碼替換成ScrollMagic代碼即可
  • 3.為什么要學習框架?

    • 提升開發(fā)效率:在企業(yè)中,時間就是效率,效率就是金錢;
    • 前端提高開發(fā)效率的發(fā)展歷程:原生JS -> jQuery之類的類庫 -> 前端模板引擎 -> Vue / React / Angular
  • 4.框架有很多, 為什么要先學Vue

    • Vue、Angular、React一起,被稱之為前端三大主流框架!
      • 但是Angular、React是老外編寫的, 所以所有的資料都是英文的
      • 而Vue是國人編寫的,所以所有的資料都是中文的,并且Vue中整合了Angular、React中的眾多優(yōu)點
      • 所以為了降低我們的學習難度,我們先學Vue, 學完之后再學習Angular和React
  • 5.使用Vue有哪些優(yōu)勢?

    • 5.1Vue的核心概念之一:
      • 通過數(shù)據(jù)驅動界面更新,無需操作DOM來更新界面
        • 使用Vue我們只需要關心如何獲取數(shù)據(jù),如何處理數(shù)據(jù),如何編寫業(yè)務邏輯代碼,我們只需要將處理好的數(shù)據(jù)交給Vue, Vue就會自動將數(shù)據(jù)渲染到模板中(界面上)
    • 5.2Vue的核心概念之二:
      • 組件化開發(fā),我們可以將網(wǎng)頁拆分成一個個獨立的組件來編寫,將來再通過封裝好的組件拼接成一個完整的網(wǎng)頁
      • 思維導圖:https://cn.vuejs.org/images/components.png

Vue基本模板

  • 1.Vue框架使用方式

    • 1.1傳統(tǒng)下載導入使用
    • 1.2vue-cli安裝導入使用
  • 2.Vue框架使用步驟

    • 2.1下載Vue框架
    • 2.2導入Vue框架
    • 2.3創(chuàng)建Vue實例對象
    • 2.4指定Vue實例對象控制的區(qū)域
    • 2.5指定Vue實例對象控制區(qū)域的數(shù)據(jù)

Vue數(shù)據(jù)單向傳遞

  • 1.MVVM設計模式

    • 在MVVM設計模式中由3個部分組成
      • M : Model 數(shù)據(jù)模型(保存數(shù)據(jù), 處理數(shù)據(jù)業(yè)務邏輯)
      • V : View 視圖(展示數(shù)據(jù), 與用戶交互)
      • VM: View Model 數(shù)據(jù)模型和視圖的橋梁(M是中國人, V是美國人, VM就是翻譯)
    • MVVM設計模式最大的特點就是支持數(shù)據(jù)的雙向傳遞
      • 數(shù)據(jù)可以從 M -> VM -> V
      • 也可以從 V -> VM -> M
  • 2.Vue中MVVM的劃分

    • Vue其實是基于MVVM設計模式的
      • 被控制的區(qū)域: View
      • Vue實例對象 : View Model
      • 實例對象中的data: Model
  • 3.Vue中數(shù)據(jù)的單向傳遞

    • 我們把"數(shù)據(jù)"交給"Vue實例對象","Vue實例對象"將數(shù)據(jù)交給"界面"
    • Model -> View Model -> View
<!--這里就是MVVM中的View-->
<div id="app">
    <p>{{ name }}</p>
</div>
<script>
// 這里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 這里就是MVVM中的Model
    data: {
        name: "微雙"
    }
});
</script>

Vue數(shù)據(jù)雙向傳遞

  • 1.Vue調試工具安裝

  • 2.安裝步驟:

    • 2.1下載離線安裝包
    • 2.2打開谷歌插件界面
    • 2.3直接將插件拖入
    • 2.4報錯程序包無效:"CRX_HEADER_INVALID",可以將安裝包修改為rar后綴,解壓之后再安裝
    • 2.5重啟瀏覽器
  • 3.數(shù)據(jù)雙向綁定

    • 默認情況下Vue只支持數(shù)據(jù)單向傳遞 M -> VM -> V,但是由于Vue是基于MVVM設計模式的,所以也提供了雙向傳遞的能力
    • 在<input>、<textarea> 及 <select> 元素上可以用v-model指令創(chuàng)建雙向數(shù)據(jù)綁定

注意點:
v-model 會忽略所有表單元素的value、checked、selected 特性的初始值,而總是將 Vue 實例的數(shù)據(jù)作為數(shù)據(jù)來源


常用指令-v-once

  • 1.什么是指令?

    • 指令就是Vue內(nèi)部提供的一些自定義屬性,這些屬性中封裝好了Vue內(nèi)部實現(xiàn)的一些功能,只要使用這些指令就可以使用Vue中實現(xiàn)的這些功能
  • 2.Vue數(shù)據(jù)綁定的特點

    • 只要數(shù)據(jù)發(fā)生變化, 界面就會跟著變化
  • 3.v-once指令

    • 讓界面不要跟著數(shù)據(jù)變化, 只渲染一次
  • 4.v-model指令

    • 渲染多次
    • 示例
<div id="app">
    <p v-once>{{ name }}</p>
    <p>{{ name }}</p>
</div>
<script src="js/vue.js"></script>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            name: "微雙"
        }
    });
</script>

常用指令-v-cloak

  • 1.Vue數(shù)據(jù)綁定過程

    • 1.1會先將未綁定數(shù)據(jù)的界面展示給用戶
    • 1.2然后再根據(jù)模型中的數(shù)據(jù)和控制的區(qū)域生成綁定數(shù)據(jù)之后的HTML代碼
    • 1.3最后再將綁定數(shù)據(jù)之后的HTML渲染到界面上
      • 正是在最終的HTML被生成渲染之前會先顯示模板內(nèi)容,所以如果用戶網(wǎng)絡比較慢或者網(wǎng)頁性能比較差, 那么用戶會看到模板內(nèi)容
  • 2.如何解決這個問題

    • 利用v-cloak配合 [v-cloak]:{display: none}默認先隱藏未渲染的界面,等到生成HTML渲染之后再重新顯示
  • 3.v-cloak指令作用:

    • 數(shù)據(jù)渲染之后自動顯示元素
    • 示例:
<style>
    [v-cloak] { display: none }
</style>
<div id="app">
    <p v-cloak>{{ name }}</p>
</div>
<script src="js/vue.js"></script>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            name: "微雙"
        }
    });
</script>

常用指令v-text和v-html

  • 1.什么是v-text指令

    • v-text就相當于過去學習的innerText
    • 會覆蓋便簽內(nèi)原有的內(nèi)容
    • 不會解析html
  • 2.什么是v-html指令

    • v-html就相當于過去學習的innerHTML
    • 會覆蓋便簽內(nèi)原有的內(nèi)容
    • 會解析html
<div id="app">
    <!--插值的方式: 可以將指定的數(shù)據(jù)插入到指定的位置-->
  <p>++++{{ name }}++++</p>
    <!--插值的方式: 不會解析HTML-->
  <p>++++{{ msg }}++++</p>
    <!--v-text的方式: 會覆蓋原有的內(nèi)容-->
  <p v-text="name">++++++++</p>
    <!--v-text的方式: 也不會解析HTML-->
  <p v-text="msg">++++++++</p>
    <!--v-html的方式: 會覆蓋原有的內(nèi)容-->
    <p v-html="name">++++++++</p>
    <!--v-html的方式:會解析HTML-->
    <p v-html="msg">++++++++</p>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            name: "微雙",
            msg: "<span>我是span</span>"
        }
    });
</script>

常用指令v-if/v-else

  • 1.什么是v-if指令

    • 條件渲染: 如果v-if取值是true就渲染元素, 如果不是就不渲染元素
  • 2.==v-if特點==:

    • 如果條件不滿足根本就不會創(chuàng)建這個元素
  • 3.v-if注意點

    • v-if可以從模型中獲取數(shù)據(jù)
    • v-if也可以直接賦值一個表達式
<div id="app">
    <p v-if="show">我是true</p>
    <p v-if="hidden">我是false</p>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            show: true,
            hidden: false
        }
    });
</script>
  • 4.v-else指令
    • v-else指令可以和v-if指令配合使用
      • 當v-if不滿足條件時就執(zhí)行v-else就顯示v-else中的內(nèi)容
<div id="app">
  <p v-if="age >= 18">成年人</p>
  <p v-else>未成年人</p>
</div>
 <script>
    let vue = new Vue({
        el: '#app',
        data: {
            show: true,
            hidden: false,
            age: 17
        }
    });
</script>

5.v-else注意點

  • v-else不能單獨出現(xiàn)
  • v-if和v-else中間不能出現(xiàn)其它內(nèi)容
// 錯誤寫法
<div id="app">
  <p v-if="age >= 18">成年人</p>
  <p>中間的內(nèi)容</p>
  <p v-else>未成年人</p>
</div>
  • 6.v-else-if指令
    • v-else-if可以和v-if指令配合使用
      • 當v-if不滿足條件時就依次執(zhí)行后續(xù)v-else-if, 哪個滿足就顯示哪個
<div id="app">
  <p v-if="score >= 80">優(yōu)秀</p>
  <p v-else-if="score >= 60">良好</p>
  <p v-else>差</p>
</div>
 <script>
    let vue = new Vue({
        el: '#app',
        data: {
            show: true,
            hidden: false,
            age: 17,
            score: 50
        }
    });
</script>
  • 7.v-else-if注意點
    • v-else-if不能單獨出現(xiàn)
    • v-if和v-else-if中間不能出現(xiàn)其它內(nèi)容

常用指令v-show

  • 1.什么是v-show指令

    • v-show和v-if的能夠一樣都是條件渲染, 取值為true就顯示, 取值為false就不顯示
  • 2.==v-show特點==

    • 如果條件不滿足根本就不會創(chuàng)建這個元素
  • 3.v-show注意點

    • v-show可以從模型中獲取數(shù)據(jù)
    • v-show也可以直接賦值一個表達式

v-if和v-show區(qū)別

  • 區(qū)別1:元素是否存在

    • v-if: 只要取值為false就不會創(chuàng)建元素
    • v-show: 哪怕取值為false也會創(chuàng)建元素, 只是如果取值是false會設置元素的display為none
  • 區(qū)別2:應用場景

    • 由于取值為false時v-if不會創(chuàng)建元素,所以如果需要切換元素的顯示和隱藏,每次v-if都會創(chuàng)建和刪除元素
    • 由于取值為false時v-show會創(chuàng)建元素并設置display為none,所以如果需要切換元素的顯示和隱藏,不會反復創(chuàng)建和刪除,只是修改display的值
    • 所以: 如果企業(yè)開發(fā)中需要頻繁切換元素顯示隱藏, 那么推薦使用v-show, 可以提高性能,否則使用v-if

常用指令v-for

  • 1.什么是v-for指令

    • 相當于JS中的for in循環(huán),可以根據(jù)數(shù)據(jù)多次渲染元素
  • 2.v-for特點

    • 可以遍歷 數(shù)組, 字符, 數(shù)字(輸出是從1開始的), 對象
    • 示例:
<div id="app">
    <ul>
        <li v-for="(value, index) in list">{{index}}-&#45;&#45;{{value}}</li>  // 遍歷數(shù)組
        <li v-for="(value, index) in 'abcdefg'">{{index}}-&#45;&#45;{{value}}</li>  // 遍歷字符串
        <li v-for="(value, index) in 6">{{index}}-&#45;&#45;{{value}}</li>  // 遍歷數(shù)字
        <li v-for="(value, key) in obj">{{key}}---{{value}}</li> // 遍歷對象
    </ul>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            list: ["張三", "李四", "王五", "趙六"],
            obj: {
                name: "lnj",
                age: 33,
                gender: "man",
                class: "知播漁"
            }
        }
    });
</script>
==注意點==
  • 1.v-for注意點

    • 1.1v-for為了提升性能,在更新已渲染過的元素列表時,會采用“就地復用”策略。也正是因為這個策略,在某些時刻會導致我們的數(shù)據(jù)混亂
      • 例如: 在列表前面新增了內(nèi)容
    • 1.2為了解決這個問題,我們可以在渲染列表的時候給每一個元素加上一個獨一無二的key
      • v-for在更新已經(jīng)渲染過的元素列表時,會先判斷key是否相同, 如果相同則復用, 如果不同則重新創(chuàng)建
  • 2.key屬性注意點

    • 不能使用index的作為key,因為當列表的內(nèi)容新增或者刪除時index都會發(fā)生變化
      • 添加到列表的末尾,index到不會發(fā)生變化,但是添加到列表頭的話,整體的index都會發(fā)生變化
  • 示例:

<div id="app">
    <form>
        <input type="text" v-model="name">
        <input type="submit" value="添加" @click.prevent="add">
    </form>
    <ul>
        <li v-for="(person,index) in persons" :key="person.id">
            <input type="checkbox">
            <span>{{index}} --- {{person.name}}</span>
        </li>
    </ul>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            persons: [
                {name: "zs", id: 1},
                {name: "ls", id: 2},
                {name: "ww", id: 3}
                ],
            name: ""
        },
        methods: {
            add(){
                let lastPerson = this.persons[this.persons.length - 1];
                let newPerson = {name: this.name, id: lastPerson.id + 1};
                // this.persons.push(newPerson);
                this.persons.unshift(newPerson);
                this.name = "";
            }
        }
    });
</script>

常用指令v-bind

  • 1.什么是v-bind指令

    • 給"元素的==屬性=="綁定數(shù)據(jù),就必須使用v-bind
      • 不同于給"元素"綁定數(shù)據(jù),我們可以使用{{}}, v-text, v-html
  • 2.v-bind格式

    • v-bind:屬性名稱="綁定的數(shù)據(jù)"
    • : 屬性名稱="綁定的數(shù)據(jù)"
<input type="text" v-bind:value="age">
<input type="text" :value="age">
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            age: 18
        }
    });
</script>
  • 3.v-bind特點
    • 賦值的數(shù)據(jù)可以是任意一個合法的JS表達式
    • 例如: :屬性名稱="age + 1"
綁定類名
  • 1.v-bind指令的特殊作用

    • v-bind指令給"任意標簽"的"任意屬性"綁定數(shù)據(jù),對于大部分的屬性而言我們只需要直接賦值即可, 例如:value="name"
    • 但是對于class和style屬性而言, 它的格式比較特殊
  • 2.通過v-bind綁定類名格式

    • :class="['需要綁定類名', ...]" 普通格式
    • :class="[flag?'active':'']"數(shù)組的每一個元素都可以是一個三目運算符按需導入
    • :class="[{'active': true}]"通過對象來決定是否需要綁定
    • :class="對象名"(==這種方法不錯==,修改方便)——使用Model中的對象來替換數(shù)組
      • 綁定的類名太多可以將類名封裝到Model中例如:obj: {'color': true,'size': true,'active': false}

注意點:
1.(:class="需要綁定類名")直接賦值一個類名(沒有放到數(shù)組中)默認回去Model中查找,但是Model中沒有對應的類名, 所以無效
2.(:class="[需要綁定類名]")如果想讓v-bind去style中查找類名,那么就必須把類名放到數(shù)組中,但是放到數(shù)組中之后默認還是回去Model中查找

  • 4.綁定類名企業(yè)應用場景
    • 從服務器動態(tài)獲取樣式后通過v-bind動態(tài)綁定類名,這樣就可以讓服務端來控制前端樣式
    • 常見場景: 618 雙11等
綁定樣式
  • 通過v-bind給style屬性綁定數(shù)據(jù)

    • 1.將數(shù)據(jù)放到對象中
      • :style="{color:'red','font-size':'50px'}"
    • 2.將數(shù)據(jù)放到Model對象中
      • :style="obj"
      • Model對象中:
        • obj: {color: 'red','font-size':'80px'}
    • 3.如果需要綁定Model中的多個對象,可以放到一個數(shù)組中賦值
      • :style="[obj1,obj2]"
      • Model對象中:
        • obj1: {color: 'red','font-size':'80px'}
        • obj2: {'background-color': 'blue'}
  • 示例:

<div id="app">
    <p :style="{color: 'red', 'font-size': '100px'}">我是段落</p>
    <p :style="obj">我是段落</p>
    <p :style="[obj1, obj2]">我是段落</p>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            obj:{
                "color": "blue",   // color可以用引號括起來,也可以不括
                "font-size": "100px"
            },
            obj1:{
                "color": "blue",
                "font-size": "100px"
            },
            obj2: {
                "background-color": "red"
            }
        }
    });
</script>
  • ==重點==:
    • 屬性和取值都用引號括起來
      • 個別屬性不用,但是都括起來沒毛病

注意點:
如果屬性名稱包含-, 那么必須用引號括起來


常用指令-v-on

  • 1.什么是v-on指令?

    • v-on指令專門用于給元素綁定監(jiān)聽事件
  • 2.v-on指令兩種格式

    • v-on:事件名稱="回調函數(shù)名稱"
    • @事件名稱="回調函數(shù)名稱"
    • 示例:
<div id="app">
<!--<button v-on:click="myFn">我是按鈕</button>-->
<button @click="myFn">我是按鈕</button>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
        },
        methods: {
            myFn(){
                alert('lnj')
            }
        }
    });
</script>

注意點:
v-on綁定的事件被觸發(fā)之后,會去Vue實例對象的methods中查找對應的回調函數(shù)

v-on修飾符
  • 1.v-on修飾符

    • 在事件中有很多東西需要我們處理,例如事件冒泡,事件捕獲,阻止默認行為等.那么在Vue中如何處理以上內(nèi)容呢,我們可以通過v-on修飾符來處理
  • 2.常見修飾符

    • .once
      • 只觸發(fā)一次回調。
    • .prevent
      • 調用 event.preventDefault()。阻止事件默認行為
    • .stop
      • 調用 event.stopPropagation()。
      • 默認情況下載嵌套的元素中,如果都監(jiān)聽了相同的事件,那么會觸發(fā)事件冒泡,這個stop就是阻止事件冒泡
    • .self
      • 當前元素觸發(fā)事件的時候才觸發(fā)回調。
    • .capture
      • 添加事件偵聽器時使用 capture 模式。
      • 默認情況下是事件冒泡,如果想變成事件捕獲, 那么就需要使用.capture修飾符
  • 示例:
<style>
    *{
        margin: 0;
        padding: 0;
    }
    .a{
        width: 300px;
        height: 300px;
        background: red;
    }
    .b{
        width: 200px;
        height: 200px;
        background: blue;
    }
    .c{
        width: 100px;
        height: 100px;
        background: green;
    }
</style>
<div id="app">
    <!--<button v-on:click.once ="myFn">我是按鈕</button>-->
    <!--<a  v-on:click.prevent="myFn">我是A標簽</a>-->
    <!--<div class="a" @click="myFn1">
        <div class="b" @click.stop="myFn2">
            <div class="c" @click="myFn3"></div>
        </div>
    </div>-->
    <!--<div class="a" @click="myFn1">
        <div class="b" @click.self="myFn2">
            <div class="c" @click="myFn3"></div>
        </div>
    </div>-->
    <div class="a" @click.capture="myFn1">
        <div class="b" @click.capture="myFn2">
            <div class="c" @click.capture="myFn3"></div>
        </div>
    </div>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
        },
        // 專門用于存儲監(jiān)聽事件回調函數(shù)
        methods: {
            myFn1(){
                console.log("爺爺");
            },
            myFn2(){
                console.log("爸爸");
            },
            myFn3(){
                console.log("兒子");
            }
        }
    });
</script>
v-on注意點
  • 1.綁定回調函數(shù)名稱的時候,后面可以寫()也可以不寫

    • v-on:click="myFn"
    • v-on:click="myFn()"
  • 2.可以給綁定的回調函數(shù)傳遞參數(shù)

    • v-on:click="myFn('lnj', 33)"
    • 示例:
<div id="app">
    <button @click="myFn('ws',29)">按鈕</button>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            
        },
        methods:{
            myFn(name,age){
                console.log(name,age);
            }
        }
    });
</script>
  • 3.如果在綁定的函數(shù)中需要用到data中的數(shù)據(jù)必須加上this
    • 示例:
<div id="app">
    <button @click="myFn('ws',29,$event)">按鈕</button>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            gender: 'man'
        },
        methods:{
            myFn(name,age,e){
                console.log(name,age,this.gender);
            }
        }
    });
</script>
v-on按鍵修飾符
  • 1.什么是按鍵修飾符

    • 我們可以通過按鍵修飾符監(jiān)聽特定按鍵觸發(fā)的事件
    • 例如: 可以監(jiān)聽當前事件是否是回車觸發(fā)的, 可以監(jiān)聽當前事件是否是ESC觸發(fā)的等
  • 2.按鍵修飾符分類

    • 2.1系統(tǒng)預定義修飾符
      • .enter/.tab/.delete (捕獲“刪除”和“退格”鍵)/.esc/.space/.up/.down/.left/.right等
    • 2.2自定義修飾符
      • 可以使用 v-on:keyup.自定義按鍵名稱
        • Vue.config.keyCodes.自定義按鍵名稱 = 查詢keycode列表里自定義按鍵對應的值
<div id="app">
    <!--<input type="text" @keyup.enter="myFn">-->
    <input type="text" @keyup.f2="myFn">
</div>
<script>
    Vue.config.keyCodes.f2 = 113;
    let vue = new Vue({
        el: '#app',
        data: {
        },
        methods: {
            myFn(){
                alert("lnj");
            }
        }
    });
</script>

自定義指令

  • 1.自定義全局指令

    • 在Vue中除了可以使用Vue內(nèi)置的一些指令以外, 我們還可以自定義指令
  • 2.自定義全局指令語法

    • 格式如下:
<script>
Vue.directive('自定義指令名稱', 
    {
    生命周期名稱: function (el) {
        指令業(yè)務邏輯代碼
    } 
});
</script>  
  • 3.指令生命周期方法
    • 自定義指令時一定要明確指令的業(yè)務邏輯代碼更適合在哪個階段執(zhí)行
    • 例如: 指令業(yè)務邏輯代碼中沒有用到元素事件, 那么可以在bind階段執(zhí)行
    • 例如: 指令業(yè)務邏輯代碼中用到了元素事件, 那么就需要在inserted階段執(zhí)行
    • 示例:
<div id="app">
<!--    <p v-color>我是段落</p>-->
    <input type="text" v-focus>
</div>
<script>
Vue.directive("color", {
    // 這里的el就是被綁定指令的那個元素
    bind: function (el) {  // bind是生命周期名稱
        el.style.color = "red";
    }
});
Vue.directive("focus", {
    inserted: function (el) {
        el.focus();   // 聚焦
    }
});
</script>

自定義指令注意點:
使用時需要加上v-, 而在自定義時不需要加上v-

自定義指令參數(shù)
  • 1.自定義指令參數(shù)

    • 在使用官方指令的時候我們可以給指令傳參
    • 例如: v-model="name"在我們自定義的指令中我們也可以傳遞傳遞
  • 2.獲取自定義指令傳遞的參數(shù)

    • 在執(zhí)行自定義指令對應的方法的時候,除了會傳遞el給我們,還會傳遞一個對象給我們,這個對象中就保存了指令傳遞過來的參數(shù)
    • 示例:
<div id="app">
    <!--<p v-color="'blue'">我是段落</p>-->
    <p v-color="curColor">我是段落</p>
</div>
<script>
    Vue.directive("color", {
        bind: function (el, obj) {
            // el.style.color = "red";
            el.style.color = obj.value;
        }
    });
    let vue = new Vue({
        el: '#app',
        data: {
            curColor: 'green'
        }
    });
</script>

自定義局部指令

  • 1.自定義全局指令的特點

    • 在任何一個Vue實例控制的區(qū)域中都可以使用
  • 2.自定義局部指令的特點

    • 只能在自定義的那個Vue實例中使用
  • 3.如何自定義一個局部指令

    • 給創(chuàng)建Vue實例時傳遞的對象添加
    • 格式如下:
<script>
let vue = new Vue({
    el: '#app',
    data: {
    },
    directives: {
    // key: 指令名稱
    // value: 對象
    '自定義生命周期名稱': {
        bind: function (el, obj) {
            指令業(yè)務邏輯代碼
            }
        }
    }
});

</script>
  • 示例:
<div id="app1">
    <p v-color="'blue'">我是段落</p>
</div>
<div id="app2">
    <p v-color="'red'">我是段落</p>
</div>
<script>
let vue1 = new Vue({
    el: '#app1',
    data: {},
    methods: {}
});
let vue2 = new Vue({
    el: '#app2',
    data: {},
    methods: {},
    // 專門用于定義局部指令的
    directives: {
        "color": {
            bind: function (el, obj) {
                el.style.color = obj.value;
            }
        }
    }
});
</script>

計算屬性

  • 1.插值語法特點

    • 可以在{{}}中編寫合法的JavaScript表達式
  • 2.在插值語法中編寫JavaScript表達式缺點

    • 2.1沒有代碼提示
    • 2.2語句過于復雜不利于我們維護
  • 3.如何解決?

    • 對于任何復雜邏輯,你都應當使用計算屬性computed
    • 示例:
<div id="app">
    <!--<p>{{msg.split("").reverse().join("")}}</p>-->
    <p>{{msg2}}</p>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            // msg: "abcdef"
        },
        // 專門用于定義計算屬性的
        computed: {
            msg2: function () {
                let res = "abcdef".split("").reverse().join("");
                return res;
            }
        }
    });
</script>

注意點:
雖然在定義計算屬性的時候是通過一個函數(shù)返回的數(shù)據(jù),但是在使用計算屬性的時候不能在計算屬性名稱后面加上()
因為它是一個屬性不是一個函數(shù)(方法)


計算屬性和函數(shù)的區(qū)別

  • 1.計算屬性和函數(shù)的共同點

    • 通過計算屬性或者通過函數(shù)我們都能拿到處理后的數(shù)據(jù)
  • 2.計算屬性和函數(shù)的區(qū)別

    • 2.1函數(shù)"不會"將計算的結果緩存起來,每一次訪問都會重新求值
    • 2.2計算屬性"會"將計算的結果緩存起來, 只要數(shù)據(jù)沒有發(fā)生變化, 就不會重新求值
  • 3.計算屬性應用場景

    • 計算屬性:比較適合用于計算不會頻繁發(fā)生變化的的數(shù)據(jù),這樣會比使用函數(shù)的性能高
    • 函數(shù):經(jīng)常發(fā)生變化的數(shù)據(jù)
<div id="app">
    <p>{{msg1()}}</p>
    <p>{{msg1()}}</p>
    <p>{{msg1()}}</p>
    <p>{{msg2}}</p>
    <p>{{msg2}}</p>
    <p>{{msg2}}</p>
</div>
<script>
let vue = new Vue({
    el: '#app',
    data: {
    },
    // 專門用于存儲監(jiān)聽事件回調函數(shù)
    methods: {
        // 函數(shù)的特點: 每次調用都會執(zhí)行
        msg1(){
            console.log("msg1函數(shù)被執(zhí)行了");
            let res = "abcdef".split("").reverse().join("");
            return res;
        }
    },
    // 專門用于定義計算屬性的
    computed: {
        msg2: function () { 
            console.log("msg2計算屬性被執(zhí)行了");
            let res = "abcdef".split("").reverse().join("");
            return res;
        }
    }
});
</script>

自定義全局過濾器

  • 1.什么是過濾器?

    • 過濾器和函數(shù)和計算屬性一樣都是用來處理數(shù)據(jù)的,但是過濾器一般用于格式化插入的文本數(shù)據(jù)
  • 2.自定義全局過濾器的特點

    • 在任何一個Vue實例控制的區(qū)域中都可以使用
  • 3.如何自定義全局過濾器Vue.filter

    • Vue.filter(參數(shù)1,參數(shù)2);
      • 第一個參數(shù): 過濾器名稱
      • 第二個參數(shù): 處理數(shù)據(jù)的函數(shù)

注意點:
默認情況下處理數(shù)據(jù)的函數(shù)接收一個參數(shù),就是當前要被處理的數(shù)據(jù)

  • 4.如何使用全局過濾器

    • {{msg | 過濾器名稱}}
    • :value="msg | 過濾器名稱"
  • 5.過濾器注意點

    • 5.1只能在插值語法和v-bind中使用
    • 5.2過濾器可以連續(xù)使用
    • 示例:
<div id="app">
    <!--Vue會把name交給指定的過濾器處理之后, 再把處理之后的結果插入到指定的元素中-->
    <p>{{name | formartStr1 | formartStr2}}</p>
</div>
<script>
    Vue.filter("formartStr1", function (value) {
        value = value.replace(/學院/g, "大學");
        return value;
    });
    Vue.filter("formartStr2", function (value) {
        value = value.replace(/大學/g, "幼兒園");
        return value;
    });
    let vue = new Vue({
        el: '#app',
        data: {
            name: "知播漁學院, 指趣學院, 前端學院, 區(qū)塊鏈學院"
        }
    });
</script>
自定義局部過濾器
  • 1.自定義局部過濾器的特點

    • 只能在自定義的那個Vue實例中使用
  • 2.如何自定義一個局部指令

    • 給創(chuàng)建Vue實例時傳遞的對象添加
    • 格式如下:
filters: {
    // key: 過濾器名稱
    // value: 過濾器處理函數(shù)
    '過濾器名稱': function (value) {
        過濾器處理函數(shù)
    }
}
  • 示例:
<div id="app1">
    <p>{{name | formartStr}}</p>
</div>
<div id="app2">
    <p>{{name | formartStr}}</p>
</div>
<script>
let vue1 = new Vue({
    el: '#app1',
    data: {
        name: "知播漁學院, 指趣學院, 前端學院, 區(qū)塊鏈學院"
    }
});
let vue2 = new Vue({
    el: '#app2',
    data: {
        name: "知播漁學院, 指趣學院, 前端學院, 區(qū)塊鏈學院"
    },
    // 專門用于定義局部過濾器的
    filters: {
        "formartStr": function (value) {
            value = value.replace(/學院/g, "大學");
            return value;
        }
    }
});
</script>
  • ==注意點==
    • 在使用過濾器的時候,可以在過濾器名稱后面加上()
    • 如果給過濾器的名稱后面加上了(),那么就可以給過濾器的函數(shù)傳遞參數(shù)
    • 示例:
<div id="app">
    <p>{{time | filter1('yyyy-MM-dd')}}</p>
</div>
<script>
    Vue.filter('filter1',function (value,frm) {
        let date = new Date(value);
        let year = date.getFullYear();
        let mouth = date.getMonth() + 1 + '';
        let day = date.getDate() + '';
        let hour = date.getHours() + '';
        let minute = date.getMinutes() + '';
        let second = date.getSeconds() + '';
        if(frm && frm === 'yyyy-MM-dd'){
            return `${year}-${mouth.padStart(2,'0')}-${day.padStart(2,'0')}`;
        }
        return `${year}-${mouth.padStart(2,'0')}-${day.padStart(2,'0')} ${hour.padStart(2,'0')}:${minute.padStart(2,'0')}:${second.padStart(2,'0')}`;
    });
    let vue = new Vue({
        el: '#app',
        data: {
            name:'知播漁學院, 指趣學院, 前端學院, 區(qū)塊鏈學院',
            time: Date.now()
        }
    });
</script>

過渡動畫

1.默認類名(v-xxx)來指定過渡動畫
  • 如何給Vue控制的元素添加過渡動畫
    • 1.將需要執(zhí)行動畫的元素放到transition組件中
    • 2.transition組件中會自動查找
      • 顯示時會自動查找.v-enter/.v-enter-active/.v-enter-to類名
      • 隱藏時會自動查找.v-leave/ .v-leave-active/.v-leave-to類名
    • 3.我們只需要在.v-enter.v-leave-to中指定動畫動畫開始的狀態(tài)
    • 4.在.v-enter-active.v-leave-active中指定動畫執(zhí)行的狀態(tài)
    • 5.即可完成過渡動畫
    • 示例:
<style>
    *{
        margin: 0;
        padding: 0;
    }
    .box{
        width: 200px;
        height: 200px;
        background: red;
    }
    .v-enter{
        opacity: 0;
    }
    .v-enter-to{
        opacity: 1;
    }
    .v-enter-active{
        transition: all 3s;
    }
    .v-leave{
        opacity: 1;
    }
    .v-leave-to{
        opacity: 0;
    }
    .v-leave-active{
        transition: all 3s;
    }
</style>
<div id="app">
    <button @click="toggle">我是按鈕</button>
    <transition>
        <div class="box" v-show="isShow"></div>
    </transition>
</div>
<script>
let vue = new Vue({
    el: '#app',
    data: {
        isShow: false
    },
    methods: {
        toggle(){
            this.isShow = !this.isShow;
        }
    }
});
</script>
==注意點==
  • 1.初始動畫設置

    • 默認情況下第一次進入的時候沒有動畫的
    • 如果想一進來就有動畫,我們可以通過給transition添加appear屬性的方式,告訴Vue第一次進入就需要顯示動畫
  • 2.如何給多個不同的元素指定不同的動畫

    • 如果有多個不同的元素需要執(zhí)行不同的過渡動畫,那么我們可以通過給transition指定name的方式,來指定"進入之前/進入之后/進入過程中,離開之前/離開之后/離開過程中"對應的類名,來實現(xiàn)不同的元素執(zhí)行不同的過渡動畫

注意點:
transition中只能放一個元素, 多個元素無效
如果想給多個元素添加過渡動畫, 那么就必須創(chuàng)建多個transition組件

<style>
    *{
        margin: 0;
        padding: 0;
    }
    .box{
        width: 200px;
        height: 200px;
        background: red;
    }
    .one-enter{
        opacity: 0;
    }
    .one-enter-to{
        opacity: 1;
        margin-left: 500px;
    }
    .one-enter-active{
        transition: all 3s;
    }
    .two-enter{
        opacity: 0;
    }
    .two-enter-to{
        opacity: 1;
        margin-top: 500px;
    }
    .two-enter-active{
        transition: all 3s;
    }
</style>
<div id="app">
    <button @click="toggle">我是按鈕</button>
    <transition appear name="one">
        <div class="box" v-show="isShow"></div>
    </transition>
    <transition appear name="two">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            isShow: true
        },
        methods: {
            toggle(){
                this.isShow = !this.isShow;
            }
        }
    });
</script>
2.JS鉤子函數(shù)來指定過渡動畫
  • 1.當前過渡存在的問題

    • 通過transition+類名的方式確實能夠實現(xiàn)過渡效果,但是實現(xiàn)的過渡效果并不能保存動畫之后的狀態(tài)
    • 因為Vue內(nèi)部的實現(xiàn)是在過程中動態(tài)綁定類名, 過程完成之后刪除類名
    • 正是因為刪除了類名, 所以不能保存最終的效果
  • 2.在Vue中如何保存過渡最終的效果

    • 通過Vue提供的JS鉤子來實現(xiàn)過渡動畫
      • v-on:before-enter="beforeEnter" 進入動畫之前

      • v-on:enter="enter" 進入動畫執(zhí)行過程中

      • v-on:after-enter="afterEnter" 進入動畫完成之后

      • v-on:enter-cancelled="enterCancelled" 進入動畫被取消

      • v-on:before-leave="beforeLeave" 離開動畫之前

      • v-on:leave="leave" 離開動畫執(zhí)行過程中

      • v-on:after-leave="afterLeave" 離開動畫完成之后

      • v-on:leave-cancelled="leaveCancelled" 離開動畫被取消

  • 3.JS鉤子實現(xiàn)過渡注意點

    • 3.1在動畫過程中必須寫上el.offsetWidth或者el.offsetHeight
    • 3.2在enter和leave方法中必須調用done方法,否則after-enter和after-leave不會執(zhí)行
    • 3.3若需要添加初始動畫,那么需要把done方法包裹到setTimeout方法中調用
    • 示例:
<div id="app">
    <button @click="toggle">我是按鈕</button>
    <transition appear
                v-bind:css="false"
                v-on:before-enter="beforeEnter"
                v-on:enter="enter"
                v-on:after-enter="afterEnter">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>
<script>
let vue = new Vue({
    el: '#app',
    data: {
        isShow: true
    },
    methods: {
        toggle(){
            this.isShow = !this.isShow;
        },
        beforeEnter(el){
            // 進入動畫開始之前
            console.log("beforeEnter");
            el.style.opacity = "0";
        },
        enter(el, done){
            // 進入動畫執(zhí)行過程中
            console.log("enter");
            // el.offsetWidth;
            el.offsetHeight;
            el.style.transition = "all 3s";
            // done();
            /*
            注意點: 如果想讓元素一進來就有動畫, 那么最好延遲以下再調用done方法
            */
            setTimeout(function () {
                done();
            }, 0);
        },
        afterEnter(el){
            // 進入動畫執(zhí)行完畢之后
            console.log("afterEnter");
            el.style.opacity = "1";
            el.style.marginLeft = "500px";
        }
    }
});
</script>
配合使用第三方 JavaScript 動畫庫,實現(xiàn)過渡動畫
  • 配合Velocity實現(xiàn)過渡動畫
    • 在Vue中我們除了可以自己實現(xiàn)過渡動畫以外,還可以結合第三方框架實現(xiàn)過渡動畫
      • 1.導入Velocity庫
      • 2.在動畫執(zhí)行過程鉤子函數(shù)中編寫Velocity動畫
      • 示例:
<style>
    *{
        margin: 0;
        padding: 0;
    }
    .box{
        width: 200px;
        height: 200px;
        background: red;
    }
</style>
<div id="app">
    <button @click="toggle">我是按鈕</button>
    <transition appear
                v-bind:css="false"
                v-on:before-enter="beforeEnter"
                v-on:enter="enter"
                v-on:after-enter="afterEnter">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            isShow: true
        },
        methods: {
            toggle(){
                this.isShow = !this.isShow;
            },
            beforeEnter(el){
            },
            enter(el, done){
                Velocity(el, {opacity: 1, marginLeft: "500px"}, 3000);
                done();
            },
            afterEnter(el){

            }
        }
    });
</script>
使用自定義類名的方式來指定過渡動畫
  • 1.自定義類名動畫

    • 1.在Vue中除了可以使用默認類名(v-xxx)來指定過渡動畫
    • 2.除了可以使用自定義類名前綴(yyy-xx)來指定過渡動畫(transition name="yyy")
    • 3.除了可以使用 JS鉤子函數(shù)來指定過渡動畫以外
    • 4.還可以使用自定義類名的方式來指定過渡動畫
      • enter-class 進入動畫開始之前
      • enter-active-class 進入動畫執(zhí)行過程中
      • enter-to-class 進入動畫執(zhí)行完畢之后
      • leave-class 離開動畫開始之前
      • leave-active-class 離開動畫執(zhí)行過程中
      • leave-to-class 離開動畫執(zhí)行完畢之后
  • 示例:

<style>
    *{
        margin: 0;
        padding: 0;
    }
    .box{
        width: 200px;
        height: 200px;
        background: red;
    }
    .a{
        opacity: 0;
    }
    .b{
        opacity: 1;
        margin-left: 500px;
    }
    .c{
        transition: all 3s;
    }
</style>
<div id="app">
    <button @click="toggle">我是按鈕</button>
    <transition appear
                enter-class="a"
                enter-active-class="c"
                enter-to-class="b">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            isShow: true
        },
        methods: {
            toggle(){
                this.isShow = !this.isShow;
            }
        }
    });
</script>
配合使用第三方 CSS 動畫庫Animate.css實現(xiàn)過渡動畫
  • 配合Animate.css實現(xiàn)過渡動畫步驟
    • 1.導入Animate.css庫
    • 2.在執(zhí)行過程中的屬性上綁定需要的類名
    • 示例:
<link  rel="stylesheet" type="text/css">
<div id="app">
    <button @click="toggle">我是按鈕</button>
    <transition appear
                enter-active-class="animated bounceInRight">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            isShow: true
        },
        methods: {
            toggle(){
                this.isShow = !this.isShow;
            }
        }
    });
</script>

過渡動畫(添加多個)

  • 如何同時給多個元素添加過渡動畫
    • 通過transition可以給單個元素添加過渡動畫,如果想給多個元素添加過渡動畫,那么就必須通過transition-group來添加
    • transition-group和transition的用法一致,只是一個是給單個元素添加動畫,一個是給多個元素添加動畫而已
    • 示例(不是最終版,里面還有bug,下面有講注意點):
<style>
    *{
        margin: 0;
        padding: 0;
    }
    .v-enter{
        opacity: 0;
    }
    .v-enter-to{
        opacity: 1;
    }
    .v-enter-active{
        transition: all 3s;
    }
    .v-leave{
        opacity: 1;
    }
    .v-leave-to{
        opacity: 0;
    }
    .v-leave-active{
        transition: all 3s;
    }
</style>
<div id="app">
    <form>
        <input type="text" v-model="name">
        <input type="submit" value="添加" @click.prevent="add">
    </form>
    <ul>
        <transition-group appear>
            <li v-for="(person,index) in persons" :key="person.id" @click="del(index)">
                <input type="checkbox">
                <span>{{index}} --- {{person.name}}</span>
            </li>
        </transition-group>
    </ul>
</div>
<script>
let vue = new Vue({
    el: '#app',
    data: {
        persons: [
            {name: "zs", id: 1},
            {name: "ls", id: 2},
            {name: "ww", id: 3}
            ],
        name: ""
    },
    methods: {
        add(){
            let lastPerson = this.persons[this.persons.length - 1];
            let newPerson = {name: this.name, id: lastPerson.id + 1};
            // this.persons.push(newPerson);
            this.persons.unshift(newPerson);
            this.name = "";
        },
        del(index){
            this.persons.splice(index, 1);
        }
    }
});
</script>
注意點:
  • 1.標簽問題

    • 默認情況下transition-group會將動畫的元素放到span標簽中
      • 解決方法:我們可以通過tag屬性來指定將動畫元素放到什么標簽中(把html里面對應的標簽刪除,tag屬性就會自動添加標簽)
  • 2.transition-group動畫混亂問題

    • 一般情況下組動畫出現(xiàn)動畫混亂都是因為v-for就地復用導致的
      • 解決方案:我們只需要保證所有數(shù)據(jù)key永遠是唯一的即可
    • 示例(上面示例就有這個bug),解決如下:
      • 1.data里面新增一個id,賦值為3(list的長度)
      • 2.add方法中
        • 添加this.id++
        • let lastPerson = this.persons[this.persons.length - 1];刪除
        • let newPerson = {name: this.name, id: lastPerson.id + 1};改成let newPerson = {name: this.name, id: this.id};
        • 成品View Model如下:
<script>
    let vue = new Vue({
        el: '#app',
        data: {
            persons: [
                {name: "zs", id: 1},
                {name: "ls", id: 2},
                {name: "ww", id: 3}
                ],
            name: "",
            id: 3
        },
        methods: {
            add(){
                this.id++;
                // let lastPerson = this.persons[this.persons.length - 1];
                let newPerson = {name: this.name, id: this.id};
                // this.persons.push(newPerson);
                this.persons.unshift(newPerson);
                this.name = "";
            },
            del(index){
                this.persons.splice(index, 1);
            }
        }
    });
</script>
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容