V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cutemurphy2888
V2EX  ›  Vue.js

父组件直接属性传函数给子组件 VS 子组件 emit 方式的区别?

  •  
  •   cutemurphy2888 · 2022-03-22 20:47:30 +08:00 · 1761 次点击
    这是一个创建于 969 天前的主题,其中的信息可能已经有所发展或是发生改变。

    可以看见子组件 props 里头接了这个函数,而且标明了是一个 Function 类型,注意不要写成 function , 容易抛错。 现在有个问题就是这种方式,父给子直接方法,子调这个方法,跟子组件 emit 一个方法,父再来接有什么区别。

    <code>
    
    父组件
    我们 qq 这个属性,传了一个 qq 方法给组件。
    
    
    <img alt="Vue logo" src="./assets/logo.png" />
      <HelloWorld msg="Welcome to Your Vue.js App" />
      <CuteMurphy msg="Welcome to Your Vue.js App" @shit="shit" :qq="qq" />
    </template>
    
    <script>
    import HelloWorld from "./components/HelloWorld.vue";
    import CuteMurphy from "./components/CuteMurphy.vue";
    
    export default {
      name: "App",
      components: {
        HelloWorld,
        CuteMurphy,
      },
      methods:{
        shit(){
          console.log("shit");
        },
        qq(msg){
          console.log(msg);
        }
      }
    };
    </script>
    
    子组件:
    可以看见子组件 props 里头接了这个函数,而且标明了是一个 Function 类型,注意不要写成 function ,
    容易抛错。
    现在有个问题就是这种方式,父给子直接方法,子调这个方法,跟子组件 emit 一个方法,父再来接有什么区别。
    
    <template>
      <div @click="handleClick">{{msg}} age is {{age}}</div>
    </template>
    
    <script>
    import {ref, watchEffect} from 'vue';
    export default {
      name: "CuteMurphy",
      props:{
        msg:{
          type:String
        },
        qq:{
          type:Function
        }
      },
      setup(props,ctx){
        const age=ref(32);
        const handleClick=()=>{
          ctx.emit("shit");
        };
    
        watchEffect(()=>{
          props.qq("jiajia");
          console.log(age.value,33);
          console.log(props.msg,777);
        });
    
        return {
          age,
          handleClick
        }
      },
      data(){
        return {
          username:"11wangjun"
        }
      },
      methods:{
      }
    };
    </script>
    
    <style scoped>
    </style>
    
    </code>
    
    8 条回复    2022-08-21 20:28:15 +08:00
    ChefIsAwesome
        1
    ChefIsAwesome  
       2022-03-22 21:21:18 +08:00
    事件一般是一对多的概念,这种一对一的确实没必要用事件。我写 vue 的时候都是直接传函数,保持一个单向的传递才不容易出错。
    waiaan
        2
    waiaan  
       2022-03-22 21:27:28 +08:00
    这个跟父组件和子组件的功能有关,父组件功能就用父组件的函数,子组件的就写在子组件里。
    WhateverYouLike
        3
    WhateverYouLike  
       2022-03-22 21:48:17 +08:00 via Android
    我老大喜欢传函数进子组件,我喜欢在子组件里 emit 。我认为,父组件的函数应尽量由父组件自己调用。一个比方,假如有客人来你家,emit 就是门把手,这个门把手把你的世界和外面的世界分隔开了,很有安全感;传函数的方式就好像你房间中央有个传送门,指不定哪天有个人传进来拉了一泡便便就跑了。

    不过感觉只要是稍微复杂点的业务逻辑,是不可能一点函数也不传的,而且 emit 有种飞线的感觉
    qxqsxbd
        4
    qxqsxbd  
       2022-03-23 10:45:27 +08:00
    父组件传函数的话,子组件还得判断传了还是没传,抛事件的话就可以无脑抛了
    cutemurphy2888
        5
    cutemurphy2888  
    OP
       2022-03-23 12:29:20 +08:00
    @qxqsxbd

    fn && fn() 不就完了。
    WhateverYouLike
        6
    WhateverYouLike  
       2022-03-23 12:34:27 +08:00 via Android
    @cutemurphy2888
    typeof fn === 'function' && fn()
    cutemurphy2888
        7
    cutemurphy2888  
    OP
       2022-03-23 13:03:19 +08:00
    @WhateverYouLike props 里写一下就行了
    type:Function
    charlie21
        8
    charlie21  
       2022-08-21 20:28:15 +08:00
    选择在子组件里 emit , 则意味着开发者写过 angular @Output Emitter https://angular.io/guide/inputs-outputs

    选择传函数进子组件 , 则意味着开发者写过初阶 react , 因为 仅对于 `子组件如何改变父组件状态` 这个事而言
    低水平 / 初阶
    https://stackoverflow.com/questions/39041710/react-js-change-child-components-state-from-parent-component
    高水平 直接封装成 context provider, 顺便攻克了 prop drilling 问题
    https://kentcdodds.com/blog/how-to-use-react-context-effectively
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2848 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:54 · PVG 21:54 · LAX 05:54 · JFK 08:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.