第五章 内置指令

编辑本文章

5.1  基本指令

5.1.1  v-cloak

    不需要表达式,会在Vue实例结束编译时从绑定的HTML元素上移除,经常和CSS的display:none配合使用。当网速较慢,Vue.js文件还没加载完是,页面上会显示{{message}}字样。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.1 .1 v-cloak</title>
</head>
<style type="text/css">
    [v-cloak] {
        display: none;
    }
</style>
<body>
<div id="app" v-cloak>
    {{message}}
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    //延迟2秒后显示
    setTimeout(() => {
        new Vue({
            el: "#app",
            data: {
                message: "这是文本内容!"
            }
        })
    }, 2000);
</script>
</body>
</html>
View Code

5.1.2  v-once

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

5.2  条件渲染指令

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

    vue条件指令可以根据表达式的值,在DOM中渲染或销毁元素/组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.2.1  v-if、v-else-if、v-else</title>
</head>
<body>
<div id="app">
    <p v-if="status===1">当status为1时显示该行</p>
    <p v-else-if="status===2">当status为2时显示该行</p>
    <p v-else="status===1">否则显示该行</p>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app=new Vue({
        el:"#app",
        data:{
            status:1
        }
    })
</script>
</body>
</html>
View Code

在渲染时,处于效率考虑,会尽可能复用已有的元素而非重新渲染,如果希望每次都重新渲染,可以提供key属性,key的值必须唯一。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.2.1 v-if、v-else-if、v-else</title>
</head>
<body>
<div id="app">
    <template v-if="type === 'name'">
        <label for="">用户名:</label>
        <input type="text" placeholder="输入用户名">
    </template>
    <template v-else>
        <label for="">邮箱:</label>
        <input type="text" placeholder="输入邮箱">
    </template>
    <button @click="handleToggleClick">切换输入类型</button>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app = new Vue({
        el: "#app",
        data: {
            type: "name"
        },
        methods: {
            handleToggleClick: function () {
                this.type = this.type == 'name' ? 'mail' : 'name';
            }
        }
    })
</script>
</body>
</html>
View Code

如果一次性判断的是多个元素,可以在Vue.js内置的<template>元素上使用条件指令

5.2.2  v-show

用法与v-if类似,作用是改变元素的css属性display,当v-show表达式值为false时,元素会隐藏。即display:none。但v-show不能用于内置<template>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-show</title>
</head>
<body>
<div id="app">
    <p v-show="status === 1">当status为1时,显示该行</p>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app = new Vue({
        el: "#app",
        data: {
            status: 2
        }
    })
</script>
</body>
</html>
View Code

5.2.3  v-show与v-if选择

    v-if每次条件变化都会适当销毁或重建元素,若初始值为false,一开始不会渲染,只有第一次条件为真时才会编译。

    v-show只是简单的css属性切换,无论条件真与否,都会编译。相比之下v-if适合条件不经常改变的场景,开销大。v-show适用于频繁切换。

5.3  列表渲染指令v-for

5.3.1  基本使用

    将一个数组遍历或枚举一个对象循环显示。需结合in来使用。v-for与v-if一样同样可以用在内置标签<template>上。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-for基本使用</title>
</head>
<body>
<div id="app">
    <ul>
        <li v-for="book in books">{{ book.name }}</li>
    </ul>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app = new Vue({
        el: "#app",
        data: {
            books: [
                {name: "《Vue.js实战》"},
                {name: "《JavaScript语言精粹》"},
                {name: "《JavaScript高级程序设计》"}
            ]
        }
    })
</script>
</body>
</html>
View Code

    

    v-for支持一个可选参数作为当前项索引

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-for基本使用</title>
</head>
<body>
<div id="app">
    <ul>
        <li v-for="(book,index) in books">{{index}}-{{ book.name }}</li>
    </ul>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app = new Vue({
        el: "#app",
        data: {
            books: [
                {name: "《Vue.js实战》"},
                {name: "《JavaScript语言精粹》"},
                {name: "《JavaScript高级程序设计》"}
            ]
        }
    })
