Vue组件之间的传值汇总

组件之间的传值

1、父传子 props

2、父传子 slot

3、父传子 不建议用 attrs

4、 子传父 ref

5、子传父 emit

6、povide/inject只能在setup的时候用。

7、利用vuex和pinia去实现数据的交互

1、实现代码App.vue

javascript 复制代码
<script setup>

import TestProps from './components/TestProps.vue';
import TestEmit from './components/TestEmit.vue';
import TestProvideInject from './components/TestProvideInject.vue';
import TestRef from './components/TestRef.vue';
import TestAttrs from './components/TestAttrs.vue';
import TestSlot from './components/TestSlot.vue';



import { createApp, provide, reactive, ref } from 'vue';

const mm = ref("父值 test");
const pmsg = "父值 test"
function pcallback()
{
  console.log("pcallback");
}

function pEmitclicked(m)
{
  console.log("pEmitclicked " + m);
}



function pclicked()
{
  console.log("pclicked ");
  provide("user","test1")
  
}
//provide() can only be used inside setup().
provide("user","test")
provide("userObj",{"a":"b"})
provide("userFunc",()=>{return "aaa"})

let testref = ref();
function prefClicked()
{
 
  console.log("title:", testref.value.title);
  console.log("msg:", testref.value.msg);
  testref.value.func();
  testref.value.title = "sssssss"; 
}
</script>

<template>
  <div>
    <p>父传子 props</p>
    <p>子传父 emit</p>
    <p> povide/inject只能在setup的时候用</p>
    <p>子传父 ref</p>
    <p>父传子 不建议用 attrs</p>
    <p>父传子 slot</p>

  </div>
  
  <div>
    
      <TestProps></TestProps>
      <TestProps :message="pmsg"></TestProps>
      <TestProps message="我是传值" :callback="pcallback"></TestProps>
  </div>
  <div>
    <p>emit===========================</p>
    <button @click="pEmitclicked">pEmitclicked</button>
    <TestEmit @subemit="pEmitclicked"></TestEmit>
  </div>
  <div> 
    <p>provide/inject===========================</p>
    <button @click="pclicked">provide/inject</button>
    <TestProvideInject></TestProvideInject>
  </div>
  <div> 
    <p>Ref===========================</p>
    <button @click="prefClicked">ref</button>
    <TestRef ref="testref"></TestRef>
  </div> 
  <div>      
    <p>attrs===========================</p>
    <TestAttrs msg="test" msg2="2222"></TestAttrs>
      
  </div>
  <div>
    <p>slot===========================</p>
    <TestSlot></TestSlot>
    <TestSlot> {{ mm }}</TestSlot>   
    <TestSlot>
      <template v-slot:header>
        <h1>Here header title</h1>
      </template>
    </TestSlot>
  </div> 


 </template>

<style scoped>

</style>

2、TestProps.vue

javascript 复制代码
<template>
    <h3>props</h3>
    <a>{{ msg }} : {{ message }}</a>
    <button @click="callback_p">调用函数</button>
</template>

<script>
import { ref } from 'vue'
export default {

    props : {
        message : {
            type : String,
            required: true,
            default : "default message ",
        },
        obj : { type: Object,
                    // 对象或数组默认值必须从一个工厂函数获取
                    default() {
                        return { message: 'hello' }
                    }
                },
        callback : {type: Function,
            // 与对象或数组默认值不同,这不是一个工厂函数 ------ 这是一个用作默认值的函数
            default() {
                console.log("default clicked");
                return 'Default function'
            }
        }
    },
    
    setup(props) //需要传值
    {
        const msg = ref("提示");
        function callback_p()
        {
            props.callback();
        }
        return {msg,callback_p};
    }
}
</script> 

<!-- <script setup>
import { ref } from "vue";
const msg = ref("提示");

