单向/双向数据流最详解

聊天记录, 网友们的思考

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

单向数据流概念

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

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

单向数据流案例

下面是单向数据流的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的人,就是我...

相关推荐
花开盛夏^.^6 小时前
电脑打开多个浏览器Web窗口占用较大的运行内存的原因
前端·浏览器
馒头不想说话7 小时前
实体店老板的24小时AI运营员工,写、剪、发全自动,省下一整个团队工资
前端
椒哥10 小时前
一天被问几十次"允许",我统计了 517 次,然后写了个插件
前端·javascript·github
风骏时光牛马10 小时前
生成一个AI稳定性治理及疑难问题分析标题,只需要一个标题,不需要其他的任何文本。
前端
莫西干式秃头10 小时前
用 AI + threejs 写了个浏览器里的 3D 动作游戏《武来》:砍怪、放技能、开 SU7
前端·人工智能·three.js
kyriewen10 小时前
我测了 6 种防请求竞态的写法:只有 1 种真能打
前端·javascript·程序员
孟健10 小时前
用 WorkBuddy 做个人名片网页,挂上开源设计技能后效果完全不同了
前端·人工智能·ai编程
IT_陈寒10 小时前
SpringBoot自动配置的坑,这次终于爬出来了
前端·人工智能·后端
LuHang11 小时前
从天地图切换到高德地图:一次真实的底图迁移实战
前端·vue.js·cesium
用户3600555790011 小时前
Kestrel_VLLM - 27 · 寄存器常驻与融合发射:两次「少发一次」
前端