【Vue】组件插槽;vue自定义指令;$ref使用(获取DOM对象或者组件对象);$netTick使用

目录

组件插槽

插槽slot使用

具名插槽

作用域插槽

vue自定义指令

自定义指令:局部注册

自定义指令:全局注册

$ref使用(获取DOM对象或者组件对象)

ref用于标签

ref用于组件

$netTick使用

组件使用v-model(v-model底层原理


组件插槽

插槽slot使用

插槽作用: 组件 传递 结构组件

🏆插槽使用2个步骤

第一步:在组件中定义一个插槽

<slot>默认值:如果父组件没有传递则默认显示</slot>

第二步:在组件中传递结构:

<子组件>父组件需要传递的结构</子组件>

    <goods>
      <button disabled>已卖完</button>
    </goods>

插槽本质:html结构的替换

具名插槽

  • 💎1.匿名插槽作用: 父组件 传递一个整个html结构 给子组件

    • 给所有slot分发相同内容

  • 💎2.具名插槽作用: 父组件 传递多个html结构 给子组件

    • 给不同slot分发不同内容

具名插槽语法如下

1.给子组件的<slot>添加name属性 : name="插槽名"

2.父组件使用v-slot:插槽名 : 给指定的插槽传递结构

  • 注意这个v-slot指令必须要写在<template>标签中,否则会报错

  • <template>是HTML5新增的一个语义化标签,模板的意思。 这个标签本身不会被渲染,因此最终在页面是看不见的。 这个标签类似于div,就是一个空盒子容器。 与div唯一的区别就是它不会渲染。

父组件template中使用v-slot的方法

具体写法

v-slot:插槽name名

      <template v-slot:a>
        <span>content组件插槽</span>
      </template>

简明写法

#插槽name名

      <template #a>
        <span>content组件插槽</span>
      </template>

父组件部分:

子组件部分:

 

作用域插槽

1.插槽与props的异同点

相同点: 都是父传子

不同点:

props: 传递的是数据

插槽:传递的是html结构

2.作用域插槽和$emit异同点

相同点:都是子传父

不同点:

$emit : 子传父的数据通过事件来接收

作用域插槽:子传父的数据是通过插槽v-slot接收 (子传父的数据,只能给插槽用)

  • 1.插槽作用:父组件 传递 html结构 给 子组件

  • 2.具名插槽作用:父组件 传递 多个html结构 给 子组件

  • 3.作用域插槽作用:父组件 给 子组件 传递插槽 时,可以使用子组件内部的数据

作用域插槽语法如下

1.给子组件的<slot>添加一个自定义属性 :

<slot :属性名="属性值" ></slot>

2.给父组件的<template>添加v-slot属性接收数据:

<template v-slot="对象名"></template>

父组件使用子组件内部数据语法: 对象名.属性名

注意点 : 不要把 具名插槽语法作用域插槽 语法搞混淆

具名插槽:

<template v-slot:name值></slot>

作用域插槽:

<template v-slot="对象名"></slot>

🏆作用域插槽本质: 子组件把自己当前数据 传递给 父组件插槽 。

  • 只能父组件插槽内部使用,而不是任何地方都能用。作用域一词因此而来

作用域插槽和具名插槽如何同时使用?

具名插槽:v-slot:body 简写:#body

作用域插槽:v-slot="scope"

如何同时使用:

v-slot:body="scope"

简写:#body="scope"

具名插槽和作用域插槽并存
(1)具名插槽语法:v-slot:插槽名
(2)作用域插槽:v-slot="对象名“
问题:两种语法都用到v-slot,而一个标签只能写一个
解决:
v-slot:插槽名=“对象名”
#插槽名=”对象名“

vue自定义指令

自定义指令:局部注册

  • 局部注册:只能在当前组件使用

  • 需求:

    • 1.添加一个自定义指令 v-focus,作用是让input表单自动聚焦

    • 2.添加一个自定义指令v-red,作用是设置标签文本颜色

自定义指令常用的三个钩子:

bind(){}:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

inserted(){}:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

update(){}:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

钩子函数参数

 (即 elbindingvnode 和 oldVnode)

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

语法:

写在directives中

directives: {
    //1.指令名:  focus
    '指令名': {
      // inserted(el) :  当指令被使用的时候会执行一次
      // update(el) : 当指令所在的组件虚拟dom变化的时候执行(不常用)
      inserted(el) {
        //el : 你的指令写在哪一个标签上,这个el就是标签dom对象
        el.focus()
      }
    },

      // inserted(el) :  当指令被使用的时候会执行一次
      // update(el) : 当指令所在的组件虚拟dom变化的时候执行(不常用)

<script>
export default {
  data() {
    return {}
  },
  //自定义指令都写在这个对象里面
  directives: {
    //1.指令名:  focus
    focus: {
      // inserted(el) :  当指令被使用的时候会执行一次
      // update(el) : 当指令所在的组件虚拟dom变化的时候执行(不常用)
      inserted(el) {
        //el : 你的指令写在哪一个标签上,这个el就是标签dom对象
        el.focus()
      }
    },
    
  }
}
</script>

自定义指令:全局注册

全局注册: 在main.js中注册,任何地方可用

  • 底层原理:挂载到Vue构造函数原型中

// 全局指令 - 到处"直接"使用
Vue.directive("focus", {
  inserted(el) {
    el.focus() // 触发标签的事件方法
  }
})

$ref使用(获取DOM对象或者组件对象)

ref作用:在vue中操作dom元素

  • vue不推荐我们直接操作dom。如果真的要在vue中操作dom,可以使用ref语法

    • 说人话 : vue不能直接操作dom,真的要操作也要按vue规定的语法来。(ref语法)

ref用于标签

ref语法使用流程语法

(1)给标签添加自定义属性ref :

<button ref="属性名"></button>
  • vue会自动把页面所有的ref属性,挂载到vue实例的$ref对象中

(2)通过 vm.$refs.属性名 获取该标签

  • 一定要注意 : vue在mounted勾子中完成页面真实DOM渲染,所以最早能获取dom的就是mounted钩子

ref易错点

1.添加的的时候是: ref

2.获取的时候是: $refs

ref用于组件

组件在使用的时候,相当于是一个自定义标签

  • 因此:ref也可以用在组件上

ref设置给不同的标签,获取到的东西是不同的。

1.如果设置给dom元素(html标签),则获取的是dom元素对象

2.如果设置给组件(组件也是一个标签),则获取的是组件vue实例对象

$netTick使用

 1.以下代码无法实现输入框聚焦
            原因:Vue更新DOM是一个   异步微任务,输入框还没有挂载到真实DOM上
       this.$refs.input.focus()
            
 2.解决方案:使用$nextTick
            (1) $nextTick是一个异步微任务,等待当前函数的dom渲染结束后执行
            (2) $nextTick类似于一个非常高级的定时器,自动追踪DOM更新,更新好了就触发

      this.$nextTick(() => {
        this.$refs.input.focus();
      });

组件使用v-model(v-model底层原理)

v-model原理面试题

  • 1.高逼格答案: v-model本质就是 props:['value'] 和 $emit(input)的简写

  • 2.详细答案:v-model会做两件事 ( 父传子 + 子传父)

    • (1)把v-model绑定的值(v-model="值"), 通过props传递给组件的value

    • (2)监听组件input事件, 修改v-mode的值为 input事件的参数 $emit('input',事件参数)

语法:

  1. 子组件中

    1. props定义value的属性

    2. 数据改变的时候通过this.$emit('input',新的数据)

  2. 只要子组件满足上面的条件,父组件就可以直接简写为v-model

    1. v-model用于表单:快速获取/设置表单的值

    2. v-model用于组件:快速实现 props父传子 和 $emit子传父

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值