Vue指令(巨全、巨詳細)

Vue指令

  • VUE指令:directive

1.都是按照v- xxx處理的,它是vue中規定給元素設置的自定義屬性, v-開頭,放在元素的行間屬性,有着特殊意義的一些詞;
2.當vue加載成功並進行處理的時候,會按照相關的規則解析和宣傳視圖,遇到對應的指令實現對應的功能
命令;
3.指令放在行間的屬性值,當編譯時,首先會去查找在vue的data中是否有這個屬性,如果沒有,就報錯;
4.在使用指令時,會先找數據類型中的值,如果數據類型中沒有,那麼就去找data或methods中的屬性名;

1.基礎指令

  • {{}}: 小鬍子語法可以將data中數據放入其中
  1. v-model-般給表單元素設置的,實現表單元素和數據之間的相互綁定
    1)先把數據綁定給表單元素,一般把數據賦值給表單元素的value、
    2)監聽表單元素的內容改變
    3)內容改變後,會把對應的數據也改變
    4)對應的數據改變,視圖中所有用到數據的地方都會重新渲染
    視圖<=>數據
    在vue框架中給表單元素設置value等屬性是沒有意義的。
  1. v-html/v-text:給非表單元素設置內容,v-html支持對於標籤的自動識別,v-text 會把所有內容分都當做文本,傳統的鬍子語法,在vue沒有 加載完成之前,會把{{xxx}}展示在頁面中,當vue 加載完纔會出現真正的內容,這樣體驗不好
  1. v-bind:給元素的內置屬性動態綁定數據,例如:給img綁定動態的圖片路徑地址
    可以簡寫成爲:,也就是v-bind:src 等價於:src
  1. v-once:綁定的數據是一次性的, 後面不論數據怎麼改變,視圖也都不會重新渲染
  1. v-if:如果對應的值是TRUE,當前元素會在結構中顯示,如果是FALSE,當前元素會在結構中移除(它控制的是組件的加載和卸載的操作=>DOM的增加和刪除) ;還有對應的v-else-if /v-else等指令;
    v-if: 控制元素的顯示隱藏;如果不是布爾,會默認轉成布爾;如果是false,直接刪除了原有的元素;
    v-else-if: v-if成立就不走這個,if條件不成立走這個
    v-else: v-else-if不成立走這個,成立不走,if連寫成立一個
  1. v-show:和v- if類似,只不過它是控制元素樣式的顯示隱藏(display的操作)
  • v- if是控制組件存不存在,對於結果是FALSE,不存在的組件來說,視圖渲染的時候無需渲染這部分內容;而v-show則不行,因爲不管是顯示還是隱藏,結構都在,所以視圖渲染的時候這部分也要渲染;
  • 在過於頻繁的切換操作中,v-if明顯要比v-show要低一些
  • 通過設置布爾值來控制元素是否顯示,如果是true,則顯示,false,則隱藏;如果不是一個布爾值,那麼會默認轉布爾;通過設置元素的display屬性來控制是否顯示;


<body>
    <div id="app">
        <div v-text="x"></div>
        <div v-html="x"></div>
        <div v-show="1" r-yy="1">中國加油</div>
        <div v-if="1===1">武漢加油</div>
        <div v-else-if="3===3">天氣真好</div>
        <div v-else>北京加油</div>
        <input type="text" v-model="a">
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
      // 指令: v-開頭,放在元素的行間屬性,有着特殊意義的一些詞;
      // v-model:一般用於表單元素;將data中數據放在input框中,當input值發生改變,數據也會跟着發生改變;
      // {{}}: 小鬍子語法可以將data中數據放入元素中
      // v-text: 可以將data中的文本放入元素中
      // v-html:可以識別標籤
      // v-show :通過設置布爾值來控制元素是否顯示,如果是true,則顯示,false,則隱藏;如果不是一個布爾值,那麼會默認轉布爾;通過設置元素的display屬性來控制是否顯示;
      // 以指令放在行間的屬性值,當編譯時,首先會去查找在vue的data中是否有這個屬性,如果沒有,就報錯;
      // v-if: 控制元素的顯示隱藏;如果不是布爾,會默認轉成布爾;如果是false,直接刪除了原有的元素;
      // v-else-if: 
      // v-else:    
        let vm = new Vue({
            el:"#app",
            data:{
                a:1,
                x:"<span>好好學習</span>"
            }
        })
    </script>
