父传子
传递静态或动态 Prop
<!-- 传入静态值 -->
<blog-post title="hai hai hai"></blog-post>
<!-- 传入变量值 -->
<blog-post :title="info.title"></blog-post>
传入一个对象的所有 property
数据
post: {
id: 1,
title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>
<!-- 等价于 -->
<blog-post
v-bind:id="post.id"
v-bind:title="post.title"
></blog-post>
props接收
- 数组形式
props: ['propA', 'propB']
- 对象形式
Vue.component('my-component', {
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' }
}
//箭头函数语法,括号()内为js表达式,即return返回的值
//default: ()=>({message: 'hello'})
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].includes(value)
}
}
}
})
- Object,Array,Function类型的默认值default为函数形式
非 Prop 的 Attribute
父组件传递的属性,子组件并没有相应prop去接收
默认这些 attribute 会被添加到这个子组件的根元素上
例如:id、class、style等属性,子组件没有显示的用props接收
父组件传递数据:
<HelloWorld :name="name" :age="age" :test="123"></HelloWorld>
子组件接收数据:
没有props接收test,故test为非Prop的Attribute,默认test添加到子组件的根元素上
<template>
<div class="outer">
<div class="box">
<div>
<h1>{{ name }}</h1>
<h1>{{ age }}</h1>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
name: {
type: String,
default: 'none'
},
age: {
type: Number,
default: 0
},
}
}
</script>
指定Attribute绑定的元素
<template>
<div class="outer">
<div class="box">
<div>
<!-- 指定Attribute绑定的元素 -->
<h1 :test="$attrs.test">{{ name }}</h1>
<h1>{{ age }}</h1>
</div>
</div>
</div>
</template>
<script>
export default {
//禁用 Attribute继承
inheritAttrs:false,
props: {
name: {
type: String,
default: 'none'
},
age: {
type: Number,
default: 0
},
}
}
</script>
单向数据流
单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。(子组件不能修改prop)
- 对象和数组是通过引用传入的,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。
子传父
<template>
<div>
<button @click="handleClick(1)">+1</button>
<button @click="handleClick(2)">+2</button>
<button @click="handleClick(3)">+3</button>
</div>
</template>
<script>
export default {
// 1.自定义事件的声明
// 方式1 数组
// emits: ['add'],
// 方式2 对象(参数验证)
emits: {
add: function (payload) {
// add的值<=1时,抛出事件add
return payload <= 1 ? true : false
},
},
methods: {
handleClick(num) {
// 2.抛出自定义事件add
this.$emit('add', num)
},
},
}
</script>
<template>
<div>
<h1>{{ count }}</h1>
<!-- 1.监听自定义事件add -->
<hello-world @add="handleAdd"></hello-world>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue';
export default {
components: { HelloWorld },
data() {
return {
count: 0
}
},
methods: {
// 2.实现自定义事件add的回调函数
handleAdd(num) {
this.count += num
},
},
}
</script>
插槽
Vue插槽
provide与inject
变为响应式数据:computed函数
全局事件总线
使用第三方库mitt,tiny-emitter
mitt
$refs
获取具有ref属性的所有DOM元素和组件实例
App.vue
<template>
<div>
<h1 ref="h1Ref">{{ msg }}</h1>
<A ref="ARef"></A>
</div>
</template>
<script>
import A from '@/components/A.vue'
export default {
data() {
return {
msg: 'hi'
}
},
components: { A },
mounted() {
// 获取DOM元素
console.log(this.$refs.h1Ref);
// 获取组件
console.log(this.$refs.ARef);
// 获取组件的根元素 this.$refs.ARef.$el
// 多个根元素时,可以通过DOM方法获取到指定根元素
console.log(this.$refs.ARef.$el.nextSibling);
},
}
</script>
<style scoped></style>
A.vue
<template>
<div>
<h1>{{ msg }}</h1>
</div>
<div>123</div>
</template>
<script>
export default {
data() {
return {
msg: 'A'
}
}
}
</script>
vuex、pinia
vuex知识点
pinia知识点
路由传值
本地存储
总结
- 父传子,父组件传递属性(静态或动态(v-bind绑定)),子组件通过
props
接收 - 子传父,子组件使用
$emit
抛出自定义事件,父组件v-on监听自定义事件并实现回调函数 - 插槽
- 父组件
provide
提供数据,子孙组件inject
注入数据 - 通过全局事件总线
eventBus
进行跨组件值传递 - 通过
$ref
$parent
和$chidren
获取实例进而通信 - 通过
vuex、pinia
进行状态管理
- 路由传值
- localStorage、sessionStorage