vue中的指令

Vue中的指令

指令 (Directives) 是带有 v- 前缀的特殊属性,通过指令可以更方便的展示数据,下面列出一些常用的

  • v-once

    使用该指令表示只渲染一次,view中展示数据不会随着model的变化而变化。

  • v-html

    通过该指令可以将html标签解析并展示到页面中。

  • v-text

    作用跟mustache类似,通常是接收一个字符串类型,区别是这里不能想mustache那些进行简单的运算

  • v-pre

    会将{{}}这些大括号内容全部展示出来,而不是进行解析

示例代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>插值表达式基本使用</title>
</head>
<body>
<div id="app">
    <div v-once>{{message}}</div>

<!-- 这种写法会将原始的button标签展示-->
    <div>{{button}}</div>
<!-- 使用v-html会让浏览器解析html标签-->
    <div v-html="button"></div>

<!-- 只显示好好学习-->
    <div v-text="message">天天向上</div>
<!--会显示好好学习 天天向上-->
    <div>{{message}} 天天向上</div>

<!--会显示{{message}}-->
    <div v-pre>{{message}}</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: '好好学习',
            button:'<button>登录</button>'
        }
    })
</script>
</html>

v-bind

v-bind命令可以实现动态绑定,即可以动态的将图片的地址,链接的地址显示在页面中。以图片为例,实际开发中,图片的地址通常是从后台传到前台的,因此img标签中的src需要把后台传过来的地址显示,此时可以使用v-bind命令。

v-bind语法:

v-bind:src

可以简写成下面方式,即v-bind可以简写为:

:src

这里的myImage和monkey1024假设是从后台获取,然后展示到页面中,这里可以使用v-bind命令展示出来。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-bind基本使用</title>
</head>
<body>
<div id="app">
    <img v-bind:src="myImage">
    <a v-bind:href="monkey1024">小猴子1024</a>
<br>
<!--简写方式-->
    <img :src="myImage">
    <a :href="monkey1024">小猴子1024</a>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            myImage:'../images/basketball.jpg',
            monkey1024:'http://www.monkey1024.com/'
        }
    })
</script>
</html>

v-bind绑定style,可以实现一些动态的css效果

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-bind绑定style</title>
</head>
<body>
<div id="app">
    <div v-bind:style="{color: myColor}">好好学习</div>
    <button v-on:click="btn">按钮</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            myColor: 'red'
        },
        methods: {
            btn: function () {
                this.myColor = 'black'
            }
        }
    })
</script>
</html>

计算属性computed

对于有些数据,我们需要进行一些计算,然后再将结果展示到页面中,此时可以利用计算属性computed来完成这个操作。例如下面示例,需要将地址拼接展示,如果按照以前的写法的话,代码显得比较多了。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>计算属性</title>
</head>
<body>
<div id="app">
<!--这种方式需要写多个,比较麻烦-->
    <div>{{province}}{{city}}{{street}}</div>
<!--通过自己定义方法来获取-->
    <div>{{getAddress()}}</div>
<!--使用计算属性-->
    <div>{{address}}</div>

</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            province: '河北',
            city: '石家庄',
            street: 'xx街xx号'
        },
        computed: {
            //计算出地址,虽然是一个函数,但是名字通常是名词。
            address: function () {
                return this.province + this.city + this.street
            }
        },
        methods: {
            //自己定义方法
            getAddress: function () {
                return this.province + this.city + this.street
            }
        }
    })
</script>
</html>

上面我们通过计算属性直接获取了地址,需要注意的是虽然我们是写了一个函数,但是前面的名字我们通常是使用名词命名,即属性的形式。实际上这里面的每个计算属性都有一个set和get方法。

computed和methods的区别

上面的示例中,我们通过methods也可以实现计算的需求,那么computed和methods有什么区别呢?区别就是computed会进行缓存,多次使用的话只会计算一次,methods会计算多次。浏览器打开下面页面之后,通过控制台可以看到computed中的内容只会打印一次,而methods中的内容会打印多次

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>computed和methods的区别</title>
</head>
<body>
<div id="app">