</body>
</html>

2.v-for:循環動態綁定數據

  • v-for:循環動態綁定數據( v-for="(item,index) in arr")
  • 可以循環數字:item從1開始到當前數字, index從0開始
  • 可以循環字符串:item是每一個字符,index索引
  • 可以循環對象:item是屬性值,index是屬性名,第三個參是索引
  • 可以循環數組:item是每一項,index是索引
<body>
    <div id="app">
        <!--  a 代表數組的每一項,index代表數組的索引 arr是data中一個變量-->
        <!-- 需要創建什麼元素,就把v-for放在哪個元素身上 -->
        <!-- v-for可以循環數字 -->
        <div v-for="(a,index)  in arr">{{a}}索引{{index}}</div>
        <ul>
            <!-- <li v-for="a in num">{{a}}</li> -->
            <!-- 也可以循環字符串 -->
            <!-- <li v-for="(a,index) in str">{{a}}索引{{index}}</li> -->
            <!-- a是屬性值,b是屬性名 -->
            <li v-for="(a,b,c) in obj">{{a}}{{b}}{{c}}</li>
            <!-- <li v-for="a in ary">{{a.fruit}}</li> -->
        </ul>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        // v-for : 可以循環數組,字符串,數字,對象
        let vm = new Vue({
            el:"#app",
            data:{
                arr:[100,200,300,400],
                num:6,
                str:"zhonghua",
                obj:{name:"zfpx",age:10},
                ary:[{fruit:"草莓"},{fruit:"蘋果"}]
            }
        })
        
    </script>
</body>

v-for練習

    <div id="app">
        <ul>
            <li v-for="(a,index) in  fruits">
                {{index+1}}.{{a.name}}
                <ul>
                    <!--a 只在當前子集可以使用-->
                    <li v-for="(b,index) in a.color">
                        <!--index如果在這個循環中不存在,會向上一級循環查找;-->
                        {{index+1}}.{{b}}
                    </li>
                </ul>
            </li>
        </ul>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                fruits: [{
                    name: "蘋果",
                    color: ["green", "red"]
                }, {
                    name: "香蕉",
                    color: ["yellow", "green"]
                }, {
                    name: "西瓜",
                    color: ["red", "white"]
                }]
            }
        })
    </script>

v-for要加:key

v-forkey.jpg

  • 不加key當選中呂不爲時,添加楠楠後選中的確是李斯,並不是我們想要的結果,我們想要的是當添加楠楠後,一種選中的是呂不爲
  • 加key同樣當選中呂不爲時,添加楠楠後依舊選中的是呂不爲。
  • vue中列表循環需加:key=“唯一標識” 唯一標識可以是item裏面id index等,因爲vue組件高度複用增加Key可以標識組件的唯一性,爲了更好地區別各個組件 key的作用主要是爲了高效的更新虛擬DOM
<body>
    <div id="app">
        <div>
          <input type="text" v-model="name">
          <button @click="add">添加</button>
        </div>
        <ul>
          <li v-for="(item, i) in list" :key="item.id">
            <input type="checkbox"> {{item.name}}
          </li>
        </ul>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        // 創建 Vue 實例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            name: '',
            newId: 3,
            list: [
              { id: 1, name: '李斯' },
              { id: 2, name: '呂不韋' },
              { id: 3, name: '嬴政' }
            ]
          },
          methods: {
            add() {
             //注意這裏是unshift
              this.list.unshift({ id: ++this.newId, name: this.name })
              this.name = ''
            }
          }
        });
      </script>
      </div>
</body>
</html>

3.v-bind :class :style

v-bind
將普通的屬性轉成動態的屬性,可以去獲取data中的數據;