//需要自己定义props
const props = defineProps({
    message : {
        type : String,
        required: true,
        default : "default message ",
    },
    obj : {
        type : Object
    },
    aryobj : {
        type : Array,
        default : []
    },
    callback : {
        type : Function,
        default() {
            console.log("default clicked");
            return "function"
        }
    }
})

function callback_p()
{
    props.callback();
}

</script> -->

3、TestAttrs.vue

javascript 复制代码
<template >
    <div>
        {{ msg }} + {{ attrs.msg2 }}
    </div>
</template>

<script>
import { ref, useAttrs } from "vue";
export default {
    inheritAttrs: true,
    setup(props, context){
        const msg = ref("msg1");
        const attrs = context.attrs;
        return {msg, attrs}
    },
}
</script> 

<!-- <script setup>
import { ref, useAttrs } from "vue";

const msg = ref("msg1");
const attrs = useAttrs();

console.log("attrs:",attrs);


</script> -->

4、TestSlot.vue

javascript 复制代码
<template >
    <div>
        <slot>defaut slot</slot>
        <slot name="header"></slot>
    </div>
</template>

5、TestRef.vue

javascript 复制代码
<template>
    <h3>{{ title }}</h3>
</template>

<!-- 
<script>
import { ref } from "vue";  
export default {
 
    setup()
    {
        const title = ref("title");
        const msg = ref({
            title:"aaa"
        });

        function func()
        {
            console.log("func");
        }

        return {title, msg, func}
    }
}
</script> -->

<script setup>
import { ref } from "vue";

const title = ref("title");
const msg = ref({
    title:"aaa"
})

function func()
{
    console.log("func");
}

defineExpose({
    title,
    msg,
    func
})

</script>

6、TestEmit.vue

javascript 复制代码
<template>
    <h3>emit+++++</h3>
    <div>{{ msg }}
    <button @click="clicked">子传父</button>
    </div>

</template>


<!-- <script>
import { ref } from 'vue';
export default {
    
    emits : {
        subemit : function(str)
        {
            console.log("subemit " + str);
            //msg.value = str;
            return true;
        }
    },
    methods : {
        clicked : function clicked()
        {
            console.log("clicked ");
            this.$emit("subemit", this.msg);
        }
    },
    setup()
    {
        const msg = ref("msg");

        //这里声明无效需要用methods
        function clicked1()
        {
            console.log("kkk");
            this.$emit("subemit", this.msg.value);
        }

        return {msg,clicked1}
    }

    
}
</script> -->

<script setup>
import { ref } from 'vue';
const msg = ref("msg");

const emits = defineEmits({
    subemit : function(str)
        {
            console.log("subemit " + str);
            return true;
        }
})

function clicked()
{
    console.log("clicked ");
    emits("subemit", msg.value);
}

</script>
<style>

</style>

7、TestProvideInject.vue

javascript 复制代码
<template>
    <div>inject provide test {{ puser }}</div>
    <button @click="pb">test</button>
</template>

<!-- <script lang="ts">
import { ref } from 'vue'

export default {
    setup() {

        const msg = ref("msgtest");
        return {msg}
    },

    methods : 
    {
        pb : function()
        {
            console.log(this.msg);
            this.$emit("subemit", this.msg);
        }
    },

    emits : {
        subemit : function(str){
            console.log("subemit " + str);
            return true; //要有返回值,不然有warning
        }
    }

}
</script> -->


<script setup>
import { inject, ref } from 'vue'


const msg = ref("msgtest");


const puser = inject("user");
const puserObj = inject("userObj");
const userFunc = inject("userFunc");


console.log(puser, puserObj, userFunc())


</script>

8、终极方法vuex和pinia

参考

Vue组件之间数据通信12种方式_vue组件间通信_小胖梅前端的博客-CSDN博客

vue组件间通信的六种方式(完整版)_vue的组件之间是如何交互的, 几种方式_学编程的ADD的博客-CSDN博客

相关推荐
weixin_382395232 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__3 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.3 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~4 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华5 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子7 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅7 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni8 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学9 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端