<!--通过自己定义方法来获取-->
    <div>{{getAddress()}}</div>
    <div>{{getAddress()}}</div>
    <div>{{getAddress()}}</div>
<!--使用计算属性-->
    <div>{{address}}</div>
    <div>{{address}}</div>
    <div>{{address}}</div>

</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            province: '河北',
            city: '石家庄',
            street: 'xx街xx号'
        },
        computed: {
            //计算出地址,虽然是一个函数,但是名字通常是名词。
            address: function () {
                console.log("computed")
                return this.province + this.city + this.street
            }
        },
        methods: {
            //自己定义方法
            getAddress: function () {
                console.log("methods")
                return this.province + this.city + this.street
            }
        }
    })
</script>
</html>

利用计算属性统计出库存总数,示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>计算库存</title>
</head>
<body>
<div id="app">
    库存总数:<div>{{total}}</div>

</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            phones:[
                {id:1001,name:'华为手机',sum:10},
                {id:1002,name:'小米手机',sum:20},
                {id:1003,name:'一加手机',sum:25}
            ]
        },
        computed: {
            total: function () {
                let count = 0;
                for (let i in this.phones) {
                    count += this.phones[i].sum
                }
                return count
            }
        }
    })
</script>
</html>

事件监听

v-on指令可以完成事件的监听,比如点击事件等。v-on语法:

v-on:click="add"

简易写法:

@click="add"

下面示例演示了点击按钮添加或者减少count的值实现一个简易计数器。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-on基本使用</title>
</head>
<body>
<div id="app">
    <div>{{count}}</div>

    <button v-on:click="add">+</button>
    <button v-on:click="subtract">-</button>

<!--语法糖-->
    <button @click="add">+</button>
    <button @click="subtract">-</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            count: 0
        },
        methods:{
            add() {
                this.count++
            },
            subtract() {
                this.count--
            }
        }
    })
</script>
</html>

在使用v-on的时候如果方法没有参数,则方法后面的括号可以省略。当方法有参数且在v-on后面省略大括号的时候,会将当前的event对象传入到方法中。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-on参数</title>
</head>
<body>
<div id="app">

<!--btn1声明的时候需要参数,倘若没有传入的话,会将当前的event对象传入-->
    <!--<button @click="btn1(1024)">按钮1</button>-->
    <button @click="btn1">按钮1</button>

<!--手动传入当前event对象-->
    <button @click="btn2(name, $event)">按钮2</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        methods: {
            btn1(param) {
                console.log('btn1', param);
            },
            btn2(name, param) {
                console.log('btn2', name, param);
            }
        }
    })
</script>
</html>

我们可以通过v-on修饰符监听一些其他的操作,例如监听某个按键的弹起。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-on修饰符</title>
</head>
<body>
<div id="app">

    <!--监听某个按键的弹起-->
    <input type="text" @keyup.enter="keyUp">

    <!--只调用一次btn1-->
    <button @click.once="btn1">按钮1</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        methods: {
            keyUp() {
                console.log('keyUp')
            },
            btn1() {
                console.log('btn1')
            }
        }
    })
</script>
</html>

v-if

我们可以通过v-if进行一些判断操作,倘若v-if判断为false的时候,对应的元素和子元素是不会展示的,即不会生成该DOM元素。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-if判断</title>
</head>
<body>
<div id="app">
    <div v-if="score>=90">优秀</div>
    <div v-else-if="score>=80">良好</div>
    <div v-else-if="score>=60">及格</div>
    <div v-else>不及格</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            score:95
        }
    })
</script>
</html>

