vue指令
Vue常用指令
v-text
该指令是用来更新元素的标签体内容的
<span v-text="msg"></span> 即: <span>{{ msg }}</span>
v-html
更新元素的innerHTML
使用该标签需要注意:
- 在网站上动态的渲染任意的HTML非常危险,会导致XSS攻击,只能在可信的内容上使用该指令,永远不要用在提交内容上使用
- v-html的内容会按照普通的HTML内容进行插入,不会作为vue模板进行编译
- 在单文件中,scoped的样式不会应用在v-html内部,因为那部分的HTML不会被vue的模板编译处理,可以额外定义一个<style>元素设置v-html内容
<div v-html="html"></div>
v-show
根据表达式运行的结果的真假来设定元素的display属性是block还是none
<div v-show="msg == 0"></div>
v-if
根据表达式的值的真假条件渲染元素,与v-show效果很相似,但是不同的是v-if是直接销毁元素或者重建元素以及它的数据绑定跟组件
注意:当和v-for一起使用时,v-for的优先级更高
<div v-if="msg == 0"></div>
v-else & v-else-if
v-else不需要表达式,必须跟v-if联用
<div v-if="Math.random() > 0.5">Now you see me</div> <div v-else>Now you don't</div>
v-else-if必须同v-if联用,最后一个判断可以使用v-else,效果同v-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>Not A/B/C</div>
v-for
根据可遍历的数据多次渲染元素或模板块
<!-- 基本的用法 --> <div v-for="item in items"> {{ item.text }} </div> <!-- item 为当前项,index 为索引 --> <p v-for="(item, index) in list">{{item}} -- {{index}}</p> <!-- item 为值,key 为键,index 为索引 --> <p v-for="(item, key, index) in obj">{{item}} -- {{key}}</p> <p v-for="item in 10">{{item}}</p>
特殊属性key
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by="$index" 。
- 在使用v-for的时候提供key属性能够提升性能
- 使用key后,Vue会基于key的变化重新排列元素顺序,且会移除key不存在的元素
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。这个特殊的属性相当于 Vue 1.x 的 track-by ,但它的工作方式类似于一个属性,所以你需要用 v-bind 来绑定动态值 (在这里使用简写):
<div v-for="item in items" :key="item.id"> </div>
filterBy筛选
在vue1.x的中,如果想要过滤v-for循环中的数据时,可以使用filterBy来进行,例如,想要筛选item中name属性里面含有hello的项,可以做如下书写
<div v-for="item in list filterBy 'hello' in name"></div>
如果item不是对象,我们筛选的是item本身,则可以不指定后面要筛选的项
<div v-for="item in list filterBy 'hello' "></div>
上面的过滤器虽然好用,但是在vue2.x中就已经没了,vue2.x将所有的系统过滤器都取消了,因此filterBy自然使用不了了,那么如何达到相同的筛选效果呢?我们其实可以通过computed在循环对象前先对要循环的对象进行处理,手动过滤出需要的项
自定义filterBy
<body> <input v-model="findInfo" /> <tr v-for="item in filterList"> <td>{{ item.id }}</td> <td>{{ item.name }}</td> </tr> <script> new Vue({ el: '#app', data: { list: [ {id: 1, name: '宝马', time: new Date()}, {id: 2, name: '奔驰', time: new Date()}, {id: 3, name: '凯迪拉克', time: new Date()}, ], findInfo: '', }, computed: { // 实现filterBy功能 filterList: function(){ let filterKey = this.findInfo; let list = this.list; if(filterKey === ""){ return list; } return list.filter(function(item){ return item.name.indexOf(filterKey) !== -1; }); } }, }); </script> </body>
在上面的代码中, findInfo 即相当于我们要筛选的条件 hello ,而要筛选的项 name 已经在computed中写死了,这样虽然没有原来的filterBy灵活,但是也足够使用了
v-on
绑定事件监听器,表达式可以是一个方法的名字或者一个内联语句。在普通元素上时,只能监听原生Dom事件。用在自定义的元素组件上时,也可以监听子组件触发的自定义事件。如果使用内联语句,可以访问一个$event属性: v-on:click="handle('ok, $event')"
修饰符
.stop
阻止冒泡,调用 event.stopPropagation().prevent
阻止默认事件,调用 event.preventDefault().capture
添加事件侦听器时使用事件捕获
模式.self
只当事件在该元素本身(比如不是子元素)触发时触发回调.once
事件只触发一次
简写
v-on还可以简写为@符,即 v-on:click="test" 等价于 @click="test"
<div @click="doSomething(“123”)"></div> <script> var vm = new Vue({ el: '#app', // methods属性用来给vue实例提供方法(事件) methods: { doSomething: function(str) { console.log(str); } } }) </script>
补充
按键修饰符:用来指定按下执行的键触发事件
<div v-on:keydown.enter="addData"></div> <!-- 还可以使用每个键指定的数字 --> <div v-on:keydown.13="addData"></div>
添加按键:vue只给我们定义了少量的按键数字对应字母,还有很多键需要我们自己定义,那么如何添加呢?
Vue.directive('on').keyCodes.f2 = 113; // vue1.x Vue.config.keyCodes.f2 = 113; // vue2.x
这样就可以使用F2键对应的英文f2了
v-bind
可以给html元素或者组件动态绑定一个或多个特性,如动态的绑定style和class
简写
可以使用 : 来简写,即 v-bind:class="active" 等价于 :class="active"
<!-- 1 --> <div v-bind:class="{ active: true }"></div> ===> <div class="active"></div> <!-- 2 --> <div :class="['active', 'text-danger']"></div> ===> <div class="active text-danger"></div> <!-- 3 --> <div v-bind:class="[{ active: true }, errorClass]"></div> ===> <div class="active text-danger"></div> --- style --- <!-- 1 --> <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> <!-- 2 将多个 样式对象 应用到一个元素上--> <div v-bind:style="[baseStyles, overridingStyles]"></div> --- script --- <script> // 2 创建 Vue 的实例对象 var vm = new Vue({ el: '#app', data: { activeColor: 'red', fontSize: 30, baseStyles: { color: 'red', 'font-size': '30px' }, overridingStyles: { color: 'green', } } }) </script>
补充
给a标签的href添加动态值
有的时候想给a标签的href添加上 http://127.0.0.1:8080/index/id ,这里面的id是一个动态值,是由data里面的数据加载而来的,那么很容易就会这样写 <a href="http://127.0.0.1:8080/index/id"></a> ,我们的本意是去数据中心找id然后加载到url后面,但是如果像上面那样写,会直接到数据中心找有没有 http://127.0.0.1:8080/index/id 这个变量,很显然并没有这个变量,那么肯定会报错,正确的写法应该如下
<a v-bind="{href: 'http://127.0.0.1:8080/index/' + id}"></a>
v-model
在表单控制或者组件上创建双向绑定
限制:只能在 <input> <select> <textarea> components 使用
修饰符
- lazy:取代input监听change事件
- number:输入字符串转为数字
- trim:输入收尾空格过滤
<!-- 输入 --> <input type="text" v-model="name" /> <!-- 显示 --> <span v-text="name"></span>
v-cloak
保持在元素上直到关联的实例结束编译。通常用来解决 {{ .... }} 闪烁问题
例如,在加载 <div>{{ name }}</div> 的时候,原意是加载name对应的值,如果这时候网速比较慢则会在浏览器页面上快速的显示 {{ name }} ,然后才会加载name所对应的值,这样会降低用户体验,那么使用什么方法可以避免呢?当然使用v-text可以,但是这里还要介绍一种方式
<style> [v-cloak]{display: none;} </style> <div id="app"> <span v-cloak>{{ name }}</span> </div> <script> new Vue({ el: "#app", data: { name: "hello", }, }); </script>
在上面的代码中,刚开始加载span时,会有一个v-cloak指令,而v-cloak在css样式中设置了display为none,所以刚开始的时候不会加载span,只带script中的name加载完后,v-cloak才会被移除,然后span显示,而此时{{ name }}已经被加载了,所以不再闪烁
v-pre
跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译
<span v-pre>{{ this will not be compiled }}</span>
自定义指令及应用
上面的指令都是Vue帮我们定义好了的,但是指令虽然比较多,仍旧难以满足我们的需求,如果我们需要自己定义指令应该怎么办呢?
自定义属性指令
<input v-color="color" /> /** * 参数一:自定义的属性名,不用加"v-" * 参数二:callback回调函数 */ Vue.directive('color', function(){ // this.vm 获取当前的vue对象 // this.expression 获取当前指令后面所带的参数名 // this.vm[this.expression] 在vue对象中拿到该属性对应的值 let color = this.vm[this.expression]; });
自定义元素指令
<my-red>搜索条件</my-red> Vue.elementDirective("my-red", { bind: function(){ // this.el指当前标签 this.el.style.color = 'red'; } });