单向/双向数据流最详解

聊天记录, 网友们的思考

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

单向数据流概念

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

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

单向数据流案例

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

相关推荐
桃园码工1 分钟前
15_HTML5 表单属性 --[HTML5 API 学习之旅]
前端·html5·表单属性
百万蹄蹄向前冲42 分钟前
2024不一样的VUE3期末考查
前端·javascript·程序员
轻口味1 小时前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami1 小时前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
wakangda2 小时前
React Native 集成原生Android功能
javascript·react native·react.js
吃杠碰小鸡2 小时前
lodash常用函数
前端·javascript
emoji1111112 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼2 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250032 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
一个处女座的程序猿O(∩_∩)O2 小时前
vue3 如何使用 mounted
前端·javascript·vue.js