VUE笔记(三)vue的语法

一、计算属性

1、计算属性的概念

计算属性是依赖于源数据(data或者属性中的数据),在元数据的基础上进行逻辑运算后得到的新的数据,计算属性要依赖于源数据,源数据数据变化计算属性也会变化

2、计算属性的语法

在vue2中使用computed这个选项完成计算属性的

<template>
  <div>
    <h2>购物车</h2>
    <table>
      <thead>
        <tr>
          <td>编号</td>
          <td>商品</td>
          <td>数量</td>
          <td>价格</td>
          <td>小计</td>
        </tr>
      </thead>
      <tbody>
          <tr v-for="item in filterShopcartList" :key="item.id">
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>
                <button @click="item.num--">-</button>
                {{item.num}}
                <button @click="item.num++">+</button>
            </td>
            <td>
              {{item.price}}
            </td>
            <td>{{(item.price*item.num).toFixed(2)}}</td>
          </tr>
      </tbody>
      <tfoot>
        <tr>
          <td colspan="5">
            总价:{{getTotalPrice}}
          </td>
        </tr>
      </tfoot>
    </table>
  </div>
</template>
​
<script>
export default {
  data(){
    return{
      shopcartList:[
        {
          id:'1001',
          name:'红富士苹果',
          price:3.69,
          num:1
        },
        {
          id:'1002',
          name:'威化饼干',
          price:1.69,
          num:1
        },
        {
          id:'1003',
          name:'康师傅方便面',
          price:5.21,
          num:1
        }
      ]
    }
  },
  computed:{
    filterShopcartList:{
      //get方法是为了完成获取计算值后的属性
      get(){
        return this.shopcartList.filter(item=>item.num>0)
      }
    },
    getTotalPrice:{
      get(){
        return this.filterShopcartList.reduce((prve,cur)=>prve+cur.price*cur.num,0).toFixed(2)
      }
    }
  }
}
</script>
​
<style>
  table{
    border-collapse: collapse;
  }
  td{
    border:1px solid #999;
    padding: 10px;
  }
</style>

2、计算属性的简写形式

1)计算属性的标准写法:(很少用,需要更改原数据时才用)
computed:{

    计算属性名称:{

        get(){

            return 新的结果

                }

            }

        }
2)计算属性的简单写法(常用)
computed:{

    计算属性名称:{

        return 新的结果

        }

    }
<template>
  <div>
    <h2>购物车</h2>
    <table>
      <thead>
        <tr>
          <td>编号</td>
          <td>商品</td>
          <td>数量</td>
          <td>价格</td>
          <td>小计</td>
        </tr>
      </thead>
      <tbody>
          <tr v-for="item in filterShopcartList" :key="item.id">
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>
                <button @click="item.num--">-</button>
                {{item.num}}
                <button @click="item.num++">+</button>
            </td>
            <td>
              {{item.price}}
            </td>
            <td>{{(item.price*item.num).toFixed(2)}}</td>
          </tr>
      </tbody>
      <tfoot>
        <tr>
          <td colspan="5">
            总价:{{getTotalPrice}}
          </td>
        </tr>
      </tfoot>
    </table>
  </div>
</template>
​
<script>
export default {
  data(){
    return{
      shopcartList:[
        {
          id:'1001',
          name:'红富士苹果',
          price:3.69,
          num:1
        },
        {
          id:'1002',
          name:'威化饼干',
          price:1.69,
          num:1
        },
        {
          id:'1003',
          name:'康师傅方便面',
          price:5.21,
          num:1
        }
      ]
    }
  },
  computed:{
    filterShopcartList:{
      //get方法是为了完成获取计算值后的属性
      get(){
        return this.shopcartList.filter(item=>item.num>0)
      }
    },
    getTotalPrice:{
      get(){
        return this.filterShopcartList.reduce((prve,cur)=>prve+cur.price*cur.num,0).toFixed(2)
      }
    }
  }
}
</script>
​
<style>
  table{
    border-collapse: collapse;
  }
  td{
    border:1px solid #999;
    padding: 10px;
  }