使用v-if切换展示内容,这种切换会进行一个复用,即当勾选上唱歌之后,点击切换性别会发现篮球是勾选上的,我们可以在input中使用填写不同的key来解决该问题。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-if应用</title>
</head>
<body>
<div id="app">
    <div v-if="sex">
        <h2>女生填写</h2>
        <div>爱好:</div>
        唱歌:<input type="checkbox" name="hobby" key="female">
        跳舞:<input type="checkbox" name="hobby" key="female">
    </div>
    <div v-else>
        <h2>男生填写</h2>
        <div>爱好:</div>
        篮球:<input type="checkbox" name="hobby" key="male">
        足球:<input type="checkbox" name="hobby" key="male">
    </div>

    <button @click="change">切换性别</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            sex: true
        },
        methods: {
            change(){
                this.sex = !this.sex;
            }
        }
    })
</script>
</html>

v-show

v-show可以控制内容的展示,通过v-show隐藏某个内容时,在页面元素中可以看到被隐藏的内容,v-show会将元素的display属性设置为none来隐藏内容,而v-if根本就不会生成这个DOM对象。

在显示和隐藏需要频繁切换的话,使用v-show,如果只会进行一次切换,使用v-if。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-show</title>
</head>
<body>
<div id="app">
    <div v-if="flag">好好学习</div>
    <div v-show="flag">天天向上</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            flag: false
        }
    })
</script>
</html>

v-for遍历

遍历数组

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-for遍历数组</title>
</head>
<body>
<div id="app">
    <!--没有使用下标值-->
    <ul>
        <li v-for="item in hobby">{{item}}</li>
    </ul>

    <!--使用下标值-->
    <ul>
        <li v-for="(item, index) in hobby">
            {{index+1}}.{{item}}
        </li>
    </ul>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            hobby: ['篮球','足球','排球']
        }
    })
</script>
</html>

遍历对象

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-for遍历数组</title>
</head>
<body>
<div id="app">
    <!--获取value-->
    <ul>
        <li v-for="item in student">{{item}}</li>
    </ul>
        <!--获取key和value -->
    <ul>
        <li v-for="(value, key) in student">{{value}}-{{key}}</li>
    </ul>
        <!--获取key和value和index -->
    <ul>
        <li v-for="(value, key, index) in student">{{value}}-{{key}}-{{index}}</li>
    </ul>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            student: {
                name: 'jack',
                age: 18
            }
        }
    })
</script>
</html>

指定v-for中的key

在v-for中建议指定key,key的值跟数据一一对应,可以使用id数据主键之类的,最好不要使用index做为key的值,index会随着数据的变化而变化。如下代码没有指定key的值,在页面勾选中足球之后,再点击添加,会发现勾选的是添加之后的玻璃球。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>v-for遍历数组</title>
</head>
<body>
<div id="app">
    <!--指定key值,这里没有id,我们就将key指定为item-->
    <ul>
        <li v-for="(item, index) in hobby" :key="item">
            <input type="checkbox">{{index+1}}.{{item}}
        </li>
    </ul>

    <button @click="add">添加</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            hobby: ['篮球','足球','排球']
        },
        methods: {
            add: function () {
                //篮球后面添加玻璃球
                this.hobby.splice(1,0,'玻璃球')
            }
        }
    })
</script>
</html>

v-for中key的作用

上面在v-for中指定key另外还有一个作用就是可以提高添加的效率,这里涉及到了diff算法,指定key之后是可以。在不指定key的时候,我们向数组里面添加元素,vue会将添加位置后面li的内容进行修改。上面代码示例中,我们点击了足球,对应的是li2,当执行添加操作之后可以发现li2的内容变成了玻璃球,这就是为什么页面中选中的是玻璃球了。

使用key之后,key会跟item内容一一对应,这样在进行插入的时候,vue不会让后面li的内容进行修改,这样提高了效率,所以key的作用是高效的更新虚拟dom。加上可以之后就不会将玻璃球放到key是足球的里面,这样就可以显示正常的效果了。

数组中响应式的方法

并不是所有数组中的方法都是响应式的,下面这些是响应式:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

下面这些方法不是响应式,其不会改变原始数组,而总是返回一个新数组。

  • filter()
  • concat()
  • slice()

除了这些之外,通过下标修改数组的元素或者修改数组长度的时候是不能检测出数组的变化的。

Category: vue