Hitsuki9's Blog.

Vue 知识点整理

字数统计: 931阅读时长: 4 min
2019/10/01 Share

组件通信

父组件 => 子组件

属性 props

1
2
3
4
5
6
7
// child
props: {
msg: String;
}

// parent
<HelloWorld msg="Welcome to Your Vue.js App" />;

特性 $attrs

1
2
3
4
5
// child 并未在 props 中声明 foo
<p>{{ $attrs.foo }}</p>

// parent
<HelloWorld foo="foo"/>

$attrs 包含了父作用域中不作为 prop 被传入的特性 (classstyle 除外),可以通过 v-bind="$attrs" 在内部组件中获取所有这些特性。

常与 inheritAttrs 配合使用,通过将 inheritAttrs 设置为 false 可使组件的根元素不继承传入的特性(classstyle 除外)。


引用 refs

1
2
3
4
5
6
// parent
<HelloWorld ref="parent"/>

mounted () {
this.$refs.parent.xx = 'xxx'
}

子元素 $children

1
2
// parent
this.$children[0].xx = 'xxx';

$children 是当前实例的直接子组件,但并不保证顺序,也不是响应式的

 

子组件 => 父组件

自定义事件

1
2
3
4
5
// child
this.$emit('add', good)

// parent
<Cart @add="cartAdd($event)"></Cart>

由谁派发的事件则由谁监听。

 

兄弟组件之间

通过共同的祖辈组件搭桥:$parent$root

1
2
3
4
5
// brother1
this.$parent.$on('foo', handle);

// brother2
this.$parent.$emit('foo');

 

祖先和后代组件之间

provide / inject

1
2
3
4
5
6
7
// ancestor
provide () {
return { foo: 'foo' }
}

// descendant
inject: ['foo']

通过 provideinject 绑定的值并不是可响应的,然而,如果传入了一个可监听的对象,那么其对象的属性还是可响应的。

 

任意两个组件

事件总线

创建一个 Bus 类来负责事件的派发、监听与回调管理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Bus {
constructor() {
this.callbacks = {};
}
$on(name, fn) {
this.callbacks[name] = this.callbacks[name] || [];
this.callbacks[name].push(fn);
}
$emit(name, args) {
if (this.callbacks[name]) {
this.callbacks[name].forEach((cb) => cb(args));
}
}
}

// main.js
Vue.prototype.$bus = new Bus();

// child1
this.$bus.$on('foo', handle);

// child2
this.$bus.$emit('foo');

实践中可以用 Vue 代替 Bus,因为它已经实现了相应功能。


Vuex

创建唯一的全局数据管理者 store,通过它来管理数据并通知组件变更状态。

 

插槽

插槽语法是 Vue 实现的内容分发 API。

匿名插槽

1
2
3
4
5
6
7
<!-- comp1 -->
<div>
<slot></slot>
</div>

<!-- parent -->
<comp>hello</comp>

具名插槽

将内容分发到子组件的指定位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- comp2 -->
<div>
<slot></slot>
<slot name="content"></slot>
</div>

<!-- parent -->
<Comp2>
<!-- 默认插槽用 default 做参数 -->
<template v-slot:default>具名插槽</template>
<!-- 具名插槽用插槽名做参数 -->
<template v-slot:content>内容...</template>
</Comp2>

作用域插槽

分发的内容需要用到子组件中的数据。

1
2
3
4
5
6
7
8
9
10
11
12
<!-- comp3 -->
<div>
<slot :foo="foo"></slot>
</div>

<!-- parent -->
<Comp3>
<!-- 把 v-slot 指定的值指定为作用域上下文对象 -->
<template v-slot:default="slotProps">
来自子组件的数据:{{ slotProps.foo }}
</template>
</Comp3>

 

双向绑定
v-model 语法糖 value 和 @input
.sync

 

vue-router
hash/history

install => {
挂载$router
注册组件
}

router => {
解析路由配置
监听 hashchange 事件
响应 url 变化
组件切换
}

创建 Router 类

  • 解析 routes 配置,生成 map
  • 监听 url 变化
  • 声明,注册组件 router-link router-view
    实现插件
  • 挂载$router

vuex
模块化
namespace

实现 Store 类

  • state 响应化处理
  • 保存状态,实现 dispatch,commit
    实现插件
  • 挂载$store

Vue SSR
SPA 请求次数多 => 首屏渲染速度慢
SEO 不友好

客户端发送请求 => 服务端将 vue 模板解析成 html(包含首屏所有需要的异步数据) => 返回给浏览器进行首屏渲染 => 同时转换为 SPA

缺点: 1.开发条件受限,例如 mouted 生命周期函数无法使用 2.服务端负载变大

CATALOG
  1. 1. 组件通信
    1. 1.1. 父组件 => 子组件
      1. 1.1.1. 属性 props
      2. 1.1.2. 特性 $attrs
      3. 1.1.3. 引用 refs
      4. 1.1.4. 子元素 $children
    2. 1.2. 子组件 => 父组件
      1. 1.2.1. 自定义事件
    3. 1.3. 兄弟组件之间
    4. 1.4. 祖先和后代组件之间
    5. 1.5. 任意两个组件
      1. 1.5.1. 事件总线
      2. 1.5.2. Vuex
  2. 2. 插槽
    1. 2.1. 匿名插槽
    2. 2.2. 具名插槽
    3. 2.3. 作用域插槽