单向/双向数据流最详解

聊天记录, 网友们的思考

你如果只是无聊翻翻, 可以直接看最底下的聊天记录, 看看网友们的思考: 聊天记录

单向数据流概念

单向数据流: 数据的流动是单向的,从组件的角度看,只能从上到下(祖到孙,或父到子,一个意思),不能从上到下。

更详细的说就是,上游的数据在上游才有可改权,下游的数据是收上游控制的,下游不能修改上游的数据。

单向数据流案例

下面是单向数据流的vue代码 (我也是react重度用户,反正会react的玩家基本都看得懂vue, 所以vue受众度更广, 就直接用vue了)

child.vue

javascript 复制代码
<template>
  <div>
    <button @click="clickBtn" class='btn-item'>hi~</button>
  </div>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  setup() {
    const clickBtn = () => {
      ctx.emit('on-change', 'hi~');
    };
    return {
      clickBtn,
    };
  },
});
</script>

parent.vue

javascript 复制代码
<template>
  <div>
    <emit-child @on-change='onEmitMessage' />
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue';
import EmitChild from './Child.vue';

export default defineComponent({
  components: {
    EmitChild,
  },
  setup() {
    const message = ref('');
    const onEmitMessage = (newMessage) => {
      console.log('newMessage', newMessage);
      message.value = newMessage;
    };
    return {
      onEmitMessage,
    };
  },
});
</script>

子组件通过emit通知父组件,父组件接收到消息后,可以做一些事情,如:修改自己组件内部的状态。而不是子组件直接修改父组件。这就是单向数据流。

注: 网上很多误导性的文章说v-modal是双向数据流,但实际上v-modal也是emit的语法糖, 本质也是单向数据流

双向数据流案例

这里就是为了展示双向数据流而硬写的了...

child.vue

javascript 复制代码
<template>
  <div>
    <button @click="clickBtn" class='btn-item'>hi~</button>
  </div>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  props: ['parentState'],
  setup(props) {
    const clickBtn = () => {
      // parentState是ref, 所以修改值相对于功能而言是有效的
      props.parentState.message = 'hi~';
    };
    return {
      clickBtn,
    };
  },
});
</script>

进一步抽象

抽象能力强的同学可以类比为纯函数和副作用函数:

纯函数 (类似遵循单向数据流的组件):

javascript 复制代码
const state = {
  message: '',
};

// 纯函数相当于纯组件, 对外界没有多余的影响, 你自己定制行为, 通过参数传进去
// 这就是单向数据流的好处, 用这个纯组件时, 对外界没有影响, 不需要担心任何问题(降低开发的心智负担)
const pureFn = (onEmitMessage) => {
  setTimeout(() => {
    onEmitMessage('hi~');
  }, 1000);
};

pureFn(newMessage => {
  state.message = newMessage;
});

// 多次调用, 爱干嘛就干嘛, 数据传递一目了然, 没有心智负担
pureFn(message => {
  console.log('newMessage', newMessage);
});

副作用函数 (类似双向数据流的组件):

javascript 复制代码
const state = {
  message: '',
};

// 卧槽, 你这么写, 还得记住这个函数什么时候会对外界做出什么影响, 心智负担太大了
// 一个是每次调用时都有心智负担, 一个是这个函数中, 到底对外界做了哪些影响...
const effectFn = () => {
  setTimeout(() => {
    state.message = 'hi~';
  }, 1000);
};

// 心智负担: 调用一次, 这时对state.message修改值了, 对xxx也影响了? 忘了, 草
effectFn();

// 心智负担: 调用一次, 这时对state.message修改值了, 对xxx也影响了? 忘了, 草
effectFn();

// 心智负担: 调用一次, 这时对state.message修改值了, 对xxx也影响了? 忘了, 草
effectFn();

思想

单向数据流就是一种更好的开发范式, 函数式编程(纯函数编程)也是。开发中持续遵循这个原则, 即使有少数烂代码没有遵循, 心智负担也是很小的。

聊天记录更生动

截图里那个最爱bb的人,就是我...

相关推荐
QQ1__8115175158 小时前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态8 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子8 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
独角鲸网络安全实验室8 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
紫微AI8 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
GISer_Jing8 小时前
AI前端(From豆包)
前端·aigc·ai编程
IT枫斗者8 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
测试修炼手册8 小时前
[测试技术] 深入理解 JSON Web Token (JWT)
前端·json
AI老李8 小时前
2026 年 Web 前端开发的 8 个趋势!
前端
里欧跑得慢8 小时前
15. Web可访问性最佳实践:让每个用户都能平等访问
前端·css·flutter·web