目录
3.跨层级组件通信
1.props
2.$emit/v-on
3..sync
4.v-model
5.ref
6.children/parent
7.attrs/listeners
8.provide/inject
9.EventBus
10.Vuex
11.$root
12.slot
这十二种可以分为三类
父组件 通过属性传值 , 子 props 接收
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>父组件向子组件传值--props</title>
- <script src="./js/vue.min.js"></script>
- </head>
- <body>
- <div id="app">
- <menu-item title="来自父组件的值"></menu-item>
- <!-- 在子组件身上绑定自定义属性来接收父组件data中的数据 -->
- <menu-item :tit="title"></menu-item>
- </div>
- <script>
- Vue.component('menu-item',{
- props:['tit'], //props用来接收父组件传过来的值
- //在props中使用驼峰形式,模版中要改为使用短横线拼接 props里面的值只读,不能修改
- //props是单向数据流
- data(){
- return{
- }
- },
- template:'{{tit}}'
- })
- var vm=new Vue({
- el:'#app',
- data:{
- title:'我是父组件中的数据'
- },
- methods:{
- }
- });
- </script>
- </body>
- </html>
子向父传值
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- </head>
- <body>
- <div id="app">
- <!-- 父组件 -->
- <div :style='{fontSize:fontSize+"px"}'>{{pmsg}}</div>
- <!-- 子组件 -->
- <menu-item :parr="parr" @aas="blune"></menu-item>
- </div>
- <script type="text/javascript" src="js/vue.js"></script>
- <script type="text/javascript">
- /*
- 子组件向父组件传值-基本用法
- props传递数据原则:单向数据流
- */
- Vue.component('menu-item', {
- props:['parr'],
- data(){
- return {
- msg1:'这是子组件传递过来的值'
- }
- },
- template: `
- <div>
- <ul>
- <li v-for="(item,index) in parr" :key="index">{{item}}</li>
- </ul>
- <button @click='dd'>扩大父组件中字体大小</button>
- </div>
- `,
- methods:{
- dd(){
- this.$emit("aas",this.msg1)
- }
- }
- });
- //$emit
- var vm = new Vue({
- el: '#app',
- data: {
- pmsg: '父组件中内容',
- parr: ['apple','orange','banana'],
- fontSize: 10
- },
- methods: {
- blune(message){
- this.fontSize+=5;
- console.log(message);
- }
- }
- });
- </script>
- </body>
- </html>
兄弟组件传值 事件总线
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- <script src="./js/vue.min.js"></script>
- </head>
- <body>
- <div id="app">
- <brother></brother>
- <sister></sister>
- </div>
- <script>
- var enveBus = new Vue();
- Vue.component('brother', {
- data() {
- return {
- kk: ''
- }
- },
- methods: {
- dd() {
- enveBus.$emit("bTs", '这是哥哥给妹妹的爱')
- }
- },
- template: `
- <div>
- <button @click='dd'>这是一个哥哥组件---{{kk}}</button>
- </div>
- `,
- mounted() {
- enveBus.$on('asd', (result) => {
- this.kk = result;
- })
- }
- });
- Vue.component('sister', {
- data() {
- return {
- sis: ''
- }
- },
- template: `
- <div>
- <button @click="cc">这是一个妹妹组件---{{sis}}</button>
- </div>
- `,
- mounted() {
- enveBus.$on('bTs', (message) => {
- this.sis = message
- })
- },
- methods: {
- cc() {
- enveBus.$emit('asd', '这是妹妹对哥哥的爱');
- }
- }
- });
- var vm = new Vue({
- el: '#app',
- data: {
- },
- methods: {
- }
- });
- </script>
- </body>
- </html>
跨组件 provide
- <script lang="ts" setup>
- // provide, inject
-
- import { provide } from 'vue';
-
- // provide(名字,值)
- const { separtor = '' } = defineProps<{
- separtor?: string
- }>()
-
- // 向后代传递值
- provide('separtor', separtor)
- </script>
- <template>
- <div class="xtx-bread">
- <slot></slot>
- </div>
- </template>
-
- <style scoped lang="less">
- .xtx-bread {
- display: flex;
- // padding: 25px 10px;
- &-item {
- a {
- color: #666;
- transition: all 0.4s;
- &:hover {
- color: @xtxColor;
- }
- }
- }
- i {
- font-size: 12px;
- margin-left: 5px;
- margin-right: 5px;
- line-height: 22px;
- }
- }
- </style>
inject
- <script lang="ts" setup>
- import { inject } from 'vue';
-
- // inject(名字)
- // 获取分隔符
- const separtor = inject('separtor')
-
- defineProps<{
- to?: string // 要跳转的位置
- }>()
- </script>
- <template>
- <slot> </slot>
- <div class="xtx-bread-item">
- <!-- 是否需要跳转 -->
- <router-link v-if="to" :to="to"><slot> </slot></router-link>
- <slot v-else> </slot>
-
- <!-- 分隔符从祖先来的 -->
- <i v-if="separtor">{{ separtor }}</i>
- <!-- 默认分隔符 -->
- <i v-else class="iconfont icon-angle-right"></i>
- </div>
-
- </template>
- <style lang="less" scoped>
- .xtx-bread-item {
- i {
- margin: 0 6px;
- font-size: 10px;
- }
- // 最后一个i隐藏
- &:nth-last-of-type(1) {
- i {
- display: none;
- }
- }
- }
- </style>
1.props 通过属性传值,子props接收
2.$emit/v-on 父组件使用子组件声明的自定义事件,传值时触发
3.v-model 原理即props与$emit;父:v-model="值"、子:this.$emit('input',值)
4..sync 原理即:属性名& this.$emit('update:属性名', 值)
5.refs 操作dom,通过this.$refs
6.$children/$parent this.$children获取所有子组件的数组对象,包括子组件的属性和监听事件; this.$parent获取父组件的对象,包括子组件的属性和监听事件;
7.$attrs / $listeners 读取到的只读(不可改): this.$attrs获取所有当前元素的属性(不包括:class、style、props传递给子的) this.$listeners获取所有当前元素的监听事件(不包括:.native声明的)
1.vuex state中为动态分享的数据; mutations为方法,修改state中的数据; actions(c,v)异步函数(也可为同步)异步操作后c.commit()调用components中的函数间接修改state的数据; getters类似于computed动态属性 modules:用于模块化时的声明
2.EventBus 通过自定义事件:this.$emit与this.$on配合使用 ...
1.provide/inject provide('键','值') const a = inject('键')
2.$root 通过this.$root获取到根,从而逐级查找到具体项(标签元素)的属性与值
3.vuex
4.EventBus
5.$attrs/$listeners