vue2-elm 和 node-elm 源码学习 (1): header

451 阅读2分钟

工程地址:


启动进入的是 home 页面,主要是以下几个模块: home页面组件 本篇先学习下header部分的代码。


<head-top signin-up='home'>
  <span slot='logo' class="head_logo"  @click="reload">ele.me</span>
</head-top>

针对这段代码有两个知识点, propslot。分别详细学习下。

prop

学习资料

定义方式

// 字符串数组形式列出
props: ['title', 'likes']

// 指定值类型 & 默认值 & 验证要求,以对象形式列出
props: {
  // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
  propA: Number,
  // 多个可能的类型
  propB: [String, Number],
  // 必填的字符串
  propC: {
    type: String,
    required: true
  },
  // 带有默认值的数字
  propD: {
    type: Number,
    default: 100
  },
  // 带有默认值的对象
  propE: {
    type: Object,
    // 对象或数组默认值必须从一个工厂函数获取
    default: function () {
      return { message: 'hello' }
    }
  },
  // 自定义验证函数
  propF: {
    validator: function (value) {
      // 这个值必须匹配下列字符串中的一个
      return ['success', 'warning', 'danger'].indexOf(value) !== -1
    }
  }
}

传递静态或动态

// 传递 数字,布尔,数组,对象都需要用 v-bind,用以和 string 区分。

// 传入一个对象的所有property,可以不用 v-bind
post: {
  id: 1,
  title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>

单向数据流

父级 prop 的更新会向下流动到子组件中,但是反过来则不行。

常见的两种子组件试图变更prop的情形和建议处理方式:

  1. prop传递初始值,子组件后续将其作为本地数据操作。
props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter	// 定义本地属性,然后prop作为初始值
  }
}
  1. prop传递原始值,子组件基于此转换。
props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
    // 最好定义计算属性来解决
  }
}

slot

学习资料

什么是插槽

官网的定义: 将 slot 元素作为承载分发内容的出口。 比较形象的理解:子组件定义了一个插座(slot), 父组件定义电器,即父向子传递。

v-slot 只能添加在 template 标签上。

后备内容(默认内容)

默认内容只会在没有提供内容的时候被渲染。

具名插槽 vs 匿名插槽

<!-- 子组件 -->
<header>
  <!-- 具名插槽 -->
  <slot name="header"></slot>
  <!-- 具名插槽的缩写 -->
  <template #header>
    <h1>Here might be a page title</h1>
  </template>
</header>
<main>
  <!-- 匿名插槽,带有隐含的名字“default” -->
  <slot></slot>
</main>

<!-- 父组件 -->
<template v-slot:header>
  <!-- 传入header插槽 -->
  <h1>Here might be a page title</h1>
</template>

<!-- 任何没有被包裹在带有 v-slot 的 <template> 中的内容都会被视为默认插槽的内容。 -->
<p>A paragraph for the main content.</p>
<p>And another one.</p>

<!-- 和上面的实现一样,只是更明确一些 -->
<!-- 也可以直接v-slot 不带参数的 v-slot 被假定对应默认插槽 -->
<template v-slot:default>
  <p>A paragraph for the main content.</p>
  <p>And another one.</p>
</template>

作用域插槽

插槽作用域里写的: 父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。 那怎样让插槽内容能够访问子组件中才有的数据?

<!-- 子组件 current-user.vue -->
<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

<!-- 父组件 -->
<current-user>
    <!-- 绑定在slot元素上的attribute称为插槽prop -->
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>