一、绑定样式
1. 绑定内联样式
(1)将元素的 style 属性看做一个大的字符串来绑定
<元素 :style="变量名"> data:{ 变量名:"css属性名1: 属性值1; css属性名2:属性值2;..." } //运行时vue把变量的字符串值,直接放到元素的style属性后,作为元素的内联样式 //该方法极其不便于只修改其中某一个css属性值,几乎不用
(2)使用对象语法灵活绑定每个 css 属性值
<元素 :style="{ css属性名1:变量1, css属性名2:变量2 , ... }" data:{ 变量1: 属性值1, 变量2: 属性值2 } //此方法极其便于修改其中某一个css属性值 //缺点是如果多个元素刚好都需要绑定同一个css属性,则属性值的变量名易冲突
举例:绑定一架飞机的位置;
<body> <div id="app"> <img :style="{left:left,top:top}" src="img/p3.png"> </div> <script> var vm = new Vue({ el: "#app", data: { left: "200px", top: "200px" } }); // 通过键盘按键控制飞机飞行 window.onkeydown = function (e) { console.log(e.keyCode); if (e.keyCode == 37) { var left = parseInt(vm.left); left -= 10; vm.left = `${left}px` } else if (e.keyCode == 38) { var top = parseInt(vm.top); top -= 10; vm.top = `${top}px` } else if (e.keyCode == 39) { var left = parseInt(vm.left); left += 10; vm.left = `${left}px` } else if (e.keyCode == 40) { var top = parseInt(vm.top); top += 10; vm.top = `${top}px` } } </script> </body>
效果如下:
(3)将对象写在 data 中的绑定方式
<元素1 :style="变量1"> <元素2 :style="变量2"> data:{ 变量1:{ css属性1:值1, css属性2:值2 }, 变量2:{ css属性1:值1, css属性2:值2 }, } //既便于修改任意一个元素的css属性,又避免多个元素的css属性发生冲突
如果有固定不变的 css 属性,就写在不带 : 的 style 里;而变化的 css 属性写在带 : 的 style 里。运行时两个 style 是合并发挥作用的,不会发生覆盖。
<元素 style="固定不变的css属性" :style="可能变化的css属性">
举例: 绑定两架飞机的位置;
<body> <div id="app"> <img :style="p3style" src="img/p3.png"> <img :style="p5style" src="img/p5.png"> </div> <script> var vm = new Vue({ el: "#app", data: { p3style: { left: "200px", bottom: "100px" }, p5style: { left: "500px", bottom: "100px" } } }); //希望按方向键操作第2架黄色飞机移动 window.onkeydown = function (e) { console.log(e.keyCode); if (e.keyCode == 37) { var left = parseInt(vm.p5style.left); left -= 10; vm.p5style.left = `${left}px` } else if (e.keyCode == 38) { var bottom = parseInt(vm.p5style.bottom); bottom += 10; vm.p5style.bottom = `${bottom}px` } else if (e.keyCode == 39) { var left = parseInt(vm.p5style.left); left += 10; vm.p5style.left = `${left}px` } else if (e.keyCode == 40) { var bottom = parseInt(vm.p5style.bottom); bottom -= 10; vm.p5style.bottom = `${bottom}px` } //实现第1架飞机移动,左65 上87 右68 下83 if (e.keyCode == 65) { var left = parseInt(vm.p3style.left); left -= 10; vm.p3style.left = `${left}px` } else if (e.keyCode == 87) { var bottom = parseInt(vm.p3style.bottom); bottom += 10; vm.p3style.bottom = `${bottom}px` } else if (e.keyCode == 68) { var left = parseInt(vm.p3style.left); left += 10; vm.p3style.left = `${left}px` } else if (e.keyCode == 83) { var bottom = parseInt(vm.p3style.bottom); bottom -= 10; vm.p3style.bottom = `${bottom}px` } } </script> </body>
2. 绑定 class
(1)将 class 属性看做一个普通的字符串变量绑定
<元素 :class="变量名" data:{ 变量名:" class名1 class名2 class名3 ..." } //该方法极不便于只修改其中某一个class
(2)将 class 属性看做一个对象来绑定
<元素 :class="{ class名1: 变量1, class名2:变量2,... }" data:{ 变量1: true或false, //开关,true表示启用这个class 变量2: true或false } //该方法便于修改某一个class //缺点是如果多个元素都绑定同一种class,但是启用或不启用的状态不同,class的变量名易冲突
举例:实现手机号带样式的验证;
<body> <!--VUE 3步 1. 做界面 1.1 唯一父元素 1.2 找可能变化的位置: 本例中:input内容由用户主动输入而改变,v-model span内容随程序自动改变,{{}} span的class在success和fail之间切换,绑定class 1.3 找可能触发事件的位置 本例中: 一边触发,一边验证,监视函数watch--> <div id="app"> 手机号:<input type="text" v-model="phone"> <span :class="{success:success,fail:fail}">{{msg}}</span> </div> <script> //2. 创建new Vue()对象 new Vue({ el: "#app", //3. 创建模型对象: data: { phone: "", //此时未输入 success: false, //未输入时不显示提示 fail: false }, watch: { phone() { // 验证手机号格式 var reg = /^1[3-9]\d{9}$/; var result = reg.test(this.phone); // 如果手机号格式正确 if (result == true) { this.success = true; //绿色success提示显示 this.fail = false; //红色fail提示不显示 this.msg = "手机号格式正确"; //否则反之 } else { this.success = false; this.fail = true; this.msg = "手机号格式错误!"; } } } }) </script> </body>
效果如下:
(3)将对象放进 data 中定义
<元素1 :class="变量1"> <元素2 :class="变量2"> data:{ 变量1:{ class名1:true或false, class名2:true或false }, 变量2:{ class名1:true或false, class名2:true或false }, } //该方法可避免不同元素之间绑定同一class时互相影响
如果有固定不变的 class,应该放在不带 : 的 class 中,而变化的 class 则放在带 : 的 class 中,最终编译时,不带 : 的 class 会和带 : 的 class 合并为一个 class 共同起作用。
<元素 class="固定不变的class" :class="变化的class"
举例:实现手机号和密码的带样式的验证;
<body> <div id="app"> 手机号:<input type="text" v-model="phone"> <span :class="phoneObj">{{phoneMsg}}</span><br> 密码:<input type="password" v-model="pwd"> <span :class="pwdObj">{{pwdMsg}}</span> </div> <script> //2. 创建new Vue()对象 new Vue({ el: "#app", data: { phone: "", phoneObj: { success: false, //未输入时无提示 fail: false }, phoneMsg: "", pwd: "", pwdObj: { success: false, //未输入时无提示 fail: false }, pwdMsg: "" }, watch: { phone() { // 验证手机号格式 var reg = /^1[3-9]\d{9}$/; var result = reg.test(this.phone); // 如果手机号格式正确 if (result == true) { this.phoneObj = { success: true, //绿色success提示显示 fail: false //红色fail提示不显示 } phoneMsg = "手机号格式正确"; //否则反之 } else { this.phoneObj = { success: false, fail: true, } this.phoneMsg = "手机号格式错误!"; } }, pwd() { // 验证密码格式 var reg = /^\d{6}$/; var result = reg.test(this.pwd); // 如果密码格式正确 if (result == true) { this.pwdObj = { success: true, //绿色提示显示 fail: false //红色提示不显示 } this.pwdMsg = "密码格式正确"; //否则反之 } else { this.pwdObj = { success: false, fail: true } this.pwdMsg = "密码格式错误!"; } } } }) </script> </body>
效果如下:
二、自定义指令
如果希望在开始时就能对 HTML 元素执行一些初始化 DOM 操作(如自动获得焦点),但是 vue 中没有提供对应功能的指令。这时就可以自定义指令。
1. 自定义指令的创建
(1)创建一个指令保存在 Vue 内存中备用
Vue.directive("指令名", { //插入后: 当前带有指令的DOM元素被vue挂载到页面上之后,自动触发的回调函数 inserted(当前带有指令的DOM元素){ 对当前带有指令的DOM元素执行原生的DOM操作 } }) //注意: //Vue中V必须大写 //定义指令时,指令名不加v-前缀
(2)在页面上使用自定义的vue指令
<元素 v-指令名> //注意: //使用指令时,必须加v-前缀
需要注意,自定义指令写在 HTML 中,而 HTML 只认识小写字母,所以不能使用驼峰命名法,如果包含多个单词,可以用”-“隔开。
原理:
Vue.directive() 是创建一个自定义指令对象,保存在 Vue 类型的内存中备用。new Vue() 扫描时,发现 v- 开头的自定义指令,就去 Vue 内存中找同名的自定义指令,找到同名的自定义指令,就自动执行自定义指令对象中的 inserted() 函数,并将当前扫描到的带有自定义指令的元素对象传给 inserted() 的形参变量;在 inserted() 函数内,可对当前传入的带有自定义指令的 DOM 元素应用原生的 DOM 操作。
举例:自定义指令让元素自动获得焦点;
<body> <div id="app"> <!--希望在页面加载时,input文本框自动获得焦点--> <input id="txt" v-myfocus><button>搜索</button> </div> <script> //定义自定义指令myfocus Vue.directive("myfocus", { inserted(element) { element.focus(); } }) new Vue({ el: "#app" }) </script> </body>
效果如下: