有没有一种正确的方法可以在 vuejs 中重置组件的初始数据?

IT技术 javascript mvvm vue.js
2021-03-10 00:15:39

我有一个包含一组特定起始数据的组件:

data: function (){
    return {
        modalBodyDisplay: 'getUserInput', // possible values: 'getUserInput', 'confirmGeocodedValue'
        submitButtonText: 'Lookup', // possible values 'Lookup', 'Yes'
        addressToConfirm: null,
        bestViewedByTheseBounds: null,
        location:{
            name: null,
            address: null,
            position: null
        }
}

这是一个模态窗口的数据,所以当它显示时我希望它从这个数据开始。如果用户从窗口取消,我想将所有数据重置为此。

我知道我可以创建一种方法来重置数据,然后手动将所有数据属性设置回原来的状态:

reset: function (){
    this.modalBodyDisplay = 'getUserInput';
    this.submitButtonText = 'Lookup';
    this.addressToConfirm = null;
    this.bestViewedByTheseBounds = null;
    this.location = {
        name: null,
        address: null,
        position: null
    };
}

但这似乎真的很草率。这意味着如果我对组件的数据属性进行了更改,我需要确保我记得更新重置方法的结构。这并不是绝对可怕,因为它是一个小的module化组件,但它让我大脑的优化部分尖叫。

我认为可行的解决方案是在ready方法中获取初始数据属性,然后使用保存的数据来重置组件:

data: function (){
    return {
        modalBodyDisplay: 'getUserInput', 
        submitButtonText: 'Lookup', 
        addressToConfirm: null,
        bestViewedByTheseBounds: null,
        location:{
            name: null,
            address: null,
            position: null
        },
        // new property for holding the initial component configuration
        initialDataConfiguration: null
    }
},
ready: function (){
    // grabbing this here so that we can reset the data when we close the window.
    this.initialDataConfiguration = this.$data;
},
methods:{
    resetWindow: function (){
        // set the data for the component back to the original configuration
        this.$data = this.initialDataConfiguration;
    }
}

但是initialDataConfiguration对象随着数据而变化(这是有道理的,因为在 read 方法中我们initialDataConfiguration正在获取数据函数的范围。

有没有办法在不继承范围的情况下获取初始配置数据?

我是不是想多了,还有更好/更简单的方法吗?

硬编码初始数据是唯一的选择吗?

6个回答
  1. 将初始数据提取到组件外部的函数中
  2. 使用该函数设置组件中的初始数据
  3. 在需要时重新使用该函数来重置状态。

// outside of the component:
function initialState (){
  return {
    modalBodyDisplay: 'getUserInput', 
    submitButtonText: 'Lookup', 
    addressToConfirm: null,
    bestViewedByTheseBounds: null,
    location:{
      name: null,
      address: null,
      position: null
    }
  }
}

//inside of the component:
data: function (){
    return initialState();
} 


methods:{
    resetWindow: function (){
        Object.assign(this.$data, initialState());
    }
}

您对 data 属性的功能是正确的,那是我草率。感谢您的编辑。
2021-04-17 00:15:39
做到了。谢谢!我对答案做了一个小的编辑,但这只是因为 vue 组件需要一个为数据返回的函数,而不仅仅是一个对象。您的答案概念绝对有效并且是正确的,编辑只是为了说明 vuejs 如何处理组件。
2021-04-19 00:15:39
对于这个问题 - [Vue 警告]:避免替换实例根 $data。改用嵌套数据属性,试试 this.$data.propName = "new value";
2021-05-07 00:15:39
它现在给出了一个错误: [Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.
2021-05-10 00:15:39
@SankalpSingha Vue 2.0 不允许你再这样做了。你可以Object.assign改用。这是工作代码:codepen.io/CodinCat/pen/ameraP?editors=1010
2021-05-12 00:15:39

要重置data当前组件实例中的组件,您可以尝试以下操作:

Object.assign(this.$data, this.$options.data())

我私下有抽象模态组件,它利用插槽来填充对话框的各个部分。当自定义模态包装抽象模态时,槽中引用的数据属于父组件范围。这是抽象模式的选项,每次显示自定义模式时都会重置数据(ES2015 代码):

watch: {
    show (value) { // this is prop's watch
      if(value) {
        Object.assign(this.$parent.$data, this.$parent.$options.data())
      }
    }
}

您当然可以微调您的模态实现 - 上面也可以在某个cancel钩子中执行

请记住,$parent不建议从 child中改变选项,但是我认为如果父组件只是自定义抽象模态而仅此而已,这可能是合理的。

这种技术现在给出了 VueJS 警告;stackoverflow.com/questions/40340561/...
2021-04-17 00:15:39
注意,这不会将上下文绑定到data. 因此,如果您thisdata方法中使用,则可以使用以下内容应用上下文:Object.assign(this.$data, this.$options.data.apply(this))
2021-04-30 00:15:39
这些方式与 location.reload() 相比有什么优势?
2021-05-03 00:15:39
@Carloslocation.reload完全重新加载网页,这在尝试重置个人组件状态时通常不是我们需要的。
2021-05-09 00:15:39

注意,Object.assign(this.$data, this.$options.data())不要将上下文绑定到 data() 中。

所以使用这个:

Object.assign(this.$data, this.$options.data.apply(this))

cc 这个答案最初是在这里

有没有typescript安全的版本?
2021-04-17 00:15:39
即插即用的答案,就像一个魅力。
2021-04-18 00:15:39

如果您对警告感到恼火,这是一种不同的方法:

const initialData = () => ({})

export default {
  data() {
    return initialData();
  },
  methods: {
    resetData(){
      const data = initialData()
      Object.keys(data).forEach(k => this[k] = data[k])
    }
  }
}

无需弄乱 $data。

我不得不将数据重置为子组件内的原始状态,这对我有用:

父组件,调用子组件的方法:

<button @click="$refs.childComponent.clearAllData()">Clear All</button >
       
<child-component ref='childComponent></child-component>

子组件:

  1. 在外部函数中定义数据,
  2. 通过定义的函数引用数据对象
  3. 定义由父组件调用的 clearallData() 方法
function initialState() {
  return { 
    someDataParameters : '',
    someMoreDataParameters: ''
  }
}

export default {
   data() {
    return initialState();
  },
methods: {
  clearAllData() {
    Object.assign(this.$data, initialState());
},