• Vue.js 常用指令(一)


    类似于 Vue.js 这种前端框架,提倡的是减少开发人员对 DOM 的直接操作,而是只关心对数据的操作,不用关心 DOM 元素的渲染。

    v-cloak、v-text、v-bind、v-on 和 v-html

    • v-cloak:用于解决差值表达式闪烁问题
    • v-text:没有闪烁问题的,会覆盖元素中原本的内容,但是插值表达式 只会替换自己的这个占位符,不会把整个元素的内容清空
    • v-html:能够渲染 html 标签元素,而不是将其当做字符串渲染
    • v-bind:用于绑定属性
    • v-on:绑定事件

    示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            /*v-cloak 需要指定 css 属性,即在渲染完成之前隐藏标签元素*/
            [v-cloak] {
                display: none;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <p v-cloak>{{ msg }}</p>		<!--{{ }} 即为插值表达式-->
            <p v-text="msg">===</p>
            <p v-html="msg2"></p>
            <input type="button" v-bind:title="mytitle" value="按钮">
            <input type="button" value="按钮" v-on:click="show">
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    msg: '123',
                    msg2: '<h1>标题一</h1>',
                    mytitle: '自定义title'
                },
                 methods: {
                    show: function() {
                        alert('Hello v-on!')
                    }
                }
            })    
        </script>
    </body>
    </html>
    

    v-on 和 跑马灯效果

    效果:前后循环

    步骤:

    • 截取第一个字符,和后面的字符,进行后前拼接,实现前面的在后面,后面的在前面
    • 开启定时器,循环跑
    • 关闭定时器

    知识点:

    • v-on:绑定点击事件
    • substring:字符串截取
    • 定时器实现循环
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <div id="app">
            <input type="button" value="运行" @click="run">
            <input type="button" value="停止" @click="stop">
        
            <h4>{{ msg }}</h4>
        </div>
       
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    msg: '猥琐发育,别浪!!',
                    intervalId: null,   // 计时器 ID
                },
                methods: {
                    // 运行事件,截取字符串
                    run() {
                        // 若 定时器 ID不为 null,说明是不是重新开始的计时器,直接返回,不需要重新开启一个新的计时器
                        if (this.intervalId !== null) return;
    
                        // 箭头函数中没有 this,即函数内的 this 和函数外的 this 一致
                        this.intervalId = setInterval(()=>{
                            var start = this.msg.substring(0, 1);
                            var end = this.msg.substring(1);
                            this.msg = end + start;
                        }, 400)
                        
                    },
    
                    // 停止计时器
                    stop() {
                        clearInterval(this.intervalId);
                        // 重新赋值为 null,避免因停止后再启动,不能开启定时器
                        this.intervalId = null; 
                    }
                }
            })
        </script>
    </body>
    </html>
    

    Tips:在 vm 实例中,若要访问 data 中的数据,只需调用 this.属性即可,this 便代表 vm 实例!

    v-on 和事件修饰符

    • .stop:阻止冒泡
    • .prevent:阻止默认事件
    • .capture:添加事件侦听器时使用事件捕获模式
    • .self:只当事件在该元素本身(比如不是子元素)触发时触发回调
    • .once:事件只触发一次

    示例:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            .inner {
                height: 150px;
                background-color: darkcyan;
            }
    
            .outer {
                padding: 40px;
                background-color: red;
            }
        </style>
    </head>
    
    <body>
        <div id="app">
            <!-- 阻止向外层元素冒泡 -->
            <!-- <div @click="divhandle" class="inner">
                <input type="button" @click.stop="btnhandle" value="按钮">
            </div> -->
    
            <!-- 阻止默认行为 -->
            <!-- <a href="https://www.baidu.com" @click.prevent="linkClick">百度</a> -->
    
            <!--实现捕获触发事件的机制 -->
            <!-- <div @click.capture="divhandle" class="inner">
                <input type="button" @click="btnhandle" value="按钮">
            </div> -->
    
            <!-- .self 只有点击自己才会触发 -->
            <!-- <div @click.self="divhandle" class="inner">
                <input type="button" @click="btnhandle" value="按钮">
            </div> -->
    
            <!-- .once 只触发一次, 事件修饰符可以嵌套,第一次点击会阻止 a 标签跳转,第二次点击就会跳转-->
            <!-- <a href="https://www.baidu.com" @click.prevent.once="linkClick">百度</a> -->
    
            <!-- .stop 与 .self 的区别 -->
            <div class="outer" @click="div2handle">
                <div @click.self="divhandle" class="inner">
                    <!-- <input type="button" @click.stop="btnhandle" value="按钮"> -->
                    <input type="button" @click="btnhandle" value="按钮">
    
                </div>
            </div>
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {},
                methods: {
                    divhandle() {
                        console.log('div handle 触发')
                    },
    
                    btnhandle() {
                        console.log('btn handle 触发')
                    },
    
                    linkClick() {
                        console.log('跳转链接!')
                    },
    
                    div2handle() {
                        console.log('外层 div');
                    },
                }
            })
        </script>
    </body>
    
    </html>
    

    概念

    • 冒泡:当点击以上 div 中的按钮时,同时也会触发 div 的事件,即同时会输出 divinput 的值,从里向外冒泡
    • 捕获:从外向里

    .stop.self 的区别:

    • .self:只会阻止自己身上冒泡行为的触发,并不会真正阻止冒泡的行为。
    • .stop:会阻止事件向其外层冒泡的行为

    v-model 和数据双向绑定

    v-bind 只能进行单向数据绑定,v-model 可以实现表单元素和 Model 中数据的双向数据绑定。常见的表单的空间元素:input、select、textarea 等。

    所谓的双向数据绑定即修改表单空间元素的值会更改 Vue 实例的值,更改 Vue 实例的值,相应地表单空间元素的值也会发生改变。

    示例一:

    <div id="app">
        <input type="text" v-model="msg">
        <h4>{{ msg }}</h4>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
    
        var vm = new Vue({
            el: '#app',
            data: {
                msg: '123'
            },
            methods: {
    
            }
        })
    </script>
    

    示例二:简易计算器

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    
    <body>
    
        <div id="app">
            <input type="text" v-model="n1">
            <select v-model="opt">
                <option value="+">+</option>
                <option value="-">-</option>
                <option value="*">*</option>
                <option value="/">/</option>
            </select>
            <input type="text" v-model="n2">
            <input type="button" value="=" @click="calc">
            <input type="text" v-model="result">
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
    
            var vm = new Vue({
                el: '#app',
                data: {
                    n1: 0,
                    n2: 0,
                    opt: '+',
                    result: 0
                },
                methods: {
                    calc() {
                        switch (this.opt) {
                            case '+':
                                this.result = parseInt(this.n1) + parseInt(this.n2);
                                break;
                            case '-':
                                this.result = parseInt(this.n1) - parseInt(this.n2);
                                break;
                            case '*':
                                this.result = parseInt(this.n1) * parseInt(this.n2);
                                break;
                            case '/':
                                this.result = parseInt(this.n1) / parseInt(this.n2);
                                break;
                        }
                    }
                }
            })
        </script>
    </body>
    
    </html>
    

    v-bind 修改样式

    class 样式

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            .red {
                color: red;
            }
    
            .thin {
                font-weight: 200;
            }
        </style>
    </head>
    
    <body>
        <div id="app">
            <!-- 传递一个数组 -->
            <!-- <p :class="['red', 'thin']">Vue 中 css 样式</p> -->
    
            <!-- 三元表达式,flag 为 true 应用 thin 样式 -->
            <!-- <p :class="['red', flag?'thin':'']">Vue 中 css 样式</p> -->
    
            <!-- 使用对象替换三元表达式,提高代码可读性 -->
            <!-- <p :class="['red', {'thin': flag}]">Vue 中 css 样式</p> -->
    
            <!-- 直接使用对象 -->
            <p :class="classObj">Vue 中 css 样式</p>
    
        </div>
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    flag: false,
                    classObj: {red: true, thin: false}
                }
            })
        </script>
    </body>
    
    </html>
    
    • 传递一个数组
    • 三元表达式,不够灵活,不推荐使用
    • 直接使用对象形式,键需要单引号扩起来
    • v-bind:引用对象方法,放在 Vue 实例 data 属性中

    内联样式

    <body>
        <div id="app">
            <!-- 直接在元素上通过 `:style` 的形式,书写样式对象 -->
            <!-- 若样式中间有横杠 -,则必须用单引号包裹 -->
            <!-- <p :style="{color: 'red', 'font-size': '40px'}">Vue 中 css 样式</p> -->
    
            <!-- data 中定义样式,再 :style 中引用对象 -->
            <!-- <p :style="styleObj1">Vue 中 css 样式</p> -->
    
            <!-- 通过数组绑定多个样式 -->
            <p :style="[ styleObj1, styleObj2 ]">Vue 中 css 样式</p>
    
    
        </div>
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    styleObj1: { color: 'red', 'font-weight': 200 },
                    styleObj2: { 'font-style': 'italic' }
                }
            })
        </script>
    </body>
    

    Tips:若样式中间有横杠 -,则必须用单引号包裹 ,如 font-size

    v-for 和 key 属性

    v-for 循环

    循环普通数组

    格式:item in 数组,若要获取索引,在 item 后面指定即可,索引从 0 开始。

     <div id="app">
        <!-- <li v-for="item in list">{{ item }}</li> -->
        <li v-for="(item, i) in list">索引:{{ i }},值: {{ item }}</li>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                list: [1, 2, 3]
            } 
        })    
    </script>
    

    循环对象数组

    <div id="app">
        <li v-for="(item, i) in list">ID:{{ item.id }}, Name: {{ item.name }}, 索引:{{ i }}</li>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                list: [
                { id: 1, name: 'zs1' },
                { id: 2, name: 'zs2' },
                { id: 3, name: 'zs3' },
                { id: 4, name: 'zs4' }
                ]
            } 
        })    
    </script>
    

    循环对象

    <div id="app">
        <li v-for="(val, key, i) in user">值: {{ val }}, 键: {{ key }}, 索引: {{ i }}</li>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                user: {
                    id: 1,
                    name: '托尼·屎大颗',
                    gender: '男'
                }
            },
        })    
    </script>
    

    循环数字

    <div id="app">
        <li v-for="count in 10">{{ count }}</li>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {},
        })    
    </script>
    

    Tips: 循环数字从 1 开始,而非 0


    v-for 的 key 属性

    2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的

    • v-for 循环的时候,key 属性只能使用 number 获取 string
    • key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值
    • 在组件中,使用 v-for 循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定唯一的字符串/数字 类型 :key

    示例:

    以下示例动态向数组对象 list 中添加对象,勾选其中一项,当向后添加 push 时,不会更改所勾选的选项。

    而当向前添加 unshift 时,则会更改所勾选的选项,这时就需要指定 key 属性,属性值且必须是 numberstring

    <div id="app">
        ID: <input type="text" v-model='id'>
        NAME: <input type="text" v-model="name">
        <input type="button" value="添加" @click="add">
    
        <!-- 指定 key 属性 -->
        <!-- <p v-for="item in list"> -->
        <p v-for="item in list" :key="item.id">
            <input type="checkbox">{{ item.id }} -- {{ item.name }}
        </p>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                id: '',
                name: '',
                list: [
                    { id: 1, name: '李斯' },
                    { id: 2, name: '嬴政' },
                    { id: 3, name: '赵高' },
                    { id: 4, name: '韩非' },
                    { id: 5, name: '荀子' }
                ]
            },
            methods: {
                add() {
                    // this.list.push({id: this.id, name: this.name});
                    this.list.unshift({id: this.id, name: this.name})
                }
            }
    
        })    
    </script>
    

    v-if 和 v-show

    v-if 和 v-show 都是根据条件展示元素,但是两者还是有些差别。

    • v-if:每次都会重新删除或创建元素,有较高的切换性能消耗
    • v-show:每次不会重新进行 DOM 的删除和创建操作,只是切换了元素的 display:none 样式,有较高的初始渲染消耗
    • 如果元素涉及到频繁的切换,最后不要使用 v-if,而是推荐使用 v-show
    • 如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if
     <div id="app">
        <input type="button" value="按钮" @click="toggle"> 
    
        <h3 v-show="flag">v-if 控制的元素</h3>
        <h3 v-show="flag">v-show 控制的元素</h3>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                flag: false
            },
            methods: {
                toggle() {
                    this.flag=!this.flag
                }
            }
    
        })    
    </script>
    

    MVC 和 MVVM 的关系图解

    总结

    • v-bind:绑定属性、包括 css 样式,简写::
    • v-model:表单空间元素,双向数据绑定,简写:@
    • v-for:循环数组、对象、数组对象,2.2+ 版本需注意 key 属性,属性值类似为 numberstring
    • v-ifv-show:都是根据条件显示元素,但是在渲染时还是有区别的
    • 绑定 css 样式两种方式:v-bind:classv-bind:style
    • vm 实例:el 指定要控制的区域,data:挂载数据,对象类型,methods:挂载方法/事件,对象类型
    • 事件修饰符:.stop、 .prevent、.capture、.self、.once
  • 相关阅读:
    一个FLAG #03# 蛇形填数
    一个FLAG #02# 逆序输出
    一个FLAG #01# 重学C/C++以及算法
    MAVLink笔记 #01# 维基百科翻(译)
    编译原理 #04# 中缀表达式转化为四元式(JavaScript实现)
    Java开发:手机电话号码校验
    解决java poi循环遍历行getLastRowNum出现不准确的问题
    Redis的安装和简单测试
    JS解析xml字符串,并把xml展示在HTML页面上
    解决cxf+springmvc发布的webservice,缺少types,portType和message标签的问题
  • 原文地址:https://www.cnblogs.com/midworld/p/13611010.html
Copyright © 2020-2023  润新知