v-bind:class :屬性是可以是對象,裏面的屬性名是class的名字,後面需要跟布爾值,屬性值時true,該樣式有效,false該樣式無效;如果是數組的話,是去獲取data中的屬性名對應的屬性值就是class的名字

v-bind:style: 後面可以是對象 數組 或者data中屬性名

    <div id="app">
        <!-- v-bind:可以省略 -->
        <!-- <img :src="imgSrc" alt=""> -->
        <!-- <div :a="imgSrc"></div> -->
        <div v-bind:class="{x:flag}">中國</div>
        <div v-bind:class="{x:flag,y:flag}">北京</div>
        <!-- 如果是數組的話,是去獲取data中的屬性名對應的屬性值就是class的名字 -->
        <div v-bind:class="a">中國</div>
        <div v-bind:class="[a,b]">北京</div>
        <ul>
            <li v-for="(a,index) in arr" :class="{y:index%2}">{{a}}</li>
        </ul>
        <div v-bind:style="{fontSize:num+'px'}">加油</div>
        <div v-bind:style='z'>666888</div>
        <div :style="[z]">666888</div>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
// v-bind
// 1.將普通的屬性轉成動態的屬性,可以去獲取data中的數據;
// 2. v-bind:class :屬性是可以是對象,裏面的屬性名是class的名字,屬性值時true,該樣式有效,false該樣式無效
// 3. v-bind:style
        new Vue({
            el: "#app",
            data: {
                imgSrc: "../../images/16.jpg",
                flag: true,
                a: "x",
                b: "y",
                arr: [1, 2, 3, 4, 5],
                num: 60,
                z: {
                    color: "red"
                }
            },
            methods: {

            },
            filters: {

            }
        });
    </script>

4.v-model(表單)

v-model : 雙向數據綁定;一般用於表單元素
在單選框中,被選中的那一項,會把input框的value值賦值給sex;v-model的值如果在單選框中相同,他們就互斥;
多選框:v-model可以綁定一個數組,那麼當該項被選中時,會把該input框中value放到數組裏面;如果多選框v-model綁定的不是一個數組,那麼默認會將該值轉成布爾值,控制所有複選框的選中狀態

<body>
    <div id="app">
      <!-- <input type="text" v-model="msg"> -->
      <!-- <input type="radio" v-model="sex" value="1">男
      <input type="radio" v-model="sex" value="2">女
      <input type="radio" v-model="food" value="3">水餃 -->
      <input type="checkbox" v-model="hobby" value="游泳">游泳
      <input type="checkbox" v-model="hobby" value="爬山">爬山
      <input type="checkbox" v-model="hobby" value="打球">打球
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
  
    <script>
        // v-model : 雙向數據綁定;一般用於表單元素
        // 在單選框中,被選中的那一項,會把input框的value值賦值給sex;v-model的值如果在單選框中相同,他們就互斥;
        // 多選框:v-model可以綁定一個數組,那麼當該項被選中時,會把該input框中value放到數組裏面;如果多選框v-model綁定的不是一個數組,那麼默認會將該值轉成布爾值,控制所有複選框的選中狀態
        let vm = new Vue({
            el:"#app",
            data:{
                msg:"上課了",
                sex:"1",//數字和字符串都可以
                food:"3",
                hobby:["游泳"]
                //hobby:1
            },
            created(){
            },
            methods:{
                
            },
            filters:{ 
                
            }
        });
    </script>
</body>

Vue優化指令

  • v-pre : 跳過這個元素的編譯;加快了它的編譯過程
  • v-cloak : 未編譯完,頁面看不到鬍子
  • v-once : 只渲染一次;以後更改數據也不再更新了;

v-pre : 跳過這個元素的編譯;加快了它的編譯過程
v-cloak : 未編譯完,頁面看不到鬍子
這個指令保持在元素上直到關聯實例結束編譯。和 CSS 規則如 [v-cloak] { display: none } 一起用時,這個指令可以隱藏未編譯的 Mustache 標籤直到實例準備完畢。
[v-cloak] {
display: none;
}
v-once : 只渲染一次;以後更改數據也不再更新了;
當寫的結構時靜態的時候,可以使用這個指令;