</script>
</body>
</html>
View Code

    遍历对象属性,默认是对象value

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.3.1 v-for遍历对象属性</title>
</head>
<body>
<div id="app">
    <span v-for="value in user">{{value}}</span>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app = new Vue({
        el: "#app",
        data: {
            user: {
                name: "Aresn",
                gender: "",
                age: 38
            }
        }
    })
</script>
</body>
</html>
View Code

v-for遍历对象属性时,可以添加key和index可选参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.3.1 v-for遍历对象属性</title>
</head>
<body>
<div id="app">
    <ul>
        <li v-for="(value,key,index) in user">{{index}}-{{key}}:{{value}}</li>
    </ul>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app = new Vue({
        el: "#app",
        data: {
            user: {
                name: "Aresn",
                gender: "",
                age: 38
            }
        }
    })
</script>
</body>
</html>
View Code

    v-for迭代整数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.3.1  v-for迭代整数</title>
</head>
<body>
<div id="app">
    <span v-for="n in 10">{{n}}</span>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app=new Vue({
        el:"#app"
    })
</script>
</body>
</html>
View Code

 

5.3.2  数组更新

    Vue的核心就是数据与视图的双向绑定,当修改数组时,Vue会检测到数据变化,使用v-for渲染的视图也会例及更新。当通过索引直接设置项或修改数组长度,Vue是无法检测到的。

    Vue包含了观察数据变化的方法,使用它们可改变数组也会触发视图更新;

    如下7个方法会改变调用的原始数组:

    1. push(),在数据后面添加一项
    2. pop()
    3. shift()
    4. unshift()
    5. splice()
    6. sort()
    7. reverse()

    如下三个方法不会改变原始数组,它们返回一个新的数组,当然可以用新数组来替换原数组。

    1. filter()
    2. concat()
    3. slice()

5.3.3  排序与过滤

     当不想改变原数组,想通过一个数组副本来做过滤或排序显示时,可以使用计算属性来返回过滤或排序后的数组

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.3.3 过滤与排序</title>
</head>
<body>
<div id="app">
    <ul>
        <template v-for="book in filterBooks">
            <li>书名:{{book.name}}}</li>
            <li>作者:{{book.author}}}</li>
        </template>
    </ul>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app =new Vue({
        el:"#app",
        data:{
            books:[
                {
                    name:"书籍1",
                    author:"作者1"
                },
                {
                    name:"书籍2",
                    author:"作者2"
                },
                {
                    name:"书籍3",
                    author:"作者3"
                }
            ]
        },
        computed:{
            filterBooks:function(){
                return this.books.filter(function (book) {
                    return book.name.match("2");
                })
            }
        }
    })
</script>
</body>
</html>
View Code

增加排序计算

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.3.3 过滤与排序</title>
</head>
<body>
<div id="app">
    <ul>
        <template v-for="book in filterBooks">
            <li>书名:{{book.name}}}</li>
            <li>作者:{{book.author}}}</li>
        </template>
    </ul>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app =new Vue({
        el:"#app",
        data:{
            books:[
                {
                    name:"书籍1",
                    author:"作者1"
                },
                {
                    name:"书籍2",
                    author:"作者2"
                },
                {
                    name:"书籍3",
                    author:"作者3"
                }
            ]
        },
        computed:{
            filterBooks:function(){
                return this.books.filter(function (book) {
                    return book.name.match("2");
                })
            },
            sortedBooks:function () {
                return this.books.sort(function (a, b) {
                    return a.name.length < b.name.length;
                })
            }
        }
    })
</script>
</body>
</html>
View Code

5.4  方法与事件

  5.4.1 基本用法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.4.1基本使用</title>
</head>
<body>
<div id="app">
    点击次数:{{counter}}
    <button @click="handleAdd()">+1</button>
    <button @click="handleAdd(10)">+10</button>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app=new Vue({
        el:"#app",
        data:{
            counter:0
        },
        methods:{
            handleAdd:function (count) {
                count = count || 1;
                this.counter+=count;
            }
        }
    })
