Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

数据绑定 #3

Open
09473ZH opened this issue Apr 3, 2024 · 0 comments
Open

数据绑定 #3

09473ZH opened this issue Apr 3, 2024 · 0 comments

Comments

@09473ZH
Copy link
Owner

09473ZH commented Apr 3, 2024

其实没什么技术含量的东西,只是很基础。

React 的受控组件

在 React 中,有“受控组件”的概念。所谓的受控组件,我们可以简单理解为由 React 的状态控制的组件。让我们来看一个例子:

function MyForm() {
 const [myValue, setMyValue] = useState('')

  function handleChange(event) {
    setMyValue(event.target.value)
  }

  return (
    <div>
      <input type="text" value={myValue} onChange={handleChange} />
      <p> {myValue}</p>
    </div>
  );
}

需要注意的是,“您传递给受控组件的 value 不应为 undefinednull”。

我们使用 **React 组件中的 “state”(useState or this.state)**进行数据管理,通过事件处理函数( onChange) 进行数据的更新。对于一个受控组件来说,这两者是缺一不可的。(例外:没有 onChange 事件处理程序的受控只读输入框,需要标记 readOnly 属性)

反之,如果一个组件不使用 React 的状态管理,可以认为它是一个非受控组件。例如:

<input defaultValue={something} />

非受控组件通常会用在无需控制组件的场景(这不是废话),比如仅仅只是数据的展示。

React 的数据绑定,就是通过受控组件实现的。上面受控组件的例子:

Untitled

发现 josh wcomeau 也提到了这个问题,并写了一篇很详细的文章

Vue 中的 “双向绑定”

事实上,Vue 和 React 都是遵循的单向数据流。
vue: "所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。"
react: The component at the top of the hierarchy (FilterableProductTable) will take your data model as a prop. This is called one-way data flow because the data flows down from the top-level component to the ones at the bottom of the tree.
不过,Vue 提供了一个语法糖“v-model”,让组件看起来是实现了双向绑定:

<input v-model="text">

在输入框等表单元素上使用v-model时,可以将数据绑定和事件处理两者结合起来,从而实现类似双向数据绑定的效果。但是本质上,它是结合了:

  1. :value用于将数据从父组件传递到子组件。
  2. @input用于在子组件发生变化时将更新通知给父组件。

就像这样:

<input
  :value="text"
  @input="event => text = event.target.value">

在自定义组件中,当你在一个组件上使用v-model时,实质上 Vue 会自动解析为:

  • value属性绑定到子组件的数据(常常通过 props 传递)。
  • 监听子组件触发的input事件,并执行一个方法(通常是更新父组件的数据)。

其实和 React 也差不多,但是不同的是,Vue 倾向于提供更多内置的抽象(Vue 还提供了一些修饰符 trim lazy number 不得不说,非常好用)和语法糖,react则是显式地通过状态更新来控制数据流。

就个人体验来说,我当然更喜欢直接用 v-model 啦,非常省事。

#2 中提供的 case 也可以用 defineModel改写,但是为了更方便理解,所以没有采用defineModel的写法。
https://cn.vuejs.org/guide/components/v-model.html 可以跟着教程试一下。

在 Vue2 中,使用 v-model 指令时必须使用名为 value 的 prop。如果需要使用其他的 prop,就要使用 v-bind.sync 。( 简写为:[propName].sync.sync 修饰符比 v-model 更灵活,因为 .sync 可以用于任意数量的属性,而 v-model 只限于一个。不过在 Vue3 中就没有这个问题了,.sync 也被废除掉了。

Just an example for .sync :

// parent
<template>
  <child-component :visible.sync="parentValue"></child-component>
</template>

// child
<script>
export default {
  props: ['visible'],
  methods: {
    updateValue(newValue) {
      this.$emit('update:visible', newValue)
    }
  }
}
</script>

很多文章喜欢把双向绑定的原理写成响应式的原理,其实我有点晕,在我看来这明明是两个东西。
Vue 的响应式原理,2 和 3 有很大的区别,网上有很多文章,我觉得吧还是直接看文档和 《Vue.js 设计与实现》(讲得很深,好多看不懂也消化不了,尽力了——!)比较好,其他太多了讲来讲去也就那些东西。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant