vue2.x
# 组件间通讯
- props 和$emit 父组件向子组件传递数据是通过 prop 传递的,子组件传递数据给父组件是通过$emit 触发事件来传递数据
// 父组件
<template>
<Acom :name="name" @getName="getName"></Acom>
</template>
<script>
import aaa from "./a.vue";
export default {
data() {
name: "xxx";
},
components: { aaa },
methods: {
getName(val) {
console.log(val); // xxx
},
},
};
</script>
// 子组件
<template>
<div>
a的内容
</div>
</template>
<script>
export default {
props: {
name: {
type: String,
default: "",
},
},
mounted() {
console.log(this.name);
},
methods: {
emitName() {
this.$emit("getName", name);
},
},
};
</script>
- $parent,$children 获取当前组件的父组件和当前组件的子组件
// 父组件 // 父组件中
<template>
<A></A>
<B></B>
</template>
<script>
export default {
mounted() {
// 通过$children可以获取到A和B两个子组件的实例
console.log("children:", this.$children);
},
};
</script>
// 子组件
<script>
export default {
mounted() {
console.log("parent:", this.$parent);
},
};
</script>
- $attrs 和$listeners A->B->C。解决深层组件间的通信(不推荐写深层组件)
// 父组件
<template>
<aaa :parentValue="parentValue" @getParentValue="getparentValue" />
</template>
<script>
import aaa from "./a.vue";
export default {
components: { aaa },
data() {
return {
parentValue: "appparentValue",
};
},
methods: {
getParentValue() {
console.log("parentValue,get");
},
},
};
</script>
// a组件
<template>
<div>
<bbb :cc="100" v-bind="$attrs" v-on="$listeners" />
</div>
</template>
<script>
import bbb from './b.vue'
export default {
mounted() {
console.log(this.$attrs, 'aaa', this.$listeners)
},
components: { bbb },
}
// b组件
<script>
export default {
mounted() {
console.log(this.$attrs, 'bbb', this.$listeners)
}
}
</script>
- 父组件中通过 provide 来提供变量,然后在子组件中通过 inject 来注入变量。
// 父组件
<script>
export default {
provide() {
return {
name: "jason",
};
},
};
</script>
// 后代组件
<script>
export default {
inject: ["name"],
};
</script>
$refs 获取组件实例
envetBus 兄弟组件数据传递
vuex 状态管理
# 插槽
# 内容插槽
// 父组件
<template>
<div>
<aaa >jason</aaa>
</div>
</template>
<script>
import aaa from "./a.vue";
export default {
components: { aaa }
}
</script>
// a.vue
<template>
<div>
<slot></slot>
</div>
</template>
当组件渲染的时候,<slot></slot>
会被替换为 jason
# 默认插槽(匿名插槽)
// 父组件
<template>
<div>
<aaa ></aaa>
</div>
</template>
<script>
import aaa from "./a.vue";
export default {
components: { aaa }
}
</script>
// a.vue
<template>
<div>
<slot>xxx</slot>
</div>
</template>
当组件渲染的时候,默认的内容为 xxx
# 内容,默认插槽一起
// 父组件
<template>
<div>
<aaa >save</aaa>
</div>
</template>
<script>
import aaa from "./a.vue";
export default {
components: { aaa }
}
</script>
// a.vue
<template>
<div>
<slot>submit</slot>
</div>
</template>
当组件渲染的时候,<aaa></aaa>
里边没有内容,显示的内容为submit,<aaa></aaa>
里边内容为save, 显示的内容为save
# 具名插槽
// 父组件
<template>
<div>
<aaa>
<template v-slot:header>
<h1>头部内容</h1>
</template>
<p>main标签里边的内容</p>
<template #footer>
<p>尾部内容</p>
</template>
</aaa>
</div>
</template>
<script>
import aaa from "./a.vue";
export default {
components: { aaa }
}
</script>
// a.vue
<template>
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
渲染结果:
头部内容
main标签里边的内容
尾部内容
注意: v-slot 只能添加在 <template>
上 具名插槽在书写的时候可以使用缩写,v-slot
用#
来代替
# 作用域插槽
解决的是父组件在向子组件插槽传递模板内容时存在访问子组件数据的问题
// 父组件
<template>
<div>
<aaa>
<template v-slot:default="slotProps">
<!-- slotProps= { "num": 100 } -->
{{slotProps}}
</template>
<template v-slot:xxx="slotProps">
<!-- slotProps = { "str": "jason" } -->
{{slotProps}}
</template>
</aaa>
</div>
</template>
<script>
import aaa from "./a.vue";
export default {
components: { aaa }
}
</script>
// a.vue
<template>
<div class="container">
<slot v-bind:num="100"></slot>
<slot name="xxx" v-bind:str="'jason'"></slot>
</div>
</template>
# vue 中修饰器
事件修饰符 .stop .prevent .capture .self .once .passive
按键修饰符 .enter .tab .delete (捕获“删除”和“退格”键) .esc .space .up .down .left .right
其他常用的修饰符 .trim .number .lazy .sync
# 函数式组件
函数式组件
: 只是接受一些 prop 的函数。在这样的场景下,我们可以将组件标记为 functional,这意味它无状态 (没有响应式数据),也没有实例 (没有 this 上下文)。
优点
:函数式组件只是函数,所以渲染开销也低很多。
Vue.component('my-component', {
functional: true,
// Props 是可选的
props: {
// ...
},
// 为了弥补缺少的实例
// 提供第二个参数作为上下文
render: function (createElement, context) {
// ...
}
})
单文件
<template functional>
<div class="wrap">
<div v-if="props.value">111</div>
<div v-else >222</div>
</div>
</template>
<script>
props: ['value']
</script>
场景
: 需要通过编程实现在多种组件中选择一种。