vue的指令

1.vue 的指令

1.1 指令的概念与分类

指令 是 vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构

vue 中的指令按照不同的用途可以分为:

  • 内容渲染指令
  • 属性绑定指令
  • 事件绑定指令
  • 双向绑定指令
  • 条件渲染指令
  • 列表渲染指令

1.2 内容渲染指令

内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。

  • v-text

    缺点:会覆盖元素内部原有的内容

    <body>
        <div id="app"> 
            <p v-text="username"></p>
            <p v-text="gender">性别</p>
        </div>
        <!-- 1.导入 vue 的库文件 -->
        <script src="./lib/vue.js"></script>
        <!-- 2.创建 vue 实例对象 -->
        <script>
            const vm = new Vue({
                el: '#app',
                data: {
                    username: '李四',
                    gender: '男'
                }
            })
        </script>
    </body>
    
  • {{ }}:插值表达式,将对应的值渲染到元素的内容节点

    <div id="app"> 
        <p>姓名:{{ username }}</p>
        <p>性别: {{ gender }}</p>
    </div>
    
  • v-html

    把包含 HTML 标签的字符串渲染为页面的 HTML 元素

    <body>
        <div id="app"> 
            <p v-html="info"></p>
        </div>
        <!-- 1.导入 vue 的库文件 -->
        <script src="./lib/vue.js"></script>
        <!-- 2.创建 vue 实例对象 -->
        <script>
            const vm = new Vue({
                el: '#app',
                data: {
                    info: '<h4 style="color:red; font-weight:bold">Hello Vue !</h4>'
                }
            })
        </script>
    </body
    

1.3 属性绑定指令

  • 插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中!

  • v-bind 可以为元素的属性动态绑定属性值

  • vue 规定 v-bind: 指令可以简写:

实例代码:

<body>
    <div id="app"> 
        <input type="text" name="" id="" v-bind:placeholder="tips">
        <img v-bind:src="photo" alt="" style="width: 30px;">
    </div>
    <!-- 1.导入 vue 的库文件 -->
    <script src="./lib/vue.js"></script>
    <!-- 2.创建 vue 实例对象 -->
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                tips: '请输入用户名',
                photo: 'https://cn.vuejs.org/images/logo.svg'
            }
        })
    </script>
</body>

使用 Javascript 表达式:

<body>
    <div id="app">
        <div>1 + 2 = {{ 1 + 2}}</div>
        <div>{{ tips  }} 反转 :{{ tips.split('').reverse().join('')}}</div>
        <div :title="'box' + index">这是一个 div</div>
    </div>
    <!-- 1.导入 vue 的库文件 -->
    <script src="./lib/vue.js"></script>
    <!-- 2.创建 vue 实例对象 -->
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                tips: '请输入用户名',
                index: 3
            }
        })
    </script>
</body>

1.4 事件绑定指令

1.4.1 如何绑定

vue 提供了 v-on 事件绑定指令,用来辅助程序员为 DOM 元素绑定事件监听。

  • v-on: 事件类型="事件处理函数"

  • 触发事件时,this === vm

  • 在绑定事件处理函数时,可以使用 () 传递参数

  • v-on: 可以简写为 @,如@click="xxx"

    案例代码:

<body>
    <div id="app"> 
        <p>count : {{ count }}</p>
        <button v-on:click="add(2)"> + 2 </button>
        <button v-on:click="sub"> - 1 </button>
    </div>

    <!-- 1.导入 vue 的库文件 -->
    <script src="./lib/vue.js"></script>
    <!-- 2.创建 vue 实例对象 -->
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                count: 5
            },
            // methods 定义事件的处理函数
            methods: {
                add( n ) {
                    //  this === vm
                    this.count += n 
                },
                sub() {
                    this.count -- 
                }
            }
        })
    </script>
</body>

1.4.2 事件对象

  • vue 提供内置变量$event,是原生的 DOM 的事件对象
  • e.target 指向触发事件的 DOM 对象
<body>
    <div id="app"> 
        <!-- 偶数背景颜色变红 -->
        <p>count : {{ count }}</p>
        <button v-on:click="add(1 , $event)"> + N </button>
    </div>

    <!-- 1.导入 vue 的库文件 -->
    <script src="./lib/vue.js"></script>
    <!-- 2.创建 vue 实例对象 -->
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                count: 5
            },
            // methods 定义事件的处理函数
            methods: {
                add( n ,e ) {
                    //  this === vm
                    this.count += n 
                    if(this.count % 2 === 0){
                        e.target.style.backgroundColor = 'red'
                    }else{
                        e.target.style.backgroundColor = ''
                    }
                }
            }
        })
    </script>
