Vue-指令

193 阅读5分钟
指令很多,平时有些不怎么用,关键时刻掉链子,补补知识广广面。
Vue 2.6版本

v-text

只解析成文本,'<strong>很壮</strong>' 还是输出'<strong>很壮</strong>'。
防止xxs注入,{{}} 语法也会转义。
     <p v-text="vText"></p>
     结果:<strong>很壮</strong>
     data: () => {
            return {
                vText: "<strong>很壮</strong>"
            }
    }

v-html

在当前元素innerHtml中插入HTML(Vue不进行编译),要注意xxs注入攻击。
应用场景:如富文本内容展示
注意:<style scoped>中的样式不会再v-html 生效。
     <p v-html="vHtml"></p>
     结果:红字蓝色
      data: () => {
            return {
                vHtml: '<p>' +
                    '<span class="text-red">红字</span>' +
                    '<span class="text-blue">蓝色</span>' +
                    '</p>'
            }
        }

v-show

vue会进行编译,根据表达式的真假值,来切换元素的display Css 属性值。
触发过渡场景
应用场景:切换频繁的元素
注意:不支持 <tempalte> 元素,也不支持 v-else, v-show 权限小于 v-if
       <template v-show="false">
                <p>我是内置模板中的内容</p>
       </template>
       结果:不会生效,内容会继续展示
       

v-if

根据表达式的真假值渲染元素,切换时它的数据绑定/以及组件被销毁进行重建。
触发过渡场景。
应用场景:切换不频繁的元素
注意:v-if 与 v-for 同时使用的时候v-for 优先级更高
        <tm v-show="isShow"></tm>
        <button @click="isShow =!isShow">v-if切换</button>
        // 结果:组件值累加后,isShow false - true 转换,不会对组件的内置数据进行重置。
         let component = Vue.component("tm", {
                template: '<div>' +
                                '<div>我是组件生产的模板</div>' +
                                '<div>累加数:{{count}}</div>' +
                                '<div>' +
                                '<button @click="count+=1">数量增加</button>' +
                                '</div>' +
                              '</div>',
                data: () => {
                                return {
                                    count: 0
                                }
                            }
                    });

v-else

在使用此元素之前必须有'v-if','v-else'
       <div v-if="false">
            v-if
        </div>
        <div v-else>
            v-else
        </div>
        // if 条件为false 选择 else 内容

v-else-if

v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:
       <div v-if="type === 'A'">
            A
        </div>
        <div v-else-if="type === 'B'">
            B
        </div>
        <div v-else-if="type === 'C'">
            C
        </div>
        <div v-else>
            No...
        </div>

v-for

遍历元素,可遍历 String,Number,Object,Array,Iterable
v-for 优先级高于 v-if
        <!--Object 使用Object.keys() 转化成数组 -->
        <div v-for="(val,key,index) in forObject">
            对象键:{{key}},对象值:{{val}},index:{{index}}
        </div>
        <!--String Array 遍历方法相同 new Array(val.length)-->
        <div v-for="(item,index) in forArray">
            数组值:{{item}},数组下标:{{index}}
        </div>
        <div v-for="(item,index) in forString">
            数组值:{{item}},数组下标:{{index}}
        </div>
        <!--Number 从1开始 new Array(number)-->
        <div v-for="(item,index) in forNumber">
            当前值:{{item}},下标:{{index}}
        </div>
        <!--Iterable 迭代器-->
        <div v-for="(item,index) in forIterable">
            当前值:{{item[0]}},下标:{{index}}
        </div>

v-on

简写形式 '@'。
应用场景:监听原生DOM事件,用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
        <!--动态事件 设定,event 可以用变量控制 -->
        <button @[event]="doThis"></button>
        <!-- 内联语句 -->
        <button @click="doThat('hello', $event)"></button>
        <!--对象写法,不能使用简写-->
        <button v-on="{mousedown:doThis,mouseup:doThat}"></button>
        <!--组件 事件传递-->
        <my-component @c-m="doThis" ></my-component>
此段先不介绍修饰指令,另开一章介绍所有修饰指令

v-bind

动态地绑定一个或多个特性,或一个组件 prop 到表达式。
绑定class,style的时候支持数组,对象。
没有参数时,可以绑定到一个包含键值对的对象。注意此时 class 和 style 绑定不支持数组和对象。
        <!-- 动态特性名 (2.6.0+) -->
        <button v-bind:[key]="value"></button>
        <!--自定义参数-->
        <div :data-name="event"></div>
        <!-- style 绑定 -->
        <div :style="{ fontSize: size + 'px' }"></div>
        <div :style="[styleObjectA, styleObjectB]"></div>
        <!--class 绑定-->
        <div :class="{classObjectA,classObjectB}"></div>
        <!-- 组件传值 -->
        <my-component :data-name="event" v-model="event"></my-component>

