vue2 vue3 各传值汇总

简介: vue

序:

vue最常见的,容易为难新手的,应该就是组件间的传参的,所以本次笔记就记录下传参,顺带也记录下vue2吧

一、vue3

1、父传子

父组件atherTitle,fatherMoney,fatherWifi,thisIsEmpty等都是传过去给子组件的

<template>
<el-row class="mb-4">
    <el-button type="danger">props.vue传递父组件的参数到子组件,子组件用defineProps接收,fatherTitle和fatherMoney参数</el-button>
</el-row>
 
<!--写在父组件的子组件-->
<Son :fatherTitle="xxxxx" :fatherMoney="money" :fatherWifi="wifi" :thisIsEmpty="myEmptyStr" :fatherArr="myArr"></Son>
</template>
 
<script lang="ts" setup>
import { ref,reactive,watch,watchEffect } from 'vue'
import Son from "./son.vue"//引入子组件
 
const  xxxxx = ref("-----这是父组件的标题-----")
const money = ref(9999999999)
const wifi = reactive({pwd:222,name:"fffff"})
const myEmptyStr = ref("")
const myArr = reactive([{code:666,msg:"success"},{code:555,msg:"fail"}])
</script>

子组件接收defineProps() 接收父组件传递过来的参数,defineProps在setup语法糖可以直接使用,不需要import

<template>
    <el-row class="mb-4">
        <el-button type="success">
            son.vue:{{sonTitle}}-------{{fatherTitle}}-----{{fatherMoney}}
        </el-button>
        <el-button type="success">{{fatherWifi}}--{{fatherWifi.pwd}}--{{fatherWifi.name}}</el-button>
        <el-button type="danger">
            父传递的空字符串:{{myEmptyStr}}
        </el-button>
    </el-row>
    <el-row class="mb-4">
      <el-button type="primary" v-for="(item,index) in fatherArr" :key="index">
          {{item}},{{item.code}}
      </el-button>
    </el-row>
 
</template>
<script lang="ts" setup>
import { ref,reactive} from 'vue'
const sonTitle = "This is  son title"
//接收父组件传过来的值,需要注意defineProps只能在setup语法糖里面使用,不需要import引入
const yyyy = defineProps({
    fatherTitle:{
        type:String,//类型字符串
        default:'当前Child.vue的默认值'//如果没有传递msg参数,默认值是这个
    },
    fatherMoney:{
        type:Number,//类型字符串
        default:0//如果没有传递msg参数,默认值是这个
    },
    fatherWifi:{
        type:Object,//类型字符串
        default:{id:999}//如果没有传递msg参数,默认值是这个
    },
    myEmptyStr:{
        type:String,
        default:"myEmptyStr默认值为空字符串"
    },
    fatherArr:{
        type:Object,//类型字符串
        //default:[]//如果没有传递msg参数,默认值是这个
    },
})
 
console.log(yyyy.fatherArr)
console.log("-------这是子组件---------")
console.log(yyyy.fatherWifi)
console.log(yyyy.fatherTitle)
 
</script>

2、子传父

子组件

<script lang="ts" setup>
import { ref,reactive} from 'vue'
 
//子组件调用父组件的方法,
//父组件的调用子组件的地方写上@onMySonFunc="fatherFunc"
const myEmit = defineEmits(["onMySonFunc"])//这样就调用到父组件的fatherFunc方法了
 
//传递参数: "调用父组件的方法"和666666
myEmit("onMySonFunc","调用父组件的方法",666666)
</script>

父组件@onMySonFunc="funcToSon",这样上面的子组件就能调用到父组件的funcToSon()方法了

<template>
<!--子组件调用父组件的funcToSon()方法-->
<Son  @onMySonFunc="funcToSon"></Son>
</template>
 
<script lang="ts" setup>
import { ref,reactive} from 'vue'
import Son from "./son.vue"//引入子组件
 
const funcToSon = (name:any,id:number)=>{
    console.log("子组件调用了父组件的funcToSon()方法",id)
    return {message:name}
}
</script>

3、隔代传

父组件provide传递参数到其他子孙组件

<script lang="ts" setup>
import { provide } from 'vue'
provide('test001', "987654321")
//provide传递test001的参数,值是987654321到子孙节点
</script>

儿子组件用inject接收父组件传递过来的参数

<script lang="ts" setup>
import {inject} from "vue"
 
//儿子组件用inject接收父组件传递过来的参数
const provideFatherStr = inject('thisFromGrandFather')
</script>

孙子组件也可以用inject接收父组件传递过来的参数

<script lang="ts" setup>
import {inject} from "vue"
 