</style>

3、计算属性的缓存特性

计算属性具有缓存作用,在原数据不改变的情况下,计算属性多次调用只有第一次进行计算,后续都是从缓存中获取数据,如果源数据变化之后,计算属性就会重新进行计算。

4、setter和getter方法

<template>
    <div>
        <div>firstName:<span>{{firstName}}</span></div>
        <div>middleName:<span>{{middleName}}</span></div>
        <div>lastName:<span>{{lastName}}</span></div>
        <div>fullName:<span>{{name}}</span></div>
        <button @click="name='zhang san feng'">changeFullName</button>
    </div>
</template>
​
<script>
export default {
  data(){
    return{
      firstName:'zhai',
      middleName:'ji',
      lastName:'zhe'
    }
  },
  computed:{
    name:{
      get(){
        return this.firstName+" "+this.middleName+" "+this.lastName
      },
      set(val){
        //计算属性是不能改的
        console.log('val',val);
        this.firstName=val.split(" ")[0]
        this.middleName=val.split(" ")[1]
        this.lastName=val.split(" ")[2]
      }
    }
  }
}
</script>
​
<style lang="scss">
  div{
    span{
      color: blue;
    }
  }
</style>

三、侦听器

1、侦听器的概念

在vue中当我们对data的数据或者计算属性进行变化的时候,专门一个选项可以随时监听data或者计算属性的变化,从而完成相应的逻辑

2、监听器的语法

监听器的语法有两种形式

  • 简写写法

watch:{
    //newval:变化之后的数据
    //oldval:变化之前的数据
    监视的数据名(newval,oldval){
​
    }
}

案例:监视计数器num的变化

export default {
  data(){
    return{
      num:0
    }
  },
  watch:{
    num(newval,oldval){
      console.log(newval,oldval);
    }
  }
}
  • 监听器的标准写法

    语法

 watch:{
    监听的数据名:{
      //监听的逻辑处理方法
      handler(newval,oldval){
​
      },
      //是否深度监听
      deep:true|false,
      //是否立即监听
      immediate:true|false
    }
  }

案例:使用标准写法完成计数器的监听

export default {
  data(){
    return{
      num:0
    }
  },
  watch:{
    num:{
      handler(newval,oldval){
        console.log(newval,oldval);
      }
    }
  }
}

3、监听对象中属性变化

如果要监听对象中属性的变化,可以有两种方式

第1种方式:通过'对象名.属性名'的方式

<template>
  <div>
     <div>
        {{obj.a}} <button @click="obj.a++">a+</button>
     </div>
     <div>
        {{obj.b}} <button @click="obj.b++">a+</button>
     </div>
     <div>
        {{obj.c}} <button @click="obj.c++">a+</button>
     </div>
  </div>
</template>
​
<script>
/* 
  watch:{
    '对象名.属性名'(newval,oldval){
    }
  }
*/
export default {
  data(){
    return{
      obj:{
        a:10,
        b:20,
        c:30
      }
    }
  },
  watch:{
    'obj.a'(newval,oldval){
      console.log('obj.a',newval,oldval);
    },
    'obj.b'(newval,oldval){
      console.log('obj.b',newval,oldval);
    },
    'obj.c'(newval,oldval){
      console.log('obj.c',newval,oldval);
    }
  }
}
</script>

如上这种方式如果属性过多,它就太麻烦了

  • 方式2:通过深度监听的方式来完成对对象的监听

export default {
  data(){
    return{
      obj:{
        a:10,
        b:20,
        c:30
      }
    }
  },
  computed:{
    //新定义一个计算属性newObj,该计算属性的作用是将data对象中的obj做一个深拷贝
    newObj(){
      //这种深拷贝对于如果一个对象中有函数,获知时间类型是无法进行深拷贝
      //JSON.stringify将JSON格式字符串(对象)转换为js对象(属性名没有双引号)
      //JSON.parse将JSON字符串转为对象;
      return JSON.parse(JSON.stringify(this.obj))
    }
  },
  watch:{
    //obj:要监听的对象
    newObj:{
      //执行监听的具体钩子函数
      handler(newval,oldval){
        console.log(newval,oldval);
      },
      //开启深度监听
      deep:true
    }
  }
}