v-model

在表单控件或者组件上创建双向绑定。对应的是input:value,
组件上绑定 会生成一个侦听函数 'input' ,props 中直接使用value 字段接收。
            <h3>input text</h3>
            <input type="text" v-model="message">
            <p>Message is:{{message}}</p>
            <h3>多行文本</h3>
            <textarea v-model="textareaMessage" placeholder="add multiple lines"></textarea>
             // 文本输入框 使用的是input 监听事件,输入内容就更新值
             //  on: {
                    input: function($event) {
                        if ($event.target.composing) {
                            return
                        }
                        _vm.message = $event.target.value
                    }
                }
            <h3>复选框</h3>
            <input type="checkbox" id="checkbox" v-model="checked">
            <label for="checkbox">{{ checked }}</label>
            <h3>多选复选框</h3>
            <input type="checkbox" value="pear" id="pear" v-model="checkedFruits">
            <label for="pear">pear</label>
            <input type="checkbox" value="banana" id="banana" v-model="checkedFruits">
            <label for="banana">banana</label>
            <input type="checkbox" value="apple" id="apple" v-model="checkedFruits">
            <label for="apple">apple</label>
            <p>选中的水果:{{checkedFruits}}</p>
            // 复选框中使用的是change 监听事件,给予model 传入的值来做选择,传入的是Array,那么会以数组的形式走,
            // 没有初始化value,接受的是 'null'。 传入的其他类型都是 走 true false 
             on: {
                    change: function($event) {
                        var ?a = _vm.checkedFruits,
                        ?el = $event.target,
                        ?c = ?el.checked ? true : false
                        if (Array.isArray(?a)) {
                            var ?v = null,
                            ?i = _vm._i(?a, ?v)
                            if (?el.checked) {
                            ?i < 0 && (_vm.checkedFruits = ?a.concat([?v]))
                            } else {
                            ?i > -1 &&
                            (_vm.checkedFruits = ?a
                                .slice(0, ?i)
                                .concat(?a.slice(?i + 1)))
                        }
                    } else {
                        _vm.checkedFruits = ?c
                    }
                }
            }
            <h3>单选框</h3>
            <input type="radio" id="one" value="One" v-model="picked">
            <label for="one">One</label>
            <br>
            <input type="radio" id="two" value="Two" v-model="picked">
            <label for="two">Two</label>
            <br>
            <p>picked:{{picked}}</p>
             // 单选框中使用的是change 监听事件,给予model 传入的值来做选择,radio未初始化值,即为null,不是字符串null
             on: {
                change: function($event) {
                    _vm.picked = null
                }
            }
            <h3>下拉选择</h3>
            <select name="" id="" multiple v-model="selected">
                <option value="one">one</option>
                <option value="two">two</option>
                <option value="three">three</option>
            </select>
            <p>selected:{{selected}}</p>
            // 下拉选择使用的change 监听事件,使用了multiple 那么v-model值必须 为数组。
            on: {
            change: function($event) {
              var ?selectedVal = Array.prototype.filter
                .call($event.target.options, function(o) {
                  return o.selected
                })
                .map(function(o) {
                  var val = "_value" in o ? o._value : o.value
                  return val
                })
              _vm.selected = $event.target.multiple
                ? ?selectedVal
                : ?selectedVal[0]
            }
          }

v-slot

v-slot代替了之前slot,以前的就不去了解了,使用现在最新的。
# 简写可以代替 v-slot 。
可以使用动态写法。
注意:v-slot只能在'<template>'标签或组件上使用。
组件模板
    <div>
        <header>
            // slotObj 可以在父作用域 中 用 v-slot:header="object"
            // 此时object 是一个对象 需要用 object.slotObj 来获取传递上来的对象
            <slot name="header" :slotObj="slotObj"></slot>
        </header>
        <main>
            <slot></slot>
        </main>
        <footer>
            <slot name="footer"></slot>
        </footer>
    </div>
简单例子
        <base-layout>
            <!--报错: v-slot can only be used on components or <template>.-->
            <!--            <h1 v-slot:header>-->
            <!--                Here might be a page title-->
            <!--            </h1>-->
            <template v-slot:header="slot">
                // 这里就接受到了 组件内部 返回的对象
                <h1>Here might be a page title{{slot.slotObj.message}}</h1>
            </template>
            <template v-slot:default>
                <p>A paragraph for the main content.</p>
                <p>And another one.</p>
            </template>
            <template v-slot:footer>
                <p>Here's some contact info</p>
            </template>
        </base-layout>

v-slot详细跳转

v-pre

被标记的dom 不会进行编译。

v-cloak

这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
解决闪烁问题。

v-once

内容只渲染一次