</script>
</body>
</html>
View Code

 

    Vue提供了一个特殊变了$event,用于访问原生DOM事件,如阻止连接打开。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.4.1基本使用</title>
</head>
<body>
<div id="app">
    点击次数:{{counter}}
    <button @click="handleAdd()">+1</button>
    <button @click="handleAdd(10)">+10</button>
    <!--Vue提供的特殊变量$event,用于访问原生DOM事件-->
    <a href="https://www.123.com" @click="handleClick('禁止打开',$event)">连接</a>
</div>
<script src="../vue.min.js"></script>

<script type="application/javascript">
    var app=new Vue({
        el:"#app",
        data:{
            counter:0
        },
        methods:{
            handleAdd:function (count) {
                count = count || 1;
                this.counter+=count;
            },
            handleClick:function (message, event) {
                event.preventDefault();//阻止默认动作
                window.alert(message);
            }
        }
    })
</script>
</body>
</html>
View Code

 

5.4.2 修饰符

    在上例使用的event.preventDefault()也可以使用Vue事件的修饰符来实现。在@绑定事件后加小圆点"."再跟一个后缀。修饰符可以连续调用。

    1. .stop:停止事件冒泡
    2. .prevent:阻止默认动作
    3. .capture
    4. .self:事件在元素本身
    5. .once:只触发一次

     键盘修饰符,只有当按某个键时调用该方法,@keyCode.n="func"

5.5 实战:利用计算属性、指令等知识开发购物车

  列表的splice方法:splice(index,howmany,item1,.....,itemX)方法向/从数组中添加/删除项目,然后返回被删除的项目。

index:必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。

howmany:必需。要删除的项目数量。如果设置为 0,则不会删除项目。

item1, ..., itemX:可选。向数组添加的新项目。

  index.html

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>购物车示例</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app" v-cloak>
    <template v-if="list.length">
        <table>
            <thead>
            <tr>
                <ht></ht>
                <ht>商品名称</ht>
                <ht>商品单价</ht>
                <ht>购买数量</ht>
                <ht>操作</ht>
            </tr>
            </thead>
            <tbody>
            <tr v-for="(item,index) in list">
                <td>{{index+1}}</td>
                <td>{{item.name}}</td>
                <td>{{item.price}}</td>
                <td>
                    <button v-on:click="handleReduce(index)"
                            v-bind:disabled="item.count === 1">-
                    </button>
                    {{item.count}}
                    <button v-on:click="handleAdd(index)">+</button>
                </td>
                <td>
                    <button v-on:click="handleRemove(index)">移除</button>
                </td>
            </tr>
            </tbody>
        </table>
        <div>总价:¥{{totalPrice}}</div>
    </template>
    <div v-else>购物车为空</div>
</div>
<script src="vue.min.js"></script>
<script src="index.js"></script>
</body>
</html>
View Code

  index.js

var app = new Vue({
    el: "#app",
    data: {
        list: [
            {id: 1, name: "iphone 7", price: 6188, count: 1},
            {id: 2, name: "iPad Pro", price: 5888, count: 1},
            {id: 3, name: "MacBook Pro", price: 21888, count: 1},
        ]
    },
    computed: {
        totalPrice: function () {
            var total = 0;
            for (var i = 0; i < this.list.length; i++) {
                var item = this.list[i];
                total += item.price * item.count;
            }
            return total.toString().replace(/\B(?=(\d{3})+$)/g, ',');
        }
    },
    methods: {
        handleReduce: function (index) {
            //这里再次判断,避免事件绑定在非button元素上,如div,span等,非button元素disabled特性不生效
            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)
        },
    }
})
View Code

  index.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;
}
View Code

posted @ 2019-04-28 13:24  丫丫625202  阅读(110)  评论(0编辑  收藏  举报