4、立即监听设置

通过对watch中 immediate设置为true,就会开启立即监听

 watch:{
    //obj:要监听的对象
    newObj:{
      //执行监听的具体钩子函数
      handler(newval,oldval){
        console.log(newval,oldval);
      },
      //开启深度监听
      deep:true,
      //开启立即监听
      immediate:true
    }
  }

四、过滤器

1、什么是过滤器

vue中定义过滤器,主要用于文本格式化,具体可以完成如下功能

  • 日期的格式化

  • 货币格式化

  • 小数点精确度的截取

  • 大小写首字母转换等

注意:vue2中过滤器,vue3中将过滤去掉了

2、过滤器的分类

按照作用范围,可以将过滤器分成两大类

  • 全局过滤器:针对项目中所有组件都有用

  • 私有过滤器(局部过滤器)只针对当前组件有效

2.1、定义私有私有过滤器
  • 定义私有过滤器

export default{
   data(){},
   methods{},
   //filters:配置对象
   filters:{
      过滤器的名称(参数){
     
      }
   }
}
  • 如何调用过滤器

使用过滤器的时候可以在两种情况下使用,第1种情况在插值表达式中使用;第2种在属性中使用

在插值表达式中使用

{{message|过滤器的2名称|过滤器2的名称}}

message代表是输出数据对象,|这个竖杠表示的就是一个管道符,使用这个符号将插值表达式和过滤器连接在一起

使用v-bind在属性中使用

<div v-bind:id="id的变量|过滤器的名称"></div>

案例:通过身份证获取格式化出生日期

<template>
    <div>
        <div>身份证号:{{idcard}}</div>
        <div>生日:{{idcard|birthday}}</div>
    </div>
</template>

<script>
export default {
  data(){
    return{
      idcard:'610122198404084030'
    }
  },
  filters:{
    birthday(val){
      return val.slice(6,10)+"-"+val.slice(10,12)+"-"+val.slice(12,14)
    }
  }
}
</script>
2.2、定义全局过滤器

定义全局过滤器的语法

Vue.filter('过滤器的名称',function(val){ return result})

定义全局过滤器的步骤

  • 在src下创建一个filters的文件夹

  • 在src/filters文件夹下定义过滤器的js文件

//首先先导入Vue
import Vue from 'vue'
Vue.filter('capitalize',function(val){
    return val.charAt(0).toUpperCase()+val.slice(1)
})
  • 在main.js中导入定义全局过滤器

import Vue from 'vue'
import App from './App.vue'
import './filters/capitalize' //在此处导入

Vue.config.productionTip = false
new Vue({
  render: h => h(App),
}).$mount('#app')
  • 在组件中可以使用|的方式来调用过滤器

五、自定义指令

之前我们已经接触过指令,在但是我们接触这些指令都是vue提供的内置指令,每一种指令有着不同的用途,如果开发者要想自定义指令,就可以使用自定义指令完成不同功能的封装

1、自定义指令的分类

  • 全局自定义指令:可以作用域全局所有的组件

  • 私有自定义指令:只能作用域该组件

1)私有自定义指令的语法
<template>
    <div>
      <h2 v-mycolor="color" @click="color='#0000ff'">Hello Giles</h2>
      <!-- <h1 v-mycolor="color='#ff0000'">Hello Giles</h1>
      <h1 v-mycolor="color='#00ff00'">Hello Giles</h1> -->
    </div>
</template>

