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

bug: component 组件中定义的 data 数据对象被共享 #43

Open
proc07 opened this issue Jun 19, 2019 · 7 comments
Open

bug: component 组件中定义的 data 数据对象被共享 #43

proc07 opened this issue Jun 19, 2019 · 7 comments

Comments

@proc07
Copy link

proc07 commented Jun 19, 2019

例子

在page页面中引用了 2 次 form 组件,导致 formData 对象数据公用,当输入一个框时,第二个文本框值自动同步,surname 参数完好!

我在原生小程序中不会出现该问题。

// page
<template>
  <view>
    <form></form>
    <form></form>
</view>
</template>
// form component
<template>
  <view class="form-validate">
    <view class="form-item">
      <view class="label">
        <text class="red">*</text></view>
      <view class="box">
        <input type="text" maxlength="50" placeholder="请输入汉字姓" value="{{ surname }}" bindinput="surnameInputChange" />
      </view>
       <view class="box">
        <input type="text" maxlength="50" placeholder="请输入汉字姓" value="{{ formData.surname }}" bindinput="surnameformDataInputChange" />
      </view>
    </view>
  </view>
</template>

<script>
import { Component } from '@tinajs/tina'

Component.define({
  data: {
    formData: {
      surname: ''
    },
    surname: '',
    __deep__: true // 1
  },
 // 2
  // data() {
  //   return {
  //     formData: {
  //       surname: ''
  //     },
  //     surname: ''
  //   }
  // },
methods: {
    surnameformDataInputChange({ detail: { value } }) {
      this.data.formData['surname'] = value
      this.setData({
        formData: this.data.formData
      })
    },
    surnameInputChange({ detail: { value } }) {
      this.setData({
        surname: value
      })
    },
  }
});
</script>

目前解决方案

  • data 中加个 __deep__: true 来标示进行对 对象 深拷贝解决。
  function SigmundData(plain) {
    var _this = this;

    classCallCheck(this, SigmundData);

    forOwn(plain, function (value, key) {
      _this[key] = value;
+     if (plain && plain.__deep__) {
+       _this[key] = deepClone1(value);
+     }
    });

    Object.defineProperty(this, '__signatures', {
      enumerable: false,
      writable: true
    });

    this.sign();
  }

如果 data 可以定义是个函数来解决那就更好 🤔

@imyelo
Copy link
Member

imyelo commented Jun 19, 2019

确认能重现。

通过避免直接修改 this.data 可以暂时避开这个问题:

-      this.data.formData['surname'] = value
       this.setData({
-        formData: this.data.formData
+        ...this.data.formData,
+        surname: value,
       })

imyelo added a commit that referenced this issue Jun 19, 2019
@imyelo imyelo closed this as completed in cd292da Jun 19, 2019
@imyelo
Copy link
Member

imyelo commented Jun 19, 2019

cd292da 修复。
已发布 v1.7.1

@proc07
Copy link
Author

proc07 commented Jun 20, 2019

@imyelo Tks, 我看你代码中初始化数据时候,每次都进行clone 数据,这样会不会有性能问题呢!需要的时候才进行clone

@imyelo
Copy link
Member

imyelo commented Jun 20, 2019

@imyelo Tks, 我看你代码中初始化数据时候,每次都进行clone 数据,这样会不会有性能问题呢!需要的时候才进行clone

clone 确实对性能有影响。或者可以考虑把 data 的 API 改为 function,同时也向下兼容 object;仅当类型为 object 时进行 clone。

@imyelo imyelo reopened this Jun 20, 2019
@proc07
Copy link
Author

proc07 commented Jun 20, 2019

@imyelo Tks, 我看你代码中初始化数据时候,每次都进行clone 数据,这样会不会有性能问题呢!需要的时候才进行clone

clone 确实对性能有影响。或者可以考虑把 data 的 API 改为 function,同时也向下兼容 object;仅当类型为 object 时进行 clone。

这个可以 👍

@proc07
Copy link
Author

proc07 commented Jun 20, 2019

确认能重现。

通过避免直接修改 this.data 可以暂时避开这个问题:

-      this.data.formData['surname'] = value
       this.setData({
-        formData: this.data.formData
+        ...this.data.formData,
+        surname: value,
       })

 我把代码换成下面形式,不会触发这个问题了。这么奇怪!!

this.setData({
  'formData.surname': value
})

@imyelo
Copy link
Member

imyelo commented Jun 20, 2019

因为这个问题的触发条件是直接修改 this.data

另外 tina 不支持数据路径的 setData,你的示例更新后 data 应该变成了 { "formData.surname": "somevalue" },跟原来效果不太一样。

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

2 participants