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博客

相关推荐
zwjapple44 分钟前
docker-compose一键部署全栈项目。springboot后端,react前端
前端·spring boot·docker
像风一样自由20203 小时前
HTML与JavaScript:构建动态交互式Web页面的基石
前端·javascript·html
aiprtem4 小时前
基于Flutter的web登录设计
前端·flutter
浪裡遊4 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
why技术4 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
幽络源小助理4 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
GISer_Jing4 小时前
0704-0706上海,又聚上了
前端·新浪微博
止观止4 小时前
深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案
前端·pnpm·前端工程化·包管理器
whale fall4 小时前
npm install安装的node_modules是什么
前端·npm·node.js
烛阴4 小时前
简单入门Python装饰器
前端·python