//孙子组件用inject接收它爷爷组件传递过来的参数
const provideFatherStr = inject('thisFromGrandFather')
</script>

4、第三库(mitt || tiny-emitter

mitt 使用举例:

// eventBus.js
import mitt from 'mitt';

const emitter = mitt();

export default emitter;
// a.js
import emitter from './utils/eventBus'

emitter.emit('panda', {name: 'lokka', age: 2})
emitter.emit('flamingo', {name: 'disy', age: 1})
// b.js
import emitter from './utils/eventBus'
// 逐个监听
—————————————————————————————————————————
emitter.on('panda', (val) => {
    console.log(val)
})

emitter.on('flamingo', (val) => {
    console.log(val)
})

// 取消监听
funtion onFoo() {}
emitter.on('foo', onFoo)
emitter.off('foo', onFoo)
—————————————————————————————————————————
// 监听多个
emitter.on('*', (type, val) => {
    console.log(type, val)
})

// 取消监听多个
emitter.all.clear()

二、vue2

1、父传子

父组件

<template>
    <div class="wrap">
        <div>我是Father组件</div>
        <Son
          str="我是字符串"
          isPublished
          :num=5
          :obj="{cont:'我是一个对象'}"
          :func="()=>{this.hello()}"
          :arr="arr"></Son>
    </div>
</template>
<script>
    import Son from './Son'
    export default {
        name: "Father",
        data(){
            return{
                arr:[1,2,3]
            }
        },
        methods:{
            hello(){
                console.log("hello world!")
            }
        },
        components:{  Son  }
    }
</script>

子组件

<template>
    <div>我是Son组件</div>
</template>
<script>
    export default {
        name: "Son",
        props:{//props列表
            arr:Array,//定义参数类型
            num:Number,
            isPublished: Boolean,
            str:String,
            str2:{
                type:String,
                default:"我是默认字符串"//定义参数默认值
            },
            func:{
                type:Function,
                required:false//定义参数是否必须值
            },
            obj:{
                type: Object,
                required:false
            }
        },
        created() {
            console.log(this.str);//我是字符串
            console.log(this.str2);//我是默认字符串
            console.log(this.num);//5
            console.log(this.isPublished);//true
            console.log(this.func);//hello(){console.log("hello world!");}
            console.log(this.arr);//[1,2,3]
            console.log(this.obj);//{cont:'我是一个对象'}
            this.func();//hello world!
        }
    }
</script>

2、子传父

2.1、$emit

父组件

<template>
    <div class="wrap">
        <div>我是Father组件</div>
        <Son @func="speak" ></Son>
    </div>
</template>

<script>
    import Son from './Son'
    export default {
        name: "Father",
        methods:{
           speak(msg){
               console.log(msg);//我是子组件发送的消息!
           }
        },
        components:{
            Son
        }
    }
</script>

子组件

<template>
    <div>
        <div>我是Son组件</div>
    </div>
</template>

<script>
    export default {
        name: "Son",
        mounted() {
             //func 是绑定的事件名
            this.$emit('func',"我是子组件发送的消息!");
        }
    }
</script>

2.2、直接传

父组件

<template>
  <div class="parent">
    <child :fatherMethod='fatherMethod'></child>// 父组件把方法传入子组件中,在子组件里直接调用这个方法
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        methods:{
            fatherMethod() {
                alert('我是父组件的know方法');
            }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

子组件

<template>
  <div class="child" @click='childClick'>
  </div>
</template>

<script>

    export default {
        props:{
            fatherMethod: {
                type: Function,
                default: null
            }
        },
        methods:{
            childClick(){
                this.fatherMethod()
        }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .child{
    width: 100px;
    height: 100px;
    background-color: blue;
  }
</style>

2.3、$refs

父组件

<template>
    <div class="wrap">
        <div>我是Father组件</div>
        <!-- ref绑定节点 -->
        <Son ref="son">
          <!-- @click.stop  阻止冒泡 -->
          <button @click.stop="UGG">按钮</button>
        </Son>
    </div>
</template>

<script>
    import Son from './Son'
    export default {
        name: "Father",
        mounted(){
          //获取节点
            this.$refs['son'].$on('func',(msg)=>{
                console.log(msg);
            })
        },
        methods:{
            UGG(){
              //调用节点里的方法
              this.$refs['son'].show()
            }
        },
        components:{
            Son
        }
    }
</script>

子组件

<template>
    <div>
        <div>我是Son组件</div>
        <button @click="$emit('func','我是子组件传递的消息1!')">Send1</button>
        <button @click="sendMsg">Send2</button>
        <!-- 插槽 -->
        <slot></slot>
    </div>
</template>

<script>
    export default {
        name: "Son",
        methods:{
            sendMsg(){
                //func 是绑定的事件名
                this.$emit('func','我是子组件传递的消息2!');
            },
            show(){
                console.log('显示')
            }
        }
    }
</script>

2.4、$parent

$root$parent 都能够实现访问父组件的属性和方法,两者的区别在于,如果存在多级子组件,通过parent 访问得到的是它最近一级的父组件,通过root 访问得到的是根父组件(App.vue) 所以存在组件嵌套的情况下 不要使用 $root

父组件

<template>
  <div class="parent">
    <child></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        data() { // 组件的data必须是函数
          return {
            msg:'父组件数据测试'
          }
        },
        methods:{
          fatherMethod() {
            alert('我是父组件的方法')
          }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

子组件

<template>
  <div class="child" @click='childClick'>
  </div>
</template>

<script>

    export default {
        data() {
            return {
                msg: '我是子组件传递过来的数据'
            }
        },
        methods:{
            childClick(){
                this.$parent.fatherMethod()
                console.log(this.$parent.msg)
        }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .child{
    width: 100px;
    height: 100px;
    background-color: blue;
  }
</style>

3、兄弟传值

在main.js种挂载全局EventBus

Vue.prototype.$EventBus = new Vue()

A组件

<template>
    <div class="wrap">
        <div>我是组件A</div>
        <button @click="sendMsg">发送</button>
    </div>
</template>

<script>
    export default {
        name: "A",
        methods:{
            sendMsg(){
               this.$EventBus.$emit('sendMsg',"这是组件A发送的消息!")
            }
        }
    }
</script>

B组件

<template>
    <div>
        <div>我是组件B</div>
    </div>
</template>

<script>
    export default {
        name: "B",
        mounted(){
            this.$EventBus.$on('sendMsg',(msg)=>{
                console.log(msg);//这是组件A发送的消息!
            })
        },
    }
</script>

4、隔代传值( provide / inject

provide是父级组件需要传递给子孙组件的属性/方法

//选项一
provide: {
  content: 'hello world'
}

//选项二
provide(){
  return {
    content: 'hello world'
  }
}

inject是子孙组件用来接收父级组件属性/方法

//选项一
inject: ['content']

//选项二
inject: {
  content: 'content'
}

//选项三
inject: {
  content: {
    from:'content',
    default:'hello world'
  }
}

a.vue

<template>
    <div>
        <span>{{a}}</span>
        <aa></aa>
    </div>
</template>

<script>
    import aa from './aa';
    
    export default {
        data(){
            return {
                a: "我是a组件中数据"
            }
        },
        provide() {
            return {
                msg: this.a
            }
        },
        components: {
            aa
        }
    }
</script>

aa.vue

<template>
    <div>
    </div>
</template>

<script>
    export default {
        inject: ['msg'],
        created() {
            console.log(this.msg); // 我是a组件中数据
        }
    }
</script>

5、跨级($attrs / $listeners

  • **$attrs:**包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用。
  • **$listeners:**包含了父作用域中的 (不含 .native修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件

父组件

<template>
    <div>
        <span>{{name}}</span>
        <span>{{price}}</span>
        <aa
        :name="name"
        :price="price"
        :size="size"
        ></aa>
    </div>
</template>

<script>
    import aa from './aa';   
    export default {
        data(){
            return {
                name: "可乐",
                price: 3,
                size: "500ml"
            }
        },
        provide() {
            return {
                msg: this.a
            }
        },
        components: {
            aa
        }
    }
</script>

子组件aa.vue

<template>
    <div>
        <span>{{name}}</span>
        <aaa v-bind="$attrs"></aaa>
    </div>
</template>

<script>
    import aaa from './aaa';    
    export default {
        props: ['name'],
        components: {
            aaa
        }
    }
</script>

子组件aaa.vue

<template>
    <div>
    </div>
</template>

<script>    
    export default {
        created() {
            console.log(this.$attrs); // {price: 3, size: "500ml"}
        }
    }
</script>
总结: $attrs 与 $listeners 是两个对象,$attrs 里存放的是父组件中绑定的非 Props 属性,$listeners里存放的是父组件中绑定的非原生事件。

6、插件传值

安装 pubsub-js 插件: npm i pubsub-js -s 可实现全局参数传递

  • publishSync 同步发送消息
  • publish 同步发送消息
  • subscribe 订阅消息
  • unsubscribe 卸载特定订阅
  • clearAllSubscriptions 清除所有订阅

组件A

<template>
    <div class="wrap">
        <div>我是组件A</div>
        <button @click="sendMsg">发送</button>
    </div>
</template>

<script>
    import  pubsub from 'pubsub-js'
    export default {
        name: "A",
        methods:{
            sendMsg(){
                //publishSync  同步发送消息
                pubsub.publishSync("sendMsg","这是A组件发布的消息!");
            }
        }
    }
</script>

组件B

<template>
    <div>
        <div>我是组件B</div>
    </div>
</template>

<script>
    import pubsub from 'pubsub-js'
    export default {
        name: "B",
        mounted(){
            //subscribe    订阅消息
            pubsub.subscribe("sendMsg",(e,msg)=>{
                console.log(e,msg);//sendMsg 这是A组件发布的消息!
            })
        },
    }
</script>

7、路由传值

7.1、页面直接传参

<router-link :to="{ path:'./attachment',query:{order_id: task.ORDERID}}">
    <mt-button type="primary" size="small">查看附件</mt-button>
</router-link>

7.2、通过方法传递参数

methods: {
    society() {
        //console.log('society');
        this.$router.push({
            name:'society',
            query:{value:1}
        })
},

7.3、接值

methods:{
    loadData:function(){
        this.id = this.$route.query.order_id;
        axios.get("http://testqywx.origimed.com:18082/weixin-qy/order/Order/userOrderFilesList.json?usercode=sysadmin&orderId="+this.id)
        .then(response=>this.tasks=response.data.reason);
    }
},

哎呀,累了,没想到总结下来,还不少,暂时先这么多吧,回头有了再更新~

目录
相关文章
|
11天前
|
开发工具 iOS开发 MacOS
基于Vite7.1+Vue3+Pinia3+ArcoDesign网页版webos后台模板
最新版研发vite7+vue3.5+pinia3+arco-design仿macos/windows风格网页版OS系统Vite-Vue3-WebOS。
133 11
|
5月前
|
缓存 JavaScript PHP
斩获开发者口碑!SnowAdmin:基于 Vue3 的高颜值后台管理系统,3 步极速上手!
SnowAdmin 是一款基于 Vue3/TypeScript/Arco Design 的开源后台管理框架,以“清新优雅、开箱即用”为核心设计理念。提供角色权限精细化管理、多主题与暗黑模式切换、动态路由与页面缓存等功能,支持代码规范自动化校验及丰富组件库。通过模块化设计与前沿技术栈(Vite5/Pinia),显著提升开发效率,适合团队协作与长期维护。项目地址:[GitHub](https://github.com/WANG-Fan0912/SnowAdmin)。
747 5
|
2月前
|
缓存 前端开发 大数据
虚拟列表在Vue3中的具体应用场景有哪些?
虚拟列表在 Vue3 中通过仅渲染可视区域内容,显著提升大数据列表性能,适用于 ERP 表格、聊天界面、社交媒体、阅读器、日历及树形结构等场景,结合 `vue-virtual-scroller` 等工具可实现高效滚动与交互体验。
257 1
|
2月前
|
缓存 JavaScript UED
除了循环引用,Vue3还有哪些常见的性能优化技巧?
除了循环引用,Vue3还有哪些常见的性能优化技巧?
147 0
|
3月前
|
JavaScript
vue3循环引用自已实现
当渲染大量数据列表时,使用虚拟列表只渲染可视区域的内容,显著减少 DOM 节点数量。
98 0
|
5月前
|
JavaScript API 容器
Vue 3 中的 nextTick 使用详解与实战案例
Vue 3 中的 nextTick 使用详解与实战案例 在 Vue 3 的日常开发中,我们经常需要在数据变化后等待 DOM 更新完成再执行某些操作。此时,nextTick 就成了一个不可或缺的工具。本文将介绍 nextTick 的基本用法,并通过三个实战案例,展示它在表单验证、弹窗动画、自动聚焦等场景中的实际应用。
414 17
|
6月前
|
JavaScript 前端开发 算法
Vue 3 和 Vue 2 的区别及优点
Vue 3 和 Vue 2 的区别及优点
|
5月前
|
JavaScript 前端开发 API
Vue 2 与 Vue 3 的区别:深度对比与迁移指南
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,在过去的几年里,Vue 2 一直是前端开发中的重要工具。而 Vue 3 作为其升级版本,带来了许多显著的改进和新特性。在本文中,我们将深入比较 Vue 2 和 Vue 3 的主要区别,帮助开发者更好地理解这两个版本之间的变化,并提供迁移建议。 1. Vue 3 的新特性概述 Vue 3 引入了许多新特性,使得开发体验更加流畅、灵活。以下是 Vue 3 的一些关键改进: 1.1 Composition API Composition API 是 Vue 3 的核心新特性之一。它改变了 Vue 组件的代码结构,使得逻辑组
1507 0
|
14天前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
122 2
|
4月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
560 0

热门文章

最新文章