<script>
export default {
  data(){
    return{
      color:'orange'
    }
  },
  directives:{
    mycolor:{
      /*
        当我们将指令绑定到标签的时候会调用一次,在此方法中完成初始化功能
        el:所绑定指令(自定义指令)所在的DOM元素
        bindings:自定义指令的配置对象
          modifiers:指令的修饰符
          name:指令的名称(不含v-和修饰符的)
          rawName:指令的全名(v-的前缀和修饰符)
          value:指定的所传递的值
        vNode:更新之后的虚拟DOM节点对象
        oldVnode:更新之前的虚拟DOM节点
      */
      bind(el,bindings,vNode,oldVnode){
        console.log('bindings',bindings.value);
        el.style.color=bindings.value
      },
      componentUpdated(el,bindings,vNode,oldVnode){
        console.log('vNode',vNode);
        console.log('oldVnode',oldVnode);
        el.style.color=bindings.value
        el.innerHTML="Hello Woniuxy"
      }
    }
  }
}
</script>

<style>

</style>
2)全局自定义指令的定义步骤

步骤

  • 在src目录下创建directives文件夹,然后在文件夹下创建自定义指令

import Vue from 'vue'
Vue.directive('ellipses',{
    bind(el,bindings){
       let w;
       if(bindings.value){
         w=bindings.value.width
       }else{
         w="100px"
       }
       el.style.width=w
       el.style.whiteSpace="nowrap"
       el.style.textOverflow="ellipsis"
       el.style.overflow='hidden'
    }
})
  • 在main.js中引入自定义指令

import Vue from 'vue'
import App from './App.vue'
import './directives/ellipses'
Vue.config.productionTip = false
new Vue({
  render: h => h(App),
}).$mount('#app')
  • 在组件中应用

 <div v-ellipses>白日依山尽,黄河入海流,欲穷千里目,更上一层楼</div>
 <div v-ellipses="{width:'150px'}">白日依山尽,黄河入海流,欲穷千里目,更上一层楼</div>
 <div v-ellipses="{width:'200px'}">白日依山尽,黄河入海流,欲穷千里目,更上一层楼</div>

2、自定义指令的案例

1)完成水印功能

import Vue from 'vue'
Vue.directive('waterMarker',{
    bind(el,bindings){
        let canvs=document.createElement('canvas')
        //设置画布的大小
        canvs.width=250
        canvs.height=150
        //获取画笔的上下文对象
        let cxt=canvs.getContext('2d')
        cxt.rotate((20*Math.PI)/180)
        cxt.fillStyle=bindings.value.color
        cxt.font="48px 宋体"
        cxt.fillText(bindings.value.content,canvs.width/10,canvs.height/2)
        el.appendChild(canvs)
    }
})

2)完成画板功能

