Day33:vue入门3-自定义指令、计算监听属性深入

1.vue自定义指令

概念

自己模拟vue官方实现一个指令

作用

对原生指令的补充和扩展,可以用于定义任何dom操作,并且可以复用

分类

全局自定义指令,可以供整个页面使用

局部自定义指令,只作用于它定义的那个vue实例,

语法

全局自定义指令(绑定到vue上)

Vue.directive('指令名称', 处理函数)

Vue.directive('focus', {
  // 当绑定元素插入到 DOM 中。
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
  // 创建根实例
  new Vue({
    el: '#app'
  })

局部自定义指令(绑定到vue实例上)

new Vue({el:'#app',directives:{指令名称,处理函数}})

new Vue({
  el: '#app', // app绑定了,app1没绑定
  directives: {
    // 注册一个局部的自定义指令 v-focus
    focus: {
      // 指令的定义
      inserted: function (el) {
        // 聚焦元素
        el.focus()
        el.style.color = 'red' // 局部属性,只对绑定的vue实例服务
      }
    }
  }
})

全局属性,每个vue实例都可以共用

局部属性,只对绑定的vue实例服务

钩子函数

钩子函数为在特定事件或者是条件发生的时候被调用的函数

指令定义函数提供了几个钩子函数(可选):

  • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
  • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
  • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
  • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
  • unbind: 只调用一次, 指令与元素解绑时调用。

练习:传参数改变样式

<div id="app">
  <h1 v-color="'blue'">albedo</h1> <!-- 把blue传到value中,所以传成字符串格式 -->
  <p v-color="'pink'">lily</p>

  <p v-size="'100'">China</p><!-- 100的单引号可以省略 -->
</div>
<script>
  new Vue({
    el: '#app',
    data: {

    },
    directives:{
      color(el,v){ // el代表添加了指令的元素
        console.log(v) 
        // v其实是对象,传递的颜色在value中
//{name: 'color', rawName: 'v-color', value: 'blue', expression: "'blue'", }
        el.style.color = v.value
      },
      size(el,v){
        el.style.fontSize = v.value + 'px'
      }
    }
  })

2.computed计算属性深入

计算属性有两个函数,get用来获取,set用来设置,这里必须用计算属性完整写法

get函数是获取计算属性的值

set函数是设置计算属性的值

完整格式

computed:{属性名:{get(){语句体},set(){语句体}}}

如果只用get函数

computed:{属性名:{方法体}}

<div id="app">
  <input type="text" v-model="firstName"><br>
  <input type="text" v-model="lastName"><br>
  <input type="text" v-model="fullName">
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      firstName:'张',
      lastName:'三',
      fullName:'张三'
    },
    /* 其实计算属性有两个函数,get用来获取,set用来设置,这里必须用计算属性完整写法 */
    computed:{
      /* fullName(){
        return this.firstName + this.lastName
      } */
      fullName:{
        // get函数是获取计算属性的值
        get(){
          return this.firstName + this.lastName
        },
        // set函数是设置计算属性的值
        set(value){
          console.log(value) // 代表你输入的内容(文本框的值)
          this.firstName = value.slice(0,1) // 截取
          this.lastName  = value.slice(1) // 从索引为1的地方截取到尾
        }
      }
    }
  })

3.watch监听属性深入

获取新旧值

想获取新旧值,只需要在函数中添加两个参数,第一个参数代表新值,第二个参数代表旧值(默认使用新值)

watch:{
  firstName(newValue,oldValue){  // 接收的两个第一个是新值,第二个是旧值
    console.log(newValue)
    console.log(oldValue)
    this.fullName = this.firstName + this.lastName
  },
  lastName(newValue,oldValue){
    console.log(newValue)
    console.log(oldValue)
    this.fullName = this.firstName + this.lastName
  }
}
监听属性和计算属性的区别

计算属性需要返回数据,在异步操作中不能实现数据的返回

监听属性不需要返回数据,可以用在异步操作中

计算属性弊端

无法处理异步逻辑,比如定时器等

监听属性没有return,可以实现异步需要

定时器里需要用箭头函数,箭头函数中的this代表了vue对象,而普通函数中的this代表window

watch:{
  firstName(){ 
    setTimeout(() => {
      console.log(this.firstName) // this应该是vue对象
      this.fullName = this.firstName + this.lastName
    },3000)
  },
  lastName(){
    setTimeout(() => {
      console.log(this.lastName) // this应该是vue对象
      this.fullName = this.firstName + this.lastName
    },3000)
  }
}

深度监听

