Vue3官网-深入组件(七)父子组件、插槽(\<slot>、作用域插值、具名插槽缩写)、 Provide / Inject(响应式)、动态组件`keep-alive`、异步组件 `defineAsyn

Vue3官网-深入组件(七)父子组件、插槽(<slot>、作用域插值、具名插槽缩写)、 Provide / Inject(响应式)、动态组件keep-alive、异步组件 defineAsyncComponent

总结:

  • 补充

    • Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。

    • truthy(真值):在 JavaScript 中,truthy(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除 false0""nullundefinedNaN 以外皆为真值)。括号内都是假值falsy。

    • .prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()

    • ==Event.preventDefault方法取消浏览器对当前事件的默认行为。==比如点击链接后,浏览器默认会跳转到另一个页面,使用这个方法以后,就不会跳转了;再比如,按一下空格键,页面向下滚动一段距离,使用这个方法以后也不会滚动了。该方法生效的前提是,事件对象的cancelable属性为true,如果为false,调用该方法没有任何效果。

    • vue:用组件(app.component)构建一个模板(template),并反复使用模板

    • 父组件、子组件

      • const app = Vue.createApp({
                  
          components: {
                  
            'component-a': ComponentA,
            'component-b': ComponentB
          }
        })
        
      • 上面代码中app为父组件,ComponentA和ComponentB为子组件

  • 插槽<slot> <todo-button>(内容分发),

    • 基础

      • Vue 实现了一套内容分发的 API,<slot> 元素作为承载分发内容的出口。

      • <!-- <todo-button>是内容分发API -->
        <todo-button>
          Add todo
        </todo-button>
        ------------------------------------------------------
        <!-- todo-button 组件模板,没有指定名字时就用默认的名字: class="btn-primary",并且<slot></slot>表示插入的内容所在的地方 -->
        <button class="btn-primary">
          <slot></slot>
        </button>
        
    • 作用域

      • 插槽可以访问与模板其余部分相同的实例 property (即相同的“作用域”)。不做操作的话父组件内容不能干涉到子组件内容,除非进行作用域插槽
      • 插槽不能访问 <todo-button> 的作用域。
      • 父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
    • 具名插槽(name,<template v-slot:>)v-solt缩写为#

      • <slot> 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:

      • <div class="container">
          <header>
            <slot name="header"></slot>
          </header>
          <main>
            <slot></slot>
          </main>
          <footer>
            <slot name="footer"></slot>
          </footer>
        </div>
        
      • 一个不带 name<slot> 出口会带有隐含的名字“default”。

      • 在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:

        <base-layout>
          <template v-slot:header>
            <h1>Here might be a page title</h1>
          </template>
        
    • 作用域插值(插槽prop)

      • 为了让插槽(在父组件中)内容能够访问子组件中才有的数据,(正常情况下父组件只能访问父组件,子组件只能访问子组件

      • 要使 item 可用于父级提供的插槽内容,我们可以添加一个 <slot> 元素并将其作为一个 attribute 绑定:

        绑定在 <slot> 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:

        <!--父组件-->
        <todo-list>
          <template v-slot:default="slotProps">
            <i class="fas fa-check"></i>
            <span class="green">{
                 { slotProps.item }}</span>
          </template>
        </todo-list>
        ----------------------------------------------
        <!--子组件-->
        <ul>
          <li v-for="( item, index ) in items">
            <slot :item="item"></slot>
          </li>
        </ul>
        
    • 具名插槽缩写 (v-slot:) 替换为字符 #

      • v-onv-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header

      • 和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:

        <!-- This will trigger a warning -->
        
        <todo-list #="{ item }">
          <i class="fas fa-check"></i>
          <span class="green">{
                 { item }}</span>
        </todo-list>
        
  • Provide / Inject

  • 当我们需要从父组件向子组件传递数据时,我们使用 props。有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。在这种情况下,如果仍然将 prop 沿着组件链逐级传递下去,可能会很麻烦。

  • 我们可以使用一对 provideinject。无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。这个特性有两个部分:父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这些数据。

  • 访问组件实例 property

    • 如果我们尝试在此处 provide 一些组件的实例 property,这将是不起作用的:

       provide: {
              
          todoLength: this.todos.length // 将会导致错误 `Cannot read property 'length' of undefined`
        },
      
    • 要访问组件实例 property,我们需要将 provide 转换为返回对象的函数

      provide() {
              
          return {
              
            todoLength: this.todos.length
          }
      
  • 响应式

    • 如果我们想对祖先组件中的更改做出响应,我们需要为 provide 的 todoLength 分配一个组合式 API computed property:

      app.component('todo-list', {
              
        // ...
        provide() {
              
          return {
              
            todoLength: Vue.computed(() => this.todos.length)
          }
        }
      })
      
  • 动态组件&异步组件

    • 动态组件keep-alive
      • 曾经在一个多标签的界面中使用 is attribute 来切换不同的组件
      • 如果你选择了一篇文章,切换到 Archive 标签,然后再切换回 Posts,是不会继续展示你之前选择的文章的。这是因为你每次切换新标签的时候,Vue 都创建了一个新的 currentTabComponent 实例。
      • 那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。
    • 异步组件 defineAsyncComponent
      • 在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。

1. 插槽<slot> <todo-button>

该页面假设你已经阅读过了

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChrisP3616

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值