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

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

目录
相关文章
|
1天前
|
存储 API
vue3中如何动态自定义创建组件并挂载
vue3中如何动态自定义创建组件并挂载
|
6天前
|
JavaScript 索引
Vue 2和Vue 3的区别以及实现原理
Vue 2 的响应式系统通过Object.defineProperty来实现,它为对象的每个属性添加 getter 和 setter,以便追踪依赖并响应数据变化。
22 9
|
8天前
|
JavaScript 开发工具
vite如何打包vue3插件为JSSDK
【9月更文挑战第10天】以下是使用 Vite 打包 Vue 3 插件为 JS SDK 的步骤:首先通过 `npm init vite-plugin-sdk --template vue` 创建 Vue 3 项目并进入项目目录 `cd vite-plugin-sdk`。接着,在 `src` 目录下创建插件文件(如 `myPlugin.js`),并在 `main.js` 中引入和使用该插件。然后,修改 `vite.config.js` 文件以配置打包选项。最后,运行 `npm run build` 进行打包,生成的 `my-plugin-sdk.js` 即为 JS SDK,可在其他项目中引入使用。
|
6天前
|
JavaScript 调度
Vue3 使用 Event Bus
Vue3 使用 Event Bus
11 1
|
6天前
|
JavaScript
Vue3 : ref 与 reactive
Vue3 : ref 与 reactive
9 1
vue3 reactive数据更新,视图不更新问题
vue3 reactive数据更新,视图不更新问题
|
7天前
|
JavaScript
|
7天前
vue3定义暴露一些常量
vue3定义暴露一些常量
|
6天前
Vue3 使用mapState
Vue3 使用mapState
10 0
|
2天前
|
JavaScript
vue中watch的用法
vue中watch的用法