<head>
    <style>
        [v-cloak] {
            display: none;
        }
    </style>
</head>

<body>
    <div id="app">
        <button @click="fn">顯示/隱藏</button>
        <div v-once>{{msg}}</div>
        <br>
        <div v-cloak>{{msg}}</div>
        <ul>
            <li>button1</li>
            <li>button2</li>
            <li>button3</li>
        </ul>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        // v-pre : 跳過這個元素的編譯;加快了它的編譯過程
        // v-cloak : 未編譯完,頁面看不到鬍子
        // 這個指令保持在元素上直到關聯實例結束編譯。和 CSS 規則如 [v-cloak] { display: none } 一起用時,這個指令可以隱藏未編譯的 Mustache 標籤直到實例準備完畢。
        // [v-cloak] {
        // display: none;
        // } 
        // v-once : 只渲染一次;以後更改數據也不再更新了;
        // 當寫的結構時靜態的時候,可以使用這個指令;
        let vm = new Vue({
            el: "#app",
            data: {
                show: true,
                msg: "你很好"
            },
            methods: {
                fn() {
                    //this.show=!this.show;
                    this.msg = "你很帥"
                }
            }
        })
    </script>
</body>

Vue事件指令

  • 給元素綁定的事件的方法,需要放在methods中
  • 方式:v-on (簡寫@) :用來實現事件綁定的指令
    • v-on:click=’ xxx’
    • @click='xxx
<body>
    <!-- 
        v-on (簡寫@) :用來實現事件綁定的指令
        v-on:click=' xxx'
        @click='xxx
        1.事件觸發的時候,需要傳遞參數信息,把方法加小括號,$event是事件對象
        v-on:click='sum( $event,10,20)
        2.事件修飾符
        常規修飾符: @click . prevent/stop = 'xxx'
        按鍵修飾符: @keydown. enter/space/delete/up/right/ down/left...=' xxx’
        鍵盤碼: @keydown.13 = 'xxx'
        組合按鍵: @keydown.al1t.67 = 'xxx’ //=>ALT+C
     -->
    <div id="app">
        <a href="https://www.baidu.com/" @click.prevent.stop='func'>
            666</a>
        <!-- <button v-on:click='func' ></button> -->
        <!-- <button v-on:click='sum( $event,10, 20)'></button> -->
        <input type="text" placeholder="請輸入搜索內容" v-model="text" @keydown.alt.67="func">
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                text: ""
            },
            methods: {
                func(ev) {
                    // console.log(this);
                    // if(ev.keyCode===13){

                    //     alert("666")
                    // }
                    alert("666");
                },
                sum(ev, n, m) {
                    console.log(arguments);

                }
            }
        })
    </script>
</body>

vue的事件對象

  • 綁定事件時,可以有小括號,也可以沒有
    1.在綁定事件時,如果沒有小括號,那麼第一個參數就是事件對象
    2. 如果有小括號,但是沒有傳參,那麼e默認是undefined;
    3. 如果需要事件對象,並且需要傳參,那麼需要在綁定時使用$event進行佔位;

  • 事件觸發的時候,需要傳遞參數信息,把方法加小括號,$event是事件對象

    • v-on:click=‘sum( $event,10,20)’
    <div id="app">
        <button @click="fn($event,100,200)">提交</button>
        <input type="text" @keyup="fn">
        {{msg}}
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                msg: "該喫飯了"
            },
            methods: {
                // 綁定事件時,可以有小括號,也可以沒有
                // 1.在綁定事件時,如果沒有小括號,那麼第一個參數就是事件對象 
                // 2. 如果有小括號,但是沒有傳參,那麼e默認是undefined;
                // 3. 如果需要事件對象,並且需要傳參,那麼需要在綁定時使用$event進行佔位;
                fn(e, a) { // e: 事件對象
                    console.log(e, a);
                }
            }
        });
    </script>