</body>

1.4.3 事件修饰符

  • 取消事件的默认行为.prevent

    原生: e.preventDefault()

    <div id="app"> 
        <a href="http://www.baidu.com" @click.prevent="show">跳转到百度首页</a>
    </div>
    
  • 阻止时事件冒泡.stop

    原生: e.stopPropagation()

    如果子元素和父元素同时绑定 click 事件,那么点击子元素,会先触发子元素的点击事件然后再往外冒泡,触发父元素的点击事件。

  • 以捕获模式触发当前的事件处理函数:.Capture

  • 绑定的事件只能触发一次:.once

  • 只有在 event.target 是当前元素自身时触发事件处理函数:.selt

1.4.4按键修饰符

在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关的事件添加按键修饰符

  • <input type="text" @keyup.esc="clearInput">

    keyEsc 时调用 clearInput

  • <input type="text" @keyup.enter="submit">

    keyEnter 时调用 submit

    例子:

<body>
    <div id="app"> 
        <input type="text" @keyup.esc="clearInput">
    </div>
    <!-- 1.导入 vue 的库文件 -->
    <script src="./lib/vue.js"></script>
    <!-- 2.创建 vue 实例对象 -->
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                count: 5
            },
            // methods 定义事件的处理函数
            methods: {
                clearInput(e) {
                    console.log('触发了 clearInput')
                    e.target.value = ''
                }
            }
        })
    </script>
</body>

1.5 双向绑定指令

1.5.1 基本使用

vue 提供 v-model 双向数据绑定指令,用来辅助开发在不操作 DOM 的前提下,快速获取表单的数据

  • input文本框中的内容与 v-model 指令绑定的数据一致
  • 当操作 input 文本框内容 v-model 指令绑定的数据也会一起改变
  • v-model 能和 input 输入框(type=radio,checkbox,xxx),textarea,select 一起使用
<body>
    <div id="app">
        <div id="app">
        <p>用户的名字是:{{ username }} </p>
        <input type="text" v-model="username" >
        <hr>
        <input type="text" :value="username" >
        <hr>
        <select v-model="city">
            <option value="">请选择城市</option>
            <option value="1">北京</option>
            <option value="2">上海</option>
            <option value="3">广州</option>
        </select>
        <!-- 没有意义 -->
        <div v-model="username"></div>
    </div>
    
    <script src="./lib/vue.js"></script>
    <script>
        // 创建 vue 实例对象
        const vm = new Vue({
            el: '#app',
            data: {
                username: 'ZhangSan'
            }
        })
    </script>
</body>

1.5.2 v-model 指令的修饰符

为了方便对用户输入的内容进行处理

修饰符作用实例
.number自动把输入值转为Number类型<input type="text" v-model.number="n1">
.trim去掉首尾空白字符<input type="text" v-model.trim="username">
.lazychange时而非input时更新<input type="text" v-model.lazy="username">
  • .trim只会取出首端和末尾的空格,中间的不会取出
  • .lazy 之后在最后输入框失去焦点时同步最后一次数据,中间的变化不会实时同步
<body>
    <!--  希望 vue 能控制下面的这个 div 帮我们把数据填充到 div 内部 -->
    <div id="app">
        <input type="text" v-model.number="n1"> + <input type="text" v-model.number="n2"> = <span>{{ n1 + n2 }} </span>
        <hr>
        <input type="text" v-model.trim="username">
        <button @click="showName"> 获取用户名 </button>
        <hr>
        <input type="text" v-model.lazy="username">
    </div>

    <script src="./lib/vue.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                n1: 1,
                n2: 2,
                username: 'zhangsan'
            },
            methods: {
                showName() {
                    console.log(`用户名是:"${this.username}"`)
                }
            }
        })
    </script>
</body>

1.6 条件渲染指令

1.6.1 v-if 和 v-show

条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏

