单向/双向数据流最详解

聊天记录, 网友们的思考

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

单向数据流概念

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

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

单向数据流案例

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

相关推荐
浪裡遊10 分钟前
MUI组件库与主题系统全面指南
开发语言·前端·javascript·vue.js·react.js·前端框架·node.js
DiXinWang32 分钟前
关闭谷歌浏览器提示“若要接收后续 Google Chrome 更新,您需使用 Windows 10 或更高版本”的方法
前端·chrome
CoderYanger40 分钟前
前端基础——HTML练习项目:填写简历信息
前端·css·职场和发展·html
muyouking111 小时前
深入理解 HTML `<label>` 的 `for` 属性:提升表单可访问性与用户体验
前端·html·ux
IT_陈寒1 小时前
Java性能调优:从GC日志分析到实战优化的5个关键技巧,让你的应用快如闪电!
前端·人工智能·后端
Mintopia1 小时前
🚀 Next.js API 压力测试:一场前端与后端的“极限拉扯”
前端·后端·全栈
Mintopia1 小时前
🛡️ 对抗性攻击与防御:WebAI模型的安全加固技术
前端·javascript·aigc
庙堂龙吟奈我何1 小时前
qiankun知识点
前端
SoaringHeart2 小时前
Flutter封装:原生路由管理极简封装 AppNavigator
前端·flutter
menu2 小时前
AI给我的建议
前端