2.vue事件修飾符

  • vue事件修飾符
    常規修飾符: @click . prevent/stop = ‘xxx’
    按鍵修飾符: @keydown. enter/space/delete/up/right/ down/left…=’ xxx’
    鍵盤碼: @keydown.13 = ‘xxx’
    組合按鍵: @keydown.alt.67 = 'xxx’ //=>ALT+C
  • vue常規事件修飾符:
    • 原生JS中e.stopPropagation() => @click . stop="”

.stop: 阻止事件的冒泡傳播; 從裏向外
.prevent: 阻止事件的默認行爲
.capture: 控制事件在捕獲階段執行 從外向裏
.once : 只執行一次
.passive: 修飾onscroll事件,不會等到onscroll執行完,就會立即執行下一次,提高代碼的性能;
.self:只有點擊自己的時候纔會執行

  • 按鍵修飾符:

.enter .tab .delete .esc .space .up .down .left .right

<body>
    <div id="app">
       <div @click.capture="fn1" style="width:100px;height:100px;background: red;">
            grandparent
            <div @click.self="fn2">
                parent
                <div @click.once="fn3">
                    child
                </div>
            </div>
        </div>
        <input type="text" @keyup.left="fn">
        <div @click="fn1">123456</div>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        // 原生JS中e.stopPropagation() 
        // 事件修飾符
        // .stop: 阻止事件的冒泡傳播;
        // .prevent: 阻止事件的默認行爲
        // .capture: 控制事件在捕獲階段執行
        // .once : 只執行一次
        // .passive: 修飾onscroll事件,不會等到onscroll執行完,就會立即執行下一次,提高代碼的性能;
        // .self:只有點擊自己的時候纔會執行 

        // 鍵盤修飾符:
        // .enter  .tab  .delete  .esc  .space  .up .down  .left .right
        let vm = new Vue({
            el:"#app",
            data:{  
                msg:"該喫飯了"
            },
            methods:{
                fn1(){
                    console.log("outer");
                },
                fn2(){
                    console.log("inner");
                },
                fn3(){
                    console.log("center");
                },
                fn(){
                    console.log("快下課了");
                }
            }
        });
        // 1. button  div:點擊按鈕隱藏,再點擊顯示
        // 2. input 框,輸入內容,回車

    </script>
</body>

Vue自定義指令

  • Vue除了核心的內置指令,vue還可以自定義指令
  • 自定義指令:
    • 全局自定義指令
    • 局部自定義指令
<body>
    <div id="app">
        <div v-drag style="width:100px;height:100px;background: red;position: absolute;">
            <div v-drag></div>
        </div>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>      
        // 全局指令
        Vue.directive("drag", {
            inserted: function (ele) {
                ele.onmousedown = function (e) {
                    // this --> 
                    // 點擊時,記錄鼠標距離盒子邊框的位置
                    this.l = e.clientX - this.offsetLeft;
                    this.t = e.clientY - this.offsetTop;
                    document.onmousemove = function (e) {
                        ele.style.left = e.clientX - ele.l + "px";
                        ele.style.top = e.clientY - ele.t + "px";
                    }
                    document.onmouseup = function () {
                        document.onmousemove = null;
                        document.onmouseup = null;
                    }
                }
                console.log(1);

            }
        });

        let vm = new Vue({
            el: "#app",
            directives: {
                // 定義局部指令  局部命令優先級高
                drag(ele) { // ele: 代表加上v-drag的元素 drag 用了幾次,輸出幾次;
                    ele.onmousedown = function (e) {
                        // this --> 
                        // 點擊時,記錄鼠標距離盒子邊框的位置
                        this.l = e.clientX - this.offsetLeft;
                        this.t = e.clientY - this.offsetTop;
                        document.onmousemove = function (e) {
                            ele.style.left = e.clientX - ele.l + "px";
                            ele.style.top = e.clientY - ele.t + "px";
                        }
                        document.onmouseup = function () {
                            document.onmousemove = null;
                            document.onmouseup = null;
                        }
                    }
                }
            }
        });
        // let vm1 = new Vue({
        //     el:"#app1"
        // });
    </script>
</body>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章