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);
    }
},

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

目录
相关文章
|
5天前
|
JSON 数据可视化 数据库
vue3+threejs+koa可视化项目——实现登录注册(第三步)
vue3+threejs+koa可视化项目——实现登录注册(第三步)
25 5
|
5天前
|
数据可视化 前端开发 JavaScript
vue3+threejs可视化项目——引入threejs加载钢铁侠模型(第二步)
vue3+threejs可视化项目——引入threejs加载钢铁侠模型(第二步)
41 3
|
5天前
|
JavaScript 数据可视化 算法
vue3+threejs可视化项目——搭建vue3+ts+antd路由布局(第一步)
vue3+threejs可视化项目——搭建vue3+ts+antd路由布局(第一步)
24 6
|
5天前
|
JSON 数据可视化 前端开发
vue3+threejs+koa可视化项目——模型文件上传(第四步)
vue3+threejs+koa可视化项目——模型文件上传(第四步)
15 7
|
5天前
|
JavaScript 前端开发 API
Vue 2 vs Vue 3:开发者之争,究竟选择哪个版本?
Vue 2 vs Vue 3:开发者之争,究竟选择哪个版本?
14 1
|
5天前
|
JavaScript 前端开发
vue3+ts+element home页面侧边栏+头部组件+路由组件组合页面教程
这是一个Vue.js组件代码示例,展示了带有侧边栏导航和面包屑导航的布局。模板中使用Element Plus组件库,包含可折叠的侧边栏,其中左侧有 Logo 和导航列表,右侧显示更具体的子菜单。`asideDisplay`控制侧边栏宽度。在`script`部分,使用Vue的响应式数据和生命周期钩子初始化路由相关数据,并从localStorage恢复状态。样式部分定义了组件的颜色、尺寸和布局。
13 1
|
5天前
|
JavaScript
【vue实战】父子组件互相传值
【vue实战】父子组件互相传值
11 1
|
6天前
|
JavaScript
vue2_引入Ant design vue
vue2_引入Ant design vue
11 0
|
7天前
|
JavaScript 前端开发
【vue】跨路由传值,params和query有什么区别?
【vue】跨路由传值,params和query有什么区别?
13 0
|
13天前
|
JavaScript 算法 前端开发
vue3和vue2的区别都有哪些
【4月更文挑战第15天】Vue3与Vue2在响应式系统(Proxy vs. Object.defineProperty)、组件模块化(Composition API vs. Options API)、数据变化检测(Reactive API vs. $watch)、虚拟DOM算法(基于迭代 vs. 基于递归)及Tree-Shaking支持上存在显著差异。Vue3的改进带来了更好的性能和灵活性,适合追求新技术的项目。Vue2则因其成熟稳定,适合维护大型项目。选择版本需根据项目需求、团队情况和技术追求来决定。
14 0