Vue指令
- VUE指令:directive
1.都是按照v- xxx处理的,它是vue中规定给元素设置的自定义属性, v-开头,放在元素的行间属性,有着特殊意义的一些词;
2.当vue加载成功并进行处理的时候,会按照相关的规则解析和宣传视图,遇到对应的指令实现对应的功能
命令;
3.指令放在行间的属性值,当编译时,首先会去查找在vue的data中是否有这个属性,如果没有,就报错;
4.在使用指令时,会先找数据类型中的值,如果数据类型中没有,那么就去找data或methods中的属性名;
1.基础指令
- {{}}: 小胡子语法可以将data中数据放入其中
- v-model-般给表单元素设置的,实现表单元素和数据之间的相互绑定
1)先把数据绑定给表单元素,一般把数据赋值给表单元素的value、
2)监听表单元素的内容改变
3)内容改变后,会把对应的数据也改变
4)对应的数据改变,视图中所有用到数据的地方都会重新渲染
视图<=>数据
在vue框架中给表单元素设置value等属性是没有意义的。
- v-html/v-text:给非表单元素设置内容,v-html支持对于标签的自动识别,v-text 会把所有内容分都当做文本,传统的胡子语法,在vue没有 加载完成之前,会把{{xxx}}展示在页面中,当vue 加载完才会出现真正的内容,这样体验不好
- v-bind:给元素的内置属性动态绑定数据,例如:给img绑定动态的图片路径地址
可以简写成为:,也就是v-bind:src 等价于:src
- v-once:绑定的数据是一次性的, 后面不论数据怎么改变,视图也都不会重新渲染
- v-if:如果对应的值是TRUE,当前元素会在结构中显示,如果是FALSE,当前元素会在结构中移除(它控制的是组件的加载和卸载的操作=>DOM的增加和删除) ;还有对应的v-else-if /v-else等指令;
v-if: 控制元素的显示隐藏;如果不是布尔,会默认转成布尔;如果是false,直接删除了原有的元素;
v-else-if: v-if成立就不走这个,if条件不成立走这个
v-else: v-else-if不成立走这个,成立不走,if连写成立一个
- v-show:和v- if类似,只不过它是控制元素样式的显示隐藏(display的操作)
- v- if是控制组件存不存在,对于结果是FALSE,不存在的组件来说,视图渲染的时候无需渲染这部分内容;而v-show则不行,因为不管是显示还是隐藏,结构都在,所以视图渲染的时候这部分也要渲染;
- 在过于频繁的切换操作中,v-if明显要比v-show要低一些
- 通过设置布尔值来控制元素是否显示,如果是true,则显示,false,则隐藏;如果不是一个布尔值,那么会默认转布尔;通过设置元素的display属性来控制是否显示;
<body>
<div id="app">
<div v-text="x"></div>
<div v-html="x"></div>
<div v-show="1" r-yy="1">中国加油</div>
<div v-if="1===1">武汉加油</div>
<div v-else-if="3===3">天气真好</div>
<div v-else>北京加油</div>
<input type="text" v-model="a">
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 指令: v-开头,放在元素的行间属性,有着特殊意义的一些词;
// v-model:一般用于表单元素;将data中数据放在input框中,当input值发生改变,数据也会跟着发生改变;
// {{}}: 小胡子语法可以将data中数据放入元素中
// v-text: 可以将data中的文本放入元素中
// v-html:可以识别标签
// v-show :通过设置布尔值来控制元素是否显示,如果是true,则显示,false,则隐藏;如果不是一个布尔值,那么会默认转布尔;通过设置元素的display属性来控制是否显示;
// 以指令放在行间的属性值,当编译时,首先会去查找在vue的data中是否有这个属性,如果没有,就报错;
// v-if: 控制元素的显示隐藏;如果不是布尔,会默认转成布尔;如果是false,直接删除了原有的元素;
// v-else-if:
// v-else:
let vm = new Vue({
el:"#app",
data:{
a:1,
x:"<span>好好学习</span>"
}
})
</script>
</body>
</html>
2.v-for:循环动态绑定数据
- v-for:循环动态绑定数据( v-for="(item,index) in arr")
- 可以循环数字:item从1开始到当前数字, index从0开始
- 可以循环字符串:item是每一个字符,index索引
- 可以循环对象:item是属性值,index是属性名,第三个参是索引
- 可以循环数组:item是每一项,index是索引
<body>
<div id="app">
<!-- a 代表数组的每一项,index代表数组的索引 arr是data中一个变量-->
<!-- 需要创建什么元素,就把v-for放在哪个元素身上 -->
<!-- v-for可以循环数字 -->
<div v-for="(a,index) in arr">{{a}}索引{{index}}</div>
<ul>
<!-- <li v-for="a in num">{{a}}</li> -->
<!-- 也可以循环字符串 -->
<!-- <li v-for="(a,index) in str">{{a}}索引{{index}}</li> -->
<!-- a是属性值,b是属性名 -->
<li v-for="(a,b,c) in obj">{{a}}{{b}}{{c}}</li>
<!-- <li v-for="a in ary">{{a.fruit}}</li> -->
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// v-for : 可以循环数组,字符串,数字,对象
let vm = new Vue({
el:"#app",
data:{
arr:[100,200,300,400],
num:6,
str:"zhonghua",
obj:{name:"zfpx",age:10},
ary:[{fruit:"草莓"},{fruit:"苹果"}]
}
})
</script>
</body>
v-for练习
<div id="app">
<ul>
<li v-for="(a,index) in fruits">
{{index+1}}.{{a.name}}
<ul>
<!--a 只在当前子集可以使用-->
<li v-for="(b,index) in a.color">
<!--index如果在这个循环中不存在,会向上一级循环查找;-->
{{index+1}}.{{b}}
</li>
</ul>
</li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
fruits: [{
name: "苹果",
color: ["green", "red"]
}, {
name: "香蕉",
color: ["yellow", "green"]
}, {
name: "西瓜",
color: ["red", "white"]
}]
}
})
</script>
v-for要加:key
- 不加key当选中吕不为时,添加楠楠后选中的确是李斯,并不是我们想要的结果,我们想要的是当添加楠楠后,一种选中的是吕不为
- 加key同样当选中吕不为时,添加楠楠后依旧选中的是吕不为。
- vue中列表循环需加:key=“唯一标识” 唯一标识可以是item里面id index等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用主要是为了高效的更新虚拟DOM
<body>
<div id="app">
<div>
<input type="text" v-model="name">
<button @click="add">添加</button>
</div>
<ul>
<li v-for="(item, i) in list" :key="item.id">
<input type="checkbox"> {{item.name}}
</li>
</ul>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
name: '',
newId: 3,
list: [
{ id: 1, name: '李斯' },
{ id: 2, name: '吕不韦' },
{ id: 3, name: '嬴政' }
]
},
methods: {
add() {
//注意这里是unshift
this.list.unshift({ id: ++this.newId, name: this.name })
this.name = ''
}
}
});
</script>
</div>
</body>
</html>
3.v-bind :class :style
v-bind
将普通的属性转成动态的属性,可以去获取data中的数据;
v-bind:class :属性是可以是对象,里面的属性名是class的名字,后面需要跟布尔值,属性值时true,该样式有效,false该样式无效;如果是数组的话,是去获取data中的属性名对应的属性值就是class的名字
v-bind:style: 后面可以是对象 数组 或者data中属性名
<div id="app">
<!-- v-bind:可以省略 -->
<!-- <img :src="imgSrc" alt=""> -->
<!-- <div :a="imgSrc"></div> -->
<div v-bind:class="{x:flag}">中国</div>
<div v-bind:class="{x:flag,y:flag}">北京</div>
<!-- 如果是数组的话,是去获取data中的属性名对应的属性值就是class的名字 -->
<div v-bind:class="a">中国</div>
<div v-bind:class="[a,b]">北京</div>
<ul>
<li v-for="(a,index) in arr" :class="{y:index%2}">{{a}}</li>
</ul>
<div v-bind:style="{fontSize:num+'px'}">加油</div>
<div v-bind:style='z'>666888</div>
<div :style="[z]">666888</div>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// v-bind
// 1.将普通的属性转成动态的属性,可以去获取data中的数据;
// 2. v-bind:class :属性是可以是对象,里面的属性名是class的名字,属性值时true,该样式有效,false该样式无效
// 3. v-bind:style
new Vue({
el: "#app",
data: {
imgSrc: "../../images/16.jpg",
flag: true,
a: "x",
b: "y",
arr: [1, 2, 3, 4, 5],
num: 60,
z: {
color: "red"
}
},
methods: {
},
filters: {
}
});
</script>
4.v-model(表单)
v-model : 双向数据绑定;一般用于表单元素
在单选框中,被选中的那一项,会把input框的value值赋值给sex;v-model的值如果在单选框中相同,他们就互斥;
多选框:v-model可以绑定一个数组,那么当该项被选中时,会把该input框中value放到数组里面;如果多选框v-model绑定的不是一个数组,那么默认会将该值转成布尔值,控制所有复选框的选中状态
<body>
<div id="app">
<!-- <input type="text" v-model="msg"> -->
<!-- <input type="radio" v-model="sex" value="1">男
<input type="radio" v-model="sex" value="2">女
<input type="radio" v-model="food" value="3">水饺 -->
<input type="checkbox" v-model="hobby" value="游泳">游泳
<input type="checkbox" v-model="hobby" value="爬山">爬山
<input type="checkbox" v-model="hobby" value="打球">打球
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// v-model : 双向数据绑定;一般用于表单元素
// 在单选框中,被选中的那一项,会把input框的value值赋值给sex;v-model的值如果在单选框中相同,他们就互斥;
// 多选框:v-model可以绑定一个数组,那么当该项被选中时,会把该input框中value放到数组里面;如果多选框v-model绑定的不是一个数组,那么默认会将该值转成布尔值,控制所有复选框的选中状态
let vm = new Vue({
el:"#app",
data:{
msg:"上课了",
sex:"1",//数字和字符串都可以
food:"3",
hobby:["游泳"]
//hobby:1
},
created(){
},
methods:{
},
filters:{
}
});
</script>
</body>
Vue优化指令
- v-pre : 跳过这个元素的编译;加快了它的编译过程
- v-cloak : 未编译完,页面看不到胡子
- v-once : 只渲染一次;以后更改数据也不再更新了;
v-pre : 跳过这个元素的编译;加快了它的编译过程
v-cloak : 未编译完,页面看不到胡子
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
[v-cloak] {
display: none;
}
v-once : 只渲染一次;以后更改数据也不再更新了;
当写的结构时静态的时候,可以使用这个指令;
<head>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<button @click="fn">显示/隐藏</button>
<div v-once>{{msg}}</div>
<br>
<div v-cloak>{{msg}}</div>
<ul>
<li>button1</li>
<li>button2</li>
<li>button3</li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// v-pre : 跳过这个元素的编译;加快了它的编译过程
// v-cloak : 未编译完,页面看不到胡子
// 这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
// [v-cloak] {
// display: none;
// }
// v-once : 只渲染一次;以后更改数据也不再更新了;
// 当写的结构时静态的时候,可以使用这个指令;
let vm = new Vue({
el: "#app",
data: {
show: true,
msg: "你很好"
},
methods: {
fn() {
//this.show=!this.show;
this.msg = "你很帅"
}
}
})
</script>
</body>
Vue事件指令
- 给元素绑定的事件的方法,需要放在methods中
- 方式:v-on (简写@) :用来实现事件绑定的指令
- v-on:click=’ xxx’
- @click='xxx
<body>
<!--
v-on (简写@) :用来实现事件绑定的指令
v-on:click=' xxx'
@click='xxx
1.事件触发的时候,需要传递参数信息,把方法加小括号,$event是事件对象
v-on:click='sum( $event,10,20)
2.事件修饰符
常规修饰符: @click . prevent/stop = 'xxx'
按键修饰符: @keydown. enter/space/delete/up/right/ down/left...=' xxx’
键盘码: @keydown.13 = 'xxx'
组合按键: @keydown.al1t.67 = 'xxx’ //=>ALT+C
-->
<div id="app">
<a href="https://www.baidu.com/" @click.prevent.stop='func'>
666</a>
<!-- <button v-on:click='func' ></button> -->
<!-- <button v-on:click='sum( $event,10, 20)'></button> -->
<input type="text" placeholder="请输入搜索内容" v-model="text" @keydown.alt.67="func">
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
text: ""
},
methods: {
func(ev) {
// console.log(this);
// if(ev.keyCode===13){
// alert("666")
// }
alert("666");
},
sum(ev, n, m) {
console.log(arguments);
}
}
})
</script>
</body>
vue的事件对象
-
绑定事件时,可以有小括号,也可以没有
1.在绑定事件时,如果没有小括号,那么第一个参数就是事件对象
2. 如果有小括号,但是没有传参,那么e默认是undefined;
3. 如果需要事件对象,并且需要传参,那么需要在绑定时使用$event进行占位; -
事件触发的时候,需要传递参数信息,把方法加小括号,$event是事件对象
- v-on:click=‘sum( $event,10,20)’
<div id="app">
<button @click="fn($event,100,200)">提交</button>
<input type="text" @keyup="fn">
{{msg}}
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
msg: "该吃饭了"
},
methods: {
// 绑定事件时,可以有小括号,也可以没有
// 1.在绑定事件时,如果没有小括号,那么第一个参数就是事件对象
// 2. 如果有小括号,但是没有传参,那么e默认是undefined;
// 3. 如果需要事件对象,并且需要传参,那么需要在绑定时使用$event进行占位;
fn(e, a) { // e: 事件对象
console.log(e, a);
}
}
});
</script>
2.vue事件修饰符
- vue事件修饰符
常规修饰符: @click . prevent/stop = ‘xxx’
按键修饰符: @keydown. enter/space/delete/up/right/ down/left…=’ xxx’
键盘码: @keydown.13 = ‘xxx’
组合按键: @keydown.alt.67 = 'xxx’ //=>ALT+C - vue常规事件修饰符:
- 原生JS中e.stopPropagation() => @click . stop="”
- 原生JS中e.stopPropagation() => @click . stop="”
.stop: 阻止事件的冒泡传播; 从里向外
.prevent: 阻止事件的默认行为
.capture: 控制事件在捕获阶段执行 从外向里
.once : 只执行一次
.passive: 修饰onscroll事件,不会等到onscroll执行完,就会立即执行下一次,提高代码的性能;
.self:只有点击自己的时候才会执行
- 按键修饰符:
.enter .tab .delete .esc .space .up .down .left .right
<body>
<div id="app">
<div @click.capture="fn1" style="width:100px;height:100px;background: red;">
grandparent
<div @click.self="fn2">
parent
<div @click.once="fn3">
child
</div>
</div>
</div>
<input type="text" @keyup.left="fn">
<div @click="fn1">123456</div>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 原生JS中e.stopPropagation()
// 事件修饰符
// .stop: 阻止事件的冒泡传播;
// .prevent: 阻止事件的默认行为
// .capture: 控制事件在捕获阶段执行
// .once : 只执行一次
// .passive: 修饰onscroll事件,不会等到onscroll执行完,就会立即执行下一次,提高代码的性能;
// .self:只有点击自己的时候才会执行
// 键盘修饰符:
// .enter .tab .delete .esc .space .up .down .left .right
let vm = new Vue({
el:"#app",
data:{
msg:"该吃饭了"
},
methods:{
fn1(){
console.log("outer");
},
fn2(){
console.log("inner");
},
fn3(){
console.log("center");
},
fn(){
console.log("快下课了");
}
}
});
// 1. button div:点击按钮隐藏,再点击显示
// 2. input 框,输入内容,回车
</script>
</body>
Vue自定义指令
- Vue除了核心的内置指令,vue还可以自定义指令
- 自定义指令:
- 全局自定义指令
- 局部自定义指令
<body>
<div id="app">
<div v-drag style="width:100px;height:100px;background: red;position: absolute;">
<div v-drag></div>
</div>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 全局指令
Vue.directive("drag", {
inserted: function (ele) {
ele.onmousedown = function (e) {
// this -->
// 点击时,记录鼠标距离盒子边框的位置
this.l = e.clientX - this.offsetLeft;
this.t = e.clientY - this.offsetTop;
document.onmousemove = function (e) {
ele.style.left = e.clientX - ele.l + "px";
ele.style.top = e.clientY - ele.t + "px";
}
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
}
}
console.log(1);
}
});
let vm = new Vue({
el: "#app",
directives: {
// 定义局部指令 局部命令优先级高
drag(ele) { // ele: 代表加上v-drag的元素 drag 用了几次,输出几次;
ele.onmousedown = function (e) {
// this -->
// 点击时,记录鼠标距离盒子边框的位置
this.l = e.clientX - this.offsetLeft;
this.t = e.clientY - this.offsetTop;
document.onmousemove = function (e) {
ele.style.left = e.clientX - ele.l + "px";
ele.style.top = e.clientY - ele.t + "px";
}
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
}
});
// let vm1 = new Vue({
// el:"#app1"
// });
</script>
</body>