import Vue from 'vue'
/*
    Vue.directive是用于定义全局指令的
    参数有两个
    参数1:自定义指令名称
    参数2:自定义指令的配置对象
*/
Vue.directive('draw',{
    bind(el,bindings){
        console.log(bindings.value);
        //创建Canvas对象
        let cvs=document.createElement('canvas')
        //给画布设置宽和高
        cvs.width=bindings.value.width
        cvs.height=bindings.value.height
        //获取上下文对象
        let cxt=cvs.getContext('2d')
        //给画笔绑定onmousedown
        cvs.onmousedown=function(e){
            //获取鼠标点下去的坐标
           cxt.moveTo(e.pageX-this.offsetLeft,e.pageY-this.offsetTop)
           //当鼠标移动时候
           cvs.onmousemove=function(e){
              cxt.lineTo(e.pageX-this.offsetLeft,e.pageY-this.offsetTop)
              cxt.stroke()
           }
           cvs.onmouseup=function(){
             cvs.onmousemove=null
           }
        }
        el.appendChild(cvs)
    }
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/92426.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年天津市大学软件学院专升本专业课考试大纲

天津市大学软件学院2024年“高职升本科”联合招生专业考试大纲 一、考试性质 天津市大学软件学院“高职升本科”联合招生专业考试是由合格的高职高专毕业生参加的选拔性考试。学校根据考生的成绩&#xff0c;按照已确定的招生计划&#xff0c;德、智、体全面衡量&#xff0c;…

mysql 查询的字段值太长显示不全 group_concat

当前这个字段非常的长&#xff0c;在数据库看的时候也只是显示一部分内容&#xff0c;这是由于group_concat的group_concat_max_len参数的值太小造成的&#xff0c;默认值如下&#xff1a; show VARIABLES like group_concat_max_len 我们需要将这个值调大一点就可以解决上面这…

利用 IDEA IDE 的轻量编辑模式快速查看和编辑工程外的文本文件

作为程序员, 我们都知道 IDE 的很好用的, 它的文本编辑器功能也非常的强大, 用起来非常便捷. 在长年累月的使用中, 我们也变得对其非常熟悉, 以致于使用起其它简单地轻量级的文本编辑器来, 比如什么记事本, Notepad, UltraEdit 等等呀, 觉得既不方便又不熟悉. 关键是很多的操作…

解决`idea`中`database`工具查询起别名乱码问题

文章目录 解决idea中database工具查询起别名乱码问题场景复现如何解决方式一 设置编码方式二&#xff1a;修改字体 原因说明 解决idea中database工具查询起别名乱码问题 场景复现 使用Idea做查询的并且起别名出现了中文乱码 如何解决 方式一 设置编码 settings->输入框输…

基于黑寡妇算法优化的BP神经网络(预测应用) - 附代码

基于黑寡妇算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于黑寡妇算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.黑寡妇优化BP神经网络2.1 BP神经网络参数设置2.2 黑寡妇算法应用 4.测试结果&#xff1a;5.Matlab代…

Hyperf 如何做到用两个端口 9501/9502 都能连接 Websocket 服务以及多 Worker 协作实现聊天室功能

为何 Hyperf 能够在两个端口上监听 WebSocket 连接&#xff1f; 源码角度来看&#xff0c;在配置了多个 Servers 时&#xff0c;实际上&#xff0c;只启动了一个 Server 注&#xff1a;我之前接触的代码都是启动一个服务绑定一个端口&#xff0c;之前也看过 swoole 扩展的文档…

数据结构--树4.2.1(二叉树)

目录 一、二叉树的存储结构 二、二叉树的遍历 一、二叉树的存储结构 顺序存储结构&#xff1a;二叉树的顺序存储结构就是用一维数组存储二叉树中的各个结点&#xff0c;并且结点的存储位置能体现结点之间的逻辑关系。 链式存储结构&#xff1a;二叉树每个结点最多只有两个孩…

SciencePlots 基本语法及特点

文章目录 简介安装 LaTeXSciencePlots 绘图示例 简介 用户有时需要根据期刊的配图绘制要求进行诸如字体、刻度轴、轴脊、图例等图层属性的定制化修改&#xff0c;耗时的同时也会容易导致用户忽略一些图层细节要求。 SciencePlots 作为一个专门用于科研论文绘图的第三方拓展工…

QT基础教程之二 第一个Qt小程序

QT基础教程之二 第一个Qt小程序 按钮的创建 在Qt程序中&#xff0c;最常用的控件之一就是按钮了&#xff0c;首先我们来看下如何创建一个按钮 QPushButton * btn new QPushButton; 头文件 #include <QPushButton>//设置父亲btn->setParent(this);//设置文字btn-&g…

微服务架构2.0--云原生时代

云原生 云原生&#xff08;Cloud Native&#xff09;是一种关注于在云环境中构建、部署和管理应用程序的方法和理念。云原生应用能够最大程度地利用云计算基础设施的优势&#xff0c;如弹性、自动化、可伸缩性和高可用性。这个概念涵盖了许多方面&#xff0c;包括架构、开发、…

channel并发编程

不要通过共享内存通信&#xff0c;要通过通信共享内存。 channel是golang并发编程中一种重要的数据结构&#xff0c;用于多个goroutine之间进行通信。 我们通常可以把channel想象成一个传送带&#xff0c;将goroutine想象成传送带周边的人&#xff0c;一个传送带的上游放上物品…

【沐风老师】如何在3dMax中将3D物体转化为样条线构成的对象?

在3dMax中如何把三维物体转化为由样条线构成的对象&#xff1f;通常这样的场景会出现在科研绘图或一些艺术创作当中&#xff0c;下面给大家详细讲解一种3dmax三维物体转样条线的方法。 第一部分&#xff1a;用粒子填充3D对象&#xff1a; 1.创建一个三维对象&#xff08;本例…

【广州华锐互动】VR高校虚拟实验教学平台提供丰富的资源支持,提高教学效果

随着科技的不断进步&#xff0c;虚拟现实(VR)技术已经逐渐渗透到各个领域&#xff0c;其中包括教育。 广州华锐互动利用VR虚拟现实技术打造的VR高校虚拟实验教学平台&#xff0c;是一种新型的教学工具&#xff0c;它提供了一个在线的教学资源管理平台&#xff0c;包含教学平台、…

Linux 基金会宣布正式进驻中国

在 LinuxCon 2017 &#xff08;北京&#xff09;即将召开前夕&#xff0c;我们Linux 中国会同 51CTO、开源中国对 Linux 基金会执行董事 Jim Zemlin 进行了一场远跨大洋的视频专访。 在这次专访中&#xff0c;Jim 先生回答了几个开源界和互联网领域关注的问题&#xff0c;并披…

低代码已经发展到什么水平了

陈老老老板&#x1f9b8; &#x1f468;‍&#x1f4bb;本文专栏&#xff1a;生活&#xff08;主要讲一下自己生活相关的内容&#xff09; &#x1f468;‍&#x1f4bb;本文简述&#xff1a;生活就像海洋,只有意志坚强的人,才能到达彼岸。 &#x1f468;‍&#x1f4bb;上一篇…

4.6 TCP面向字节流

TCP 是面向字节流的协议&#xff0c;UDP 是面向报文的协议 操作系统对 TCP 和 UDP 协议的发送方的机制不同&#xff0c;也就是问题原因在发送方。 UDP面向报文协议&#xff1a; 操作系统不会对UDP协议传输的消息进行拆分&#xff0c;在组装好UDP头部后就交给网络层处理&…

春秋云镜:CVE-2019-9042(Sitemagic CMS v4.4 任意文件上传漏洞)

一、题目 靶标介绍&#xff1a; Sitemagic CMS v4.4 index.php?SMExtSMFiles 存在任意文件上传漏洞&#xff0c;攻击者可上传恶意代码执行系统命令。 进入题目&#xff1a; admin/admin /index.php?SMExtSMFiles&SMTemplateTypeBasic&SMExecModeDedicated&SMFil…

苍穹外卖总结

前言 1、软件开发流程 瀑布模型需求分析//需求规格说明书、产品原型↓ 设计 //UI设计、数据库设计、接口设计↓编码 //项目代码、单元测试↓ 测试 //测试用例、测试报告↓上线运维 //软件环境安装、配置第一阶段&#xff1a;需求分析需求规格说明书、产品原型一般来说…

再见 Xshell替代工具Tabby

替代Xshell 之前经常使用Xshell来操作Linux虚拟机&#xff0c;基本上是够用了。但是Xshell免费使用只供非商业用途&#xff0c;而且如果你想用FTP来进行文件传输的话&#xff0c;还需单独下载Xftp。 无意中发现了另一款开源的终端工具Tabby&#xff0c;它直接集成了SFTP功能&…

smartbi token回调获取登录凭证漏洞

前段时间&#xff0c;Smartbi官方修复了一处权限绕过漏洞。未经授权的攻击者可利用该漏洞&#xff0c;获取管理员token&#xff0c;完全接管管理员权限。于是研究了下相关补丁并进行分析。 0x01分析结果 依据补丁分析&#xff0c;得到如下漏洞复现步骤 第一步&#xff0c;设…