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>
发布了51 篇原创文章 · 获赞 13 · 访问量 3059

猜你喜欢

转载自blog.csdn.net/Sheng_zhenzhen/article/details/104622978