完整格式

watch:{属性名:{handler(newValue,oldValue){函数体},immediate:true,deep:true)}}

<div id="app">
    <button  @click="count++">按钮</button>
    <h1 v-show="show">新中地</h1>
</div>
<script>
    new Vue({
        el: '#app', // 设置vue接管的区域
        data: {
            show: false,// 没有对初始值进行监听
            count:0
        },
        watch: {  // 监听原始数据,当count值发生改变,执行对应操作
            count() {
                if (this.count%2 == 0) {
                    this.show = false
                } else {
                    this.show = true
                }
            }
        }
    })
立即监听

正常情况下应该是显示,此处没有显示,因为监听器只在变化的时候监听,没有监听到初始值0

采用监听器完整写法进行监听,在其中使用immediate属性,进行立即监听——设置immediate属性为true,他就可以在页面加载完成后,执行handler函数

简写形式,无法设置其他属性

完整形式,可以设置属性(handler:属性值发生改变会触发的函数)

深度监听

将count的值使用对象{number:0}来表示,则普通监听只能在表面监听到count,无法深度监听到内部的number

解决方式1:将监听对象换成count.number

弊端:如果count里面有很多属性,难以监听

解决方式2:使用deep属性开启深度监听

watch: {
  count: {
    handler: function () {
      if (this.count % 2 == 0) {
        this.show = true
      } else {
        this.show = false
      }
    },
    immediate : true
    // 开启深度监听
    deep:true
  }
}
  1. 普通监听:直接监听
  2. 有初始值的监听:immediate : true
  3. 深度监听:deep:true

4.filter过滤属性

概念

提供管道服务,对数据进行过滤(vue3已废弃)

语法

filters:{函数名或过滤器名(参数){默认第一个参数就是要处理的字符串}}

<div id="app">
  <h1>{{msg | toUp}}</h1> <!-- 内容  管道  过滤器 -->
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      msg:'xzd'
    },
    filters: { /* 过滤属性 */
      toUp(e){ 
        console.log(e) // 代表xzd
        return e.toUpperCase() // 变成大写
      }
    }
  })

5.全局方法和实例方法

概念

Vue 不能检测到对象属性的添加或删除,最好的方式就是在初始化实例前声明根级响应式属性,哪怕只是一个空值。

如果我们需要在运行过程中实现属性的添加或删除,则可以使用全局 Vue,Vue.set 和 Vue.delete 方法。

Vue.set

Vue.set 方法用于设置对象的属性,它可以解决 Vue 无法检测添加属性的限制,语法格式如下:

Vue.set( target, key, value )

this.$set(target, key, value)

  • target: 可以是对象或数组
  • key : 可以是字符串或数字
  • value: 可以是任何类型

Vue.set可以简写为this.$set,其中的this指向的就是new Vue

删除

this.$delete(target, key)

<div id="app">
  <button @click="add()">添加属性</button>
  <button @click="del()">删除属性</button>
  <p>{{stu.name}}</p>
  <p>{{stu.age}}</p>
  <p>{{stu.gender}}</p>
  <p>{{stu.height}}</p>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      stu:{
        name:'zc',
        age:23,
        gender:'male'
      },
    },
    methods: {
      // 实现添加属性的方法
      add(){
        // Vue.set(this.stu,'height',180) // 静态方法
        this.$set(this.stu,'height',180) // 实例方法
      },
      // 实现删除属性的方法
      del(){
        this.$delete(this.stu,'age')
      }
    }
  })

<div id="app">
  <ul>
    <li v-for="item in num">{{item}}</li>
  </ul>
  <button @click="sortN()">排序数字</button>
  <button @click="reverseN()">翻转顺序</button>
  <button @click="filteN()">过滤小于8的值</button>
  <button @click="subN()">截取前4个值</button>
  <button @click="updateN()">修改第一个值</button>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      num:[3, 15, 10, 1, 19, 32, 20]
    },
    methods: {
      sortN(){
        this.num.sort((a , b) => a - b)
      },
      reverseN(){
        this.num = this.num.reverse()
      },
      filteN(){
        this.num = this.num.filter((num) => num > 8)
      },
      subN(){
        this.num = this.num.slice(0 , 3)
      },
      updateN(){
        this.$set(this.num , 0 , 188)
      },
    }
  })

数组push(),pop(),shift(),unshift(),splice(),sort(),reverse()会触发数组的改变,v-for能监测到并更新

slice(),filter(),contact() 或者使用索引修改值,vue监测不到

需要使用Vue.set或者覆盖原数组才能实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值