vue 中的slot 和 mixins

更新日期: 2019-07-06阅读: 2.3k标签: slot

前言

vue 为我们提供了很多复用性的方式,slot 和 mixins 就是其中两种...下面对这两种方式做一下记录


插槽使用场景

- 该组件被多个地方使用
- 每个父组件中对该组件的内部有一部分需要特殊定制
- slot可以让我们更好的复用组件的同时并对其定制化处理
- 可以理解为父组件想子组件传递了一段 html 文本
要求:
    1.子组件模板包含至少一个 插槽 <slot></slot>
    2.父组件整个内容片段将插入到 slot 所在的 dom 位置,并替换掉 slot 标签本身


1.普通插槽 slot

父组件: 负责分发插槽内容
        <child ref=child>
            我是父组件分发给 child 的所有内容
        </child>
        父组件获取子组件可以通过 this.$refs.child 来做操作

子组件:  <template>
            <slot>这里可以放一些默认值</slot>
        </template>
        模板中放置一个 <slot></slot>组件,
        我们可以自定义组件中的方法和数据,封装一些通用逻辑,比如前几篇中封装的 scroll滚动组件


2.具名插槽 子组件通过 name 属性 来匹配父组件分发的内容

父组件: 添加 slot 属性来作为标识
        <div slot="header">我是 header 分发的内容 111</div>
        <div slot="main">我是 main 分发的内容222</div>
        <div slot="footer">我是 footer 分发的内容333</div>

      在2.6.0 以上使用的是 v-slot:header; 默认插槽为: v-slot:default

子组件: slot 添加 name 属性来接受父组件分发的 DOM 元素
        <template>
            <slot name="header"></slot>
            <slot name="main"></slot>
            <slot name="footer"></slot>
        </template>
    当然,我们还可以调换插槽的位置...


3.作用域插槽 父组件可以接收来自子组件的 slot 传递过来的参数值

可以理解为: 子组件中的作用域插槽可以为父组件中的插槽的展示提供数据

子组件:
    <template>
        <div>
            <slot name="header" :value="value"></slot>
        </div>
    </template>
    <script>
        export default {
            data() {
                return {
                    value: '我是子组件的值'
                }
            }
        }
    </script>

父组件:
    <child>
        <template slot="header" slot-scope="slotHeaderProps">
            渲染子组件传过来的对象中 value值{{ slotHeaderProps.value }}
        </template>
    </child>

    在 2.6 以上绑定值的方式: v-slot:header="slotHeaderProps"
    而且可以使用解构 v-slot:header="{value}", 将子组件传过来的值解构

    还有就是, 我们可以把 slot直接写在子组件行内, 不必另起一个 template
    即这样: <child v-slot:header="{value}">{{value}}</child>

vue3.0以后 slot 和 slot="xxx",slot-scope 的方式会被废弃...新的用法slot, v-slot:xxx || v-slot:default, v-slot:xxx="slotProps"


混入 Mixins 使用

- 也是为了实现代码逻辑复用
- 当多个组件中出现业务逻辑重复时我们就可以抽离重复代码片段,写成一个混入对象
- 父组件直接引入这个对象


代码演示

就拿一个比较常见的场景: 下拉加载更多数据; 这类业务在H5端可以说是非常常见了,当我们很多页面都要用到时,就可以抽离成一个混入对象

// 滚动加载
import {throttle} from "@/common/js/tool";

export const scrollMixin = {
  methods: {
    doScrollLoading() {
      // 滚动超出高度
      let scrollTop =
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop;
      // 滚动区域高度
      let scrollHeight =
        document.body.scrollHeight || document.body.scrollHeight;
      // 可视区高度
      let clientHeight =
        document.documentElement.clientHeight || document.body.clientHeight;

      if (scrollHeight - clientHeight - scrollTop <= this.bottomHeight) {
        // 组件中需加入开关和加载更多; 还是有些耦合了...
        if (!this.isLoadMore) {
          this.loadMore();
        }
      }
    }
  },
  computed: {
    bottomHeight() {
      return this.$store.state.footerHeight;
    }
  },
  mounted() {
    window.addEventListener("scroll", throttle(this.doScrollLoading, 100, 1));
  },
  destroyed() {
    window.removeEventListener("scroll", throttle(this.doScrollLoading, 100, 1));
  }
}

父组件中引入使用

import { scrollMixin } from "@/mixins/scrollMixin";
mixins: [scrollMixin]

注意组件中重写的方法会覆盖混入中的方法,loadMore和 isloadMore 需要在
引用的组件中进行重写

链接: https://fly63.com/article/detial/4030

Vue.js的组件中的slot和props

props是用来接收参数的 例如父组件向子组件传参 可以放在props中;插槽 slot分发模式主要用于在组件中插入标签或者组件之间的相互嵌套,个人认为如果组件中有需要单独定义的地方可以使用slot

Vue slot插槽

插槽用于内容分发,存在于子组件之中。插槽作用域:父级组件作用域为父级,子级组件作用域为子级,在哪定义的作用域就在哪。子组件之间的内容是在父级作用域的,无法直接访问子组件里面的数据。

vue2.6中slot的新用法

最近发布不久的Vue 2.6,使用插槽的语法变得更加简洁。 对插槽的这种改变让我对发现插槽的潜在功能感兴趣,以便为我们基于Vue的项目提供可重用性,新功能和更清晰的可读性。 真正有能力的插槽是什么?

vue使用slot分发内容与react使用prop分发内容

vue将 <slot> 元素作为承载分发内容的出口,当组件渲染的时候,<slot></slot> 将会被替换该组件起始标签和结束标签之间的任何内容

让你的组件千变万化,Vue slot 剖玄析微

Vue 代码中的 slot 是什么,简单来说就是插槽。 <slot> 元素作为组件模板之中的内容分发插槽,传入内容后 <slot> 元素自身将被替换。看了上面这句官方解释,可能一样不知道 slot 指的是什么

高级 Vue 技巧:控制父类的 slot

首先来思考一个问题:是否有一种方法可以从子组件填充父组件的插槽?最近一位同事问我这个问题,答案很简单:可以的。但我的解决方案可能和你想的完全不一样,这是涉及一个棘手的Vue架构问题

Vue3中插槽(slot)用法汇总

Vue中的插槽相信使用过Vue的小伙伴或多或少的都用过,但是你是否了解它全部用法呢?本篇文章就为大家带来Vue3中插槽的全部用法来帮助大家查漏补缺。

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!