v-if v-show

  • v-if 值为true显示,值为false隐藏,隐藏:直接 移除DOM结构
  • v-show 值为true显示,值为false隐藏,隐藏:给 DOM 的 dispaly 设置为 none
  • 如果要频繁的切换元素的显示状态v-show性能更好,不用每次都动态添加删除元素
  • 如果初始状态为 false ,并且之后显示的状态可能性较小,使用 v-if更好

1.6.2v-else-if 和 v-else

v-else-if必须配合 v-if 使用,否则不被识别

<div v-if="type === 'A' ">优秀</div>
<div v-else-if="type === 'B' ">良好</div>
<div v-else-if="type === 'C' ">一般</div>
<div v-else="type === 'D' "></div>

1.7 列表渲染条件

vue 提供了 v-for 列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。v-for 指令需要使用 item in items 形式的特殊语法。

  • items 是待循环的数组
  • item 是被循环的每一项

v-for 还支持一个可选的第二个参数,即当前项的索引。语法格式:

(item,index) in items

item 和 index 都是形参

<div id="app">
    <table class="table table-border table-hover table-striped">
        <thead>
            <th>索引</th>
            <th>ID</th>
            <th>姓名</th>
        </thead>
        <tbody>
            <tr v-for="(item,index) in list">
                <td>{{ index }} </td>
                <td>{{ item.id }} </td>
                <td>{{ item.name }} </td>
            </tr>
        </tbody>
    </table>
</div>
  • 官方建议:只要用到了 v-for 指令,那么一定要绑定一个 :key 属性
  • 最好将 id 作为 key 的值
  • 对 key 的值得类型,是有要求的,字符串或者数值类型
  • key 值不允许重复,否则报错 Duplicate keys detected
  • 使用 index 的值当做 key 的值没有任何意义,index 的值不具有唯一性

1.7 品牌列表案例源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">  
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div style="width: 30%;position: relative;margin: 20px;">
            <form @submit.prevent="add" class="bs-example bs-example-form" role="form" style="width: 80%;">
                <div class="input-group">
                    <span class="input-group-addon">品牌名称</span>
                    <input type="text" class="form-control" placeholder="请输入品牌名称" v-model.trim="brand">
                    
                </div>
                <button type="submit" class="btn btn-success" style="position: absolute;right: 0;top: 0;">添加</button>
            </form>
        </div>
        <div style="width: 80%;border-top: 1px solid #cfcfcf;margin-left: 20px;">
            <table class="table table-bordered table-hover table-striped">
                <thead>
                    <th>#</th>
                    <th>品牌名称</th>
                    <th>状态</th>
                    <th>创建时间</th>
                    <th>操作</th>
                </thead>
                <tbody>
                    <tr v-for="item in list" :key="item.id">
                        <td>{{ item.id }} </td>
                        <td>{{ item.name }} </td>
                        <td>
                            <div class="checkbox">
                                <label>
                                    <!-- v-model 内部会判断属性 text,checkbox,radio 最后确定是 value,checked... -->
                                    <input type="checkbox"  v-model="item.status">
                                    <span v-if="item.status === false">已禁用</span> 
                                    <span v-else>已启用</span> 
                                </label>
                            </div>
                        </td>
                        <td>{{ item.time}} </td>
                        <td>
                            <span @click="remove(item.id)" style="cursor: pointer;">删除</span> 
                        </td>

                    </tr>
                </tbody>
            </table>
        </div>
        
    </div>

    <script src="./lib/vue.js"></script>
    <script>
        // 创建 vue 实例对象
        const vm = new Vue({
            el: '#app',

            data: {
                list: [
                    { id: 1, name: '宝马',status: true,time: new Date()},
                    { id: 2, name: '奔驰',status: false,time: new Date()},
                    { id: 3, name: '奥迪',status: true,time: new Date()},
                ],
                brand: '',
                // 下一个可用的 id
                nextId: 4
            },

            methods: {
                // 点击链接删除
                remove(id) {
                    console.log(id)
                    this.list = this.list.filter(item => item.id !== id)
                },
                add(){
                    console.log(this.brand)
                    if(this.brand === ''){
                        return window.alert('必须填写品牌名称!!!')
                    }
                    let obj = {
                        id: this.nextId,
                        name: this.brand,
                        status: true,
                        time: new Date()
                    }
                    this.list.push(obj)
                    this.brand = ''
                    this.nextId ++
                }
            }
        })
    </script>
</body>
</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值