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

请教关于 props 单向数据流

  •  
  •   waiaan · 2022-12-23 17:18:18 +08:00 · 1489 次点击
    这是一个创建于 483 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <template>
        <el-select
          class="mr__m"
          :value="value"
          placeholder="请先选择分类"
          filterable
          @input="change($event)"
        >
          <el-option
            v-for="(option, index) in list"
            :key="'categoryOptions' + index"
            :label="option.dictValue"
            :value="option.dictKey"
          />
        </el-select>
    </template>
    <script>
    export default {
      props: {
        list: {
          type: Array,
          default: _ => []
        },
        value: {
          type: [String, Object]
        }
      },
      methods: {
        change(val) {
          this.$emit('input', val)
        }
      }
    }
    </script>
    

    这种封装方式是不是违背了数据单项流动的原则?好一点的写法应该是怎么样的?

    谢谢。

    8 条回复    2023-01-03 08:51:07 +08:00
    wu67
        1
    wu67  
       2022-12-23 17:28:17 +08:00
    按我的理解, 单向的意思是他只能用父传给子、祖先传给后代, 同时不应直接改这个值.
    直接改可能会有什么情况呢? 界面更新不及时(响应性问题)、追踪困难(无法知道是哪里的代码变更了数据).

    你可以直接 watch value, 然后赋值给另一个变量 viewValue, select 绑定 viewValue, select 组件选中的时候, 通过事件通知父组件变更 value 的值.
    IvanLi127
        2
    IvanLi127  
       2022-12-23 20:11:46 +08:00 via Android
    看起来不违反,能圈个重点吗?
    zsj1029
        3
    zsj1029  
       2022-12-23 22:21:16 +08:00 via iPhone
    强烈尝试 mithril.js 可以用 jsx 语法,小而强大,前端目前越发的无限复杂,90%都在做无用功
    zsj1029
        4
    zsj1029  
       2022-12-23 22:29:55 +08:00 via iPhone
    @zsj1029 angular vue react 都用来写过项目,最后发现 mithriljs 足矣,当然自己要会写 ui ,如果只是套三大的各类现成 ui 库,还是拿来主义效率高
    V1Eerie
        5
    V1Eerie  
       2022-12-23 22:31:45 +08:00
    我觉得没有违反。最好保证每次改变值的时候都能及时更新。
    jqtmviyu
        6
    jqtmviyu  
       2022-12-23 22:49:01 +08:00
    我觉得没有违反。 数据还是在父组件那里管理,子组件只是通知父组件更新。

    如果子组件直接把原始数据改了,这份数据又在其他地方用到,追踪起来就乱了,根本不知道是哪位子组件改的。
    bojackhorseman
        7
    bojackhorseman  
       2022-12-24 00:12:17 +08:00 via iPhone
    这样写 vue 会警告的吧,建议用 writeable computed 来处理,get 返回 value 的值,set 调用 this.$emit(input, val)
    waiaan
        8
    waiaan  
    OP
       2023-01-03 08:51:07 +08:00
    @wu67
    @bojackhorseman
    这样有个问题,就是子组件抛出事件后,又会触发子组件上 value 的 watcher

    @IvanLi127
    @V1Eerie
    @jqtmviyu
    子组件不是通过抛出事件来改变父组件中的值,而是直接修改。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2779 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:20 · PVG 21:20 · LAX 06:20 · JFK 09:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.