zoukankan      html  css  js  c++  java
  • 05.vue-charp-05 内置指令

    基本指令

    v-cloak

    v-cloak不需要表达式,它会在Vue实例结束编译时从绑定的HTML元素上移除,经常和CSS的display: none;配合使用:

    这时虽然已经加了指令v-cloak,但其实并没有起到任何作用,当网速较慢、Vue.js文件还没加载完时,在页面上会显示{{ message }}的字样,直到Vue创建实例、编译模板时,DOM才会被替换,所以这个过程屏幕是有闪动的。只要加一句CSS就可以解决这个问题了:
    [v-cloak] {
    display: none;
    }
    在一般情况下,v-cloak是一个解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用,但是在具有工程化的项目里,比如后面进阶篇将介绍webpack和vue-router时,项目的HTML结构只有一个空的div元素,剩余的内容都是由路由去挂载不同组件完成的,所以不再需要v-cloak。

    v-once

    不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容

    <body>
        <div id="app">
            <input type="text" v-model="message" placeholder="message" />
            <h1 v-once>v-once指渲染一次:{{message}}</h1>
            <h1>双向绑定,动态显示:{{message}}</h1>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            new Vue({
                el: '#app',
                data: {
                    message: 'hello world'
                }
            })
        </script>
    </body>
    

    条件渲染

    v-if、v-else-if、v-else

    <body>
        <div id="app">
            <input type="text" v-model="status" placeholder="status值" />
            <h1 v-if="status === 1">status值=1</h1>
            <h1 v-else-if="status === 1">status值=1</h1>
            <h1 v-else="status === 1">status值=1</h1>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            new Vue({
                el: '#app',
                data: {
                    status: 1
                }
            })
        </script>
    </body>
    

    v-show

    v-show是改变元素的CSS属性display。当v-show表达式的值为false时,元素会隐藏,查看DOM结构会 display: none;

    <body>
        <div id="app">
            <input type="text" v-model="status" placeholder="status值" />
            <h1 v-show="status == 1">status值=1时才显示,否则隐藏</h1>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            new Vue({
                el: '#app',
                data: {
                    status: 1
                }
            })
        </script>
    </body>
    

    列表渲染 v-for

    <body>
        <div id="app">
            <ul>
                <li v-for="book in books">{{ book.name }}</li>
            </ul>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            new Vue({
                el: '#app',
                data: {
                    books: [
                        { name: '《Vue.js实战》' },
                        { name: '《JavaScript语言精粹》' },
                        { name: '《JavaScript高级程序设计》' }
                    ]
                }
            })
        </script>
    </body>
    

    v-for中可选参数:Index

    <body>
        <div id="app">
            <ul>
                <li v-for="(book,index) in books">{{index}}.{{ book.name }}</li>
            </ul>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            new Vue({
                el: '#app',
                data: {
                    books: [
                        { name: '《Vue.js实战》' },
                        { name: '《JavaScript语言精粹》' },
                        { name: '《JavaScript高级程序设计》' }
                    ]
                }
            })
        </script>
    </body>
    

    v-for 遍历对象属性

    遍历对象属性时,有两个可选参数,分别是键名和索引:

    <body>
        <div id="app">
            <ul>
                <li v-for="value in user">{{value}}</li>
            </ul>
            <ul>
                <li v-for="(value, key, index) in user">
                    {{ index }} - {{ key }}: {{ value }}
                </li>
            </ul>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            new Vue({
                el: '#app',
                data: {
                    user: {
                        name: 'Aresn',
                        gender: '男',
                        age: 26
                    }
                }
            })
        </script>
    </body>
    

    数组更新

    Vue在检测到数组变化时,并不是直接重新渲染整个列表,而是最大化地复用DOM元素。替换的数组中,含有相同元素的项不会被重新渲染,因此可以大胆地用新数组来替换旧数组,不用担心性能问题。

    <body>
        <div id="app">
            <ul>
                <li v-for="(book,index) in books">{{index}}.{{ book.name }}</li>
            </ul>
            <button type="button" @click="add">添加</button>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            var app = new Vue({
                el: '#app',
                data: {
                    books: [
                        { name: '《Vue.js实战》' },
                        { name: '《JavaScript语言精粹》' },
                        { name: '《JavaScript高级程序设计》' }
                    ]
                },
                methods: {
                    add: function () {
                        this.books.push({ name: '《Electron In Action》' });
                    }
                },
            })
    
        </script>
    </body>
    

    数组元素和个数更新

    需要注意的是,以下变动的数组中,Vue是不能检测到的,也不会触发视图更新:

    • 通过索引直接设置项,比如app.books[3] = {…}。
    • 修改数组长度,比如app.books.length = 1。

    解决第一个问题可以用两种方法实现同样的效果,第一种是使用Vue内置的set方法:
    Vue.set(app.books, 3, {
    name: '《CSS揭秘》',
    author: '[希] Lea Verou'
    });
    如果是在webpack中使用组件化的方式(进阶篇中将介绍),默认是没有导入Vue的,这时可以使用$set,例如:
    this.$set(app.books, 3, {
    name: '《CSS揭秘》',
    author: '[希] Lea Verou'
    })
    // 这里的this指向的就是当前组件实例,即app。在非webpack模式下也可以用$set方法,例如app.$set(…)
    另一种方法:
    app.books.splice(3, 1, {
    name: '《CSS揭秘》',
    author: '[希] Lea Verou'
    })
    第二个问题也可以直接用splice来解决:
    app.books.splice(1);

    <body>
        <div id="app">
            <ul>
                <li v-for="(book,index) in books">{{index}}.{{ book.name }}</li>
            </ul>
            <button type="button" @click="updateArrayElement">更新数组元素</button>
            <button type="button" @click="deleArray">截取数组</button>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            var app = new Vue({
                el: '#app',
                data: {
                    books: [
                        { name: '《Vue.js实战》' },
                        { name: '《JavaScript语言精粹》' },
                        { name: '《JavaScript高级程序设计》' }
                    ]
                },
                methods: {
                    updateArrayElement: function () {
                        //方法1
                        this.books.splice(0, 1, { name: '《Vue.js实战》(this.books.splice)' });
                        //方法2
                        this.$set(this.books, 1, { name: '《JavaScript语言精粹》(app.$set)' });
                        //方法3
                        Vue.set(this.books, 2, { name: 'JavaScript高级程序设计》(Vue.set)' })
                    },
                    deleArray: function () {
                        this.books.splice(1);
                    }
                }
            })
    
        </script>
    </body>
    

    过滤与排序

    <body>
        <div id="app">
            <ul>
                <li v-for="(book,index) in books">{{book.id}}.{{ book.name }}</li>
            </ul>
            <ul>
                <li v-for="(book,index) in filterBooks">{{book.id}}.{{ book.name }}</li>
            </ul>
            <ul>
                <li v-for="(book,index) in sortedBooks">{{book.id}}.{{ book.name }}</li>
            </ul>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            var app = new Vue({
                el: '#app',
                data: {
                    books: [
                        { id: 1, name: '《Vue.js实战》' },
                        { id: 2, name: '《JavaScript语言精粹》' },
                        { id: 3, name: '《JavaScript高级程序设计》' }
                    ]
                }, computed: {
                    filterBooks: function () {
                        return this.books.filter(function (book) {
                            return book.name.match(/JavaScript/);
                        });
                    },
                    sortedBooks: function () {
                        return this.books.sort(function (a, b) {
                            return b.id - a.id;
                        });
                    }
                },
    
            })
    
        </script>
    </body>
    

    方法与事件

    基本用法

    @click的表达式可以直接使用JavaScript语句,也可以是一个在Vue实例中methods选项内的函数

    • 无参数 可以不用写括号,如:@click="handleAdd"

    • 特殊变量$event:

      Vue提供了一个特殊变量$event,用于访问原生DOM事件,例如下面的实例可以阻止链接打开:

    <body>
        <div id="app">
            count:{{count}}
            <button @click="add()">+1</button>
            <button @click="add(10)">+10</button>
            <button @click="add2">+1</button>
            <a href="http://baidu.com" @click="addWithEvent('禁止打开', $event)">打开链接</a>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            var app = new Vue({
                el: '#app',
                data: {
                    count: 0,
                }, methods: {
                    add: function (count) {
                        count = count || 1;
                        this.count += count;
                    },
                    add2: function () {
                        this.count += 1;
                    },
                    addWithEvent: function (msg, event) {
                        event.preventDefault();
                        alert(msg);
                    }
                }
            })
        </script>
    </body>
    
    

    修饰符

    在上例使用的event.preventDefault()也可以用Vue事件的修饰符来实现,在@绑定的事件后加小圆点“.”,再跟一个后缀来使用修饰符。Vue支持以下修饰符:

    <body>
        <div id="app">
            <a href="http://baidu.com" @click="addWithEvent1($event)">正常打开链接</a>
            <a href="http://baidu.com" @click="addWithEvent2('禁止打开', $event)">禁止打开链接</a>
            <a href="http://baidu.com" @click.prevent="addWithEvent3('禁止打开')">禁止打开链接</a>
        </div>
        <script src="../lib/vue.2.6.11.js"></script>
        <script>
            var app = new Vue({
                el: '#app',
                data: {
                    count: 0,
                }, methods: {
                    addWithEvent1: function (event) {
                        alert(msg);
                    },
                    addWithEvent2: function (msg, event) {
                        event.preventDefault();
                        alert(msg);
                    },
                    addWithEvent3: function (msg, event) {
                        alert(msg);
                    }
                }
            })
        </script>
    </body>
    

    练习:购物车

    index.html

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>Vue 示例:购物车</title>
        <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    
    <body>
        <div id="app" v-cloak>
            <template v-if="list.length">
                <table>
                    <thead>
                        <th>序号</th>
                        <th>商品名称</th>
                        <th>商品单价</th>
                        <th>购买数量</th>
                        <th>操作</th>
                    </thead>
                    <tbody>
                        <tr v-for="(item, index) in list">
                            <td>{{index + 1}} </td>
                            <td>{{item.name}}</td>
                            <td>{{item.price}}</td>
                            <td>
                                <button @click="handleReduce(index)" :disabled="item.count === 1">-</button>
                                {{item.count}}
                                <button @click="handleAdd(index)">+</button>
                            </td>
                            <td>
                                <button @click="handleRemove(index)">移除</button>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <div>
                    总价:¥{{totalPrice}}
                </div>
            </template>
            <div v-else>
                购物车为空
            </div>
        </div>
        <script src="../../lib/vue.2.6.11.js"></script>
        <script src="index.js"></script>
    </body>
    
    </html>
    

    index.js

    var app = new Vue({
        el: '#app',
        data: {
            list: [
                {
                    id: 1,
                    name: "iphone7",
                    price: 6188,
                    count: 1
                },
                {
                    id: 2,
                    name: "IPad pro",
                    price: 5888,
                    count: 1
                }, {
                    id: 3,
                    name: "MacBook Pro",
                    price: 21488,
                    count: 1
                }
            ]
        }, methods: {
            handleReduce: function (index) {
                if (this.list[index].count === 1) {
                    return;
                }
                this.list[index].count--;
            },
            handleAdd: function (index) {
                this.list[index].count++;
            },
            handleRemove: function (index) {
                this.list.splice(index, 1);
            },
        }, computed: {
            totalPrice: function () {
                let total = 0;
                for (let i = 0; i < this.list.length; i++) {
                    const item = this.list[i];
                    total += item.price * item.count;
                }
                // return total;
                return total.toString().replace(/B(?=(d{3})+$)/g, ',');
            }
        }
    })
    

    style.css

    [v-cloak] {
        display: none;
    }
    table{
        border: 1px solid #e9e9e9;
        border-collapse: collapse;
        border-spacing: 0;
        empty-cells: show;
    }
    th, td{
        padding: 8px 16px;
        border: 1px solid #e9e9e9;
        text-align: left;
    }
    th{
        background: #f7f7f7;
        color: #5c6b77;
        font-weight: 600;
        white-space: nowrap;
    }[v-cloak] {
        display: none;
    }
    table{
        border: 1px solid #e9e9e9;
        border-collapse: collapse;
        border-spacing: 0;
        empty-cells: show;
    }
    th, td{
        padding: 8px 16px;
        border: 1px solid #e9e9e9;
        text-align: left;
    }
    th{
        background: #f7f7f7;
        color: #5c6b77;
        font-weight: 600;
        white-space: nowrap;
    }
    
  • 相关阅读:
    《安富莱嵌入式周报》第241期:2021.11.222021.11.28
    开源功率计,带电源功能,专用于物联网功耗测量
    实用技能分享,充分利用内联函数,内联汇编,内部函数和嵌入式汇编提升代码执行效率和便捷性(20211217)
    【STM32F407】第7章 RTX5任务管理
    【STM32H7】第8章 RTX5任务优先级分配和修改
    H7TOOL的LUA小程序教程第3期:使用LUA控制H7TOOL的LCD简易界面设计
    【小知识】使用串口8bit,7bit和6bit数据格式的奇偶校验问题
    【第3版emWin教程】第53章 emWin6.x的按钮Button控件
    【第3版emWin教程】第51章 emWin6.x的Window窗口控件
    各种GUIBuilder体验TouchGFX,AppWizard,GUIX Studio,Embedded Wizard,AWTK,柿饼UI,LVGL,Qt fot MCU等(20211221)
  • 原文地址:https://www.cnblogs.com/easy5weikai/p/13232477.html
Copyright © 2011-2022 走看看