当前位置:   article > 正文

组件插槽,vue自定义指令,$ref使用(获取DOM对象 或 组件对象), $nextTick使用,组件使用v-model(v-model底层原理)_如何获得插槽中的dom

如何获得插槽中的dom

1.1-插槽slot使用

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

官网文档:

通过插槽分发内容

插槽后备内容

插槽使用2个步骤

第一步:在组件中定义一个插槽 <slot>默认值:如果父组件没有传递则默认显示</slot>

第二步:在组件中传递结构: <子组件>父组件需要传递的结构</子组件>

  1. 插槽的作用是什么让父组件传递什么到子组件中?

    html结构

  2. 插槽的默认值写哪里?

    <solt>默认值</slot>

1.2-具名插槽

具名插槽语法如下

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

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

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

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

vue中并不是所有的指令都能简写,有简写符号的指令主要有三个

v-on 指令 可以简写成 @

v-bind指令 可以简写成 :

v-slot指令 可以简写成 #

1.3-作用域插槽

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>

作用域插槽基本使用

02-vue自定义指令

  • 官方文档:自定义指令 — Vue.js

  • 1.复习指令作用 : 给标签添加额外的功能

  • 2.复习指令本质 : 行内自定义属性

  • 3.自定义指令作用 : 给标签添加 vue没有的,额外的功能

1.1-自定义指令:局部注册

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

  • 需求:

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

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

  1. <template>
  2. <div>
  3. <!-- 使用指令 v-指令名 -->
  4. <input type="text" v-focus />
  5. <br />
  6. <input type="text" v-red />
  7. <p v-red>我是p标签,我使用了自定义指令v-red</p>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. data() {
  13. return {}
  14. },
  15. //自定义指令都写在这个对象里面
  16. directives: {
  17. //1.指令名: focus
  18. focus: {
  19. // inserted(el) : 当指令被使用的时候会执行一次
  20. // update(el) : 当指令所在的组件虚拟dom变化的时候执行(不常用)
  21. inserted(el) {
  22. //el : 你的指令写在哪一个标签上,这个el就是标签dom对象
  23. el.focus()
  24. }
  25. },
  26. //2.指令名: red
  27. red: {
  28. inserted(el) {
  29. el.style.color = "red"
  30. }
  31. }
  32. }
  33. }
  34. </script>
  35. <style></style>

1.2-自定义指令:全局注册

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

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

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

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

  • 官方文档:https://cn.vuejs.org/v2/api/#vm-refs

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

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

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

1.1-ref用于标签

ref语法使用流程语法

(1)给标签添加自定义属性red :<button ref="属性名"></button>

  • vue会自动把页面所有的ref属性,挂载到vue实例的$ref对象中

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

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

ref易错点

1.添加的的时候是: ref

2.获取的时候是: $refs

ref.vue

  1. <template>
  2. <div>
  3. <button ref="btn">按钮</button>
  4. <p ref="p1">p标签</p>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. data() {
  10. return {}
  11. },
  12. created() {
  13. //这个勾子只是完成data数据初始化,并没有渲染真实dom。因此无法获取标签
  14. console.log(this.$refs)
  15. },
  16. mounted() {
  17. //这个勾子完成初始dom渲染,也是最早能获取页面dom元素的勾子
  18. console.log(this.$refs)//{ btn:按钮标签 , p1:p标签 }
  19. console.log(this.$refs.btn)//button标签dom对象
  20. console.log(this.$refs.p1)//p标签dom对象
  21. },
  22. }
  23. </script>
  24. <style></style>>

App.vue

  1. <template>
  2. <div>
  3. <ref></ref>
  4. </div>
  5. </template>
  6. <script>
  7. //导入局部组件
  8. import ref from "./components/ref.vue"
  9. export default {
  10. data() {
  11. return {}
  12. },
  13. components: {
  14. ref
  15. },
  16. }
  17. </script>
  18. <style>
  19. </style>

1.2-ref用于组件

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

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

ref设置给不同的标签,获取到的东西是不同的。 1.如果设置给dom元素(html标签),则获取的是dom元素对象 2.如果设置给组件(组件也是一个标签),则获取的是组件vue实例对象 官方文档:访问子组件或子元素

 

04-$nextTick使用

$nextTick工作原理官方文档:深入响应式原理 — Vue.js

需求: 点击搜索按钮, 弹出聚焦的输入框, 按钮消失

  1. <template>
  2. <div>
  3. <input ref="myInp" type="text" placeholder="这是一个输入框" v-if="isShow">
  4. <button v-else @click="btn">点击我进行搜索</button>
  5. </div>
  6. </template>
  7. <script>
  8. // 目标: 点按钮(消失) - 输入框出现并聚焦
  9. // 1. 获取到输入框
  10. // 2. 输入框调用事件方法focus()达到聚焦行为
  11. export default {
  12. data(){
  13. return {
  14. isShow: false,
  15. }
  16. },
  17. methods: {
  18. async btn(){
  19. this.isShow = true;
  20. /* 1.以下代码无法实现输入框聚焦
  21. 原因: data变化更新DOM是异步的,输入框还没有挂载到真实DOM上
  22. */
  23. // this.$refs.myInp.focus()
  24. /* 2.解决方案:使用$nextTick
  25. (1) $nextTick是一个异步微任务,等待当前函数的dom渲染结束后执行
  26. (2) $nextTick类似于一个非常高级的定时器,自动追踪DOM更新,更新好了就触发
  27. */
  28. // this.$nextTick(() => {
  29. // this.$refs.myInp.focus()
  30. // })
  31. /* 3.拓展: await异步函数
  32. 原因: $nextTick() 返回的是一个Promise对象(底层基于promise)
  33. */
  34. await this.$nextTick()
  35. this.$refs.myInp.focus()
  36. }
  37. }
  38. }
  39. </script>

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

官网文档:组件使用v-model

语法:

  1. 子组件中

    1. props定义value的属性

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

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/133953
推荐阅读
相关标签
  

闽ICP备14008679号