Vue(四)绑定样式、自定义指令

简介: Vue(四)绑定样式、自定义指令

一、绑定样式

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>

效果如下:

image.png



(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>

效果如下:

image.png


(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>

效果如下:

image.png


二、自定义指令

       如果希望在开始时就能对 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>

效果如下:


image.png



相关文章
|
1月前
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
137 4
|
14天前
|
人工智能 自然语言处理 JavaScript
用 CodeBuddy 搭建Vue框架 像呼吸一样简单
本文介绍如何借助 CodeBuddy 快速创建 Vue 项目。CodeBuddy 是一款支持自然语言编程的工具,能根据用户需求自动生成代码,降低开发门槛。文章详细说明了通过 CodeBuddy 创建 Vue 项目的步骤,包括解决项目创建失败的问题、自动补全代码功能以及启动开发服务器的方法。无论开发者经验如何,CodeBuddy 都能显著提升效率,让开发更专注创意实现。
|
25天前
|
缓存 JavaScript 前端开发
Vue 基础语法介绍
Vue 基础语法介绍
|
2月前
|
SQL JavaScript 前端开发
Vue实现动态数据透视表(交叉表)
Vue实现动态数据透视表(交叉表)
194 13
|
5月前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
241 1
|
2月前
|
JavaScript 前端开发 算法
vue渲染页面的原理
vue渲染页面的原理
145 56
|
2月前
|
数据采集 资源调度 JavaScript
极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图
本文介绍了使用 Vue Flow 绘制流程图的方法与技巧。Vue Flow 是一个灵活强大的工具,适合自定义复杂的流程图。文章从环境要求(Node.js v20+ 和 Vue 3.3+)、基础入门案例、自定义功能(节点与连线的定制、事件处理)到实际案例全面解析其用法。重点强调了 Vue Flow 的高度灵活性,虽然预定义内容较少,但提供了丰富的 API 支持深度定制。同时,文中还分享了关于句柄(handles)的使用方法,以及如何解决官网复杂案例无法运行的问题。最后通过对比 mermaid,总结 Vue Flow 更适合需要高度自定义和复杂需求的场景,并附带多个相关技术博客链接供进一步学习。
|
3月前
|
移动开发 JavaScript API
Vue Router 核心原理
Vue Router 是 Vue.js 的官方路由管理器,用于实现单页面应用(SPA)的路由功能。其核心原理包括路由配置、监听浏览器事件和组件渲染等。通过定义路径与组件的映射关系,Vue Router 将用户访问的路径与对应的组件关联,支持哈希和历史模式监听 URL 变化,确保页面导航时正确渲染组件。
|
3月前
|
监控 JavaScript 前端开发
ry-vue-flowable-xg:震撼来袭!这款基于 Vue 和 Flowable 的企业级工程项目管理项目,你绝不能错过
基于 Vue 和 Flowable 的企业级工程项目管理平台,免费开源且高度定制化。它覆盖投标管理、进度控制、财务核算等全流程需求,提供流程设计、部署、监控和任务管理等功能,适用于企业办公、生产制造、金融服务等多个场景,助力企业提升效率与竞争力。
195 12
|
2月前
|
存储 数据采集 供应链
属性描述符初探——Vue实现数据劫持的基础
属性描述符还有很多内容可以挖掘,比如defineProperty与Proxy的区别,比如vue2与vue3实现数据劫持的方式有什么不同,实现效果有哪些差异等,这篇博文只是入门,以后有时间再深挖。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~