Có cách nào thích hợp để đặt lại dữ liệu ban đầu của một thành phần trong vuejs không?


92

Tôi có một thành phần với một bộ dữ liệu bắt đầu cụ thể:

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
        }
}

Đây là dữ liệu cho một cửa sổ phương thức, vì vậy khi nó hiển thị, tôi muốn nó bắt đầu với dữ liệu này. Nếu người dùng hủy khỏi cửa sổ, tôi muốn đặt lại tất cả dữ liệu thành này.

Tôi biết tôi có thể tạo một phương pháp để đặt lại dữ liệu và chỉ cần đặt thủ công tất cả các thuộc tính dữ liệu về ban đầu:

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

Nhưng điều này có vẻ thực sự cẩu thả. Có nghĩa là nếu tôi thực hiện thay đổi đối với các thuộc tính dữ liệu của thành phần, tôi sẽ cần đảm bảo rằng tôi nhớ cập nhật cấu trúc của phương thức đặt lại. Điều đó không hoàn toàn kinh khủng vì nó là một thành phần mô-đun nhỏ, nhưng nó khiến phần tối ưu hóa trong não của tôi kêu gào.

Giải pháp mà tôi nghĩ sẽ hiệu quả là lấy các thuộc tính dữ liệu ban đầu trong một readyphương thức và sau đó sử dụng dữ liệu đã lưu đó để đặt lại các thành phần:

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;
    }
}

Nhưng initialDataConfigurationđối tượng đang thay đổi cùng với dữ liệu (điều này có ý nghĩa vì trong phương thức đọc, chúng ta initialDataConfigurationđang nhận phạm vi của hàm dữ liệu.

Có cách nào để lấy dữ liệu cấu hình ban đầu mà không kế thừa phạm vi không?

Tôi có suy nghĩ quá nhiều về điều này và có cách nào tốt hơn / dễ dàng hơn để làm điều này không?

Mã cứng dữ liệu ban đầu có phải là lựa chọn duy nhất không?


Bạn đang sử dụng v-show hoặc v-if để hiển thị phương thức?
Rwd

Tôi đang sử dụng bootstrap cho css nên tôi đang sử dụng nó được xây dựng trong phương thức thúc đẩy jquery để hiển thị và ẩn. Vì vậy, về cơ bản phần cửa sổ của thành phần luôn ở đó, chỉ bị ẩn.
Chris Schmitz

Câu trả lời:


125
  1. trích xuất dữ liệu ban đầu vào một hàm bên ngoài thành phần
  2. sử dụng hàm đó để đặt dữ liệu ban đầu trong thành phần
  3. sử dụng lại chức năng đó để thiết lập lại trạng thái khi cần thiết.

// 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());
    }
}


5
Điều đó đã làm được. Cảm ơn! Tôi đã thực hiện một chỉnh sửa nhỏ cho câu trả lời, nhưng chỉ vì một thành phần vue yêu cầu một hàm được trả về cho dữ liệu thay vì chỉ một đối tượng. Khái niệm câu trả lời của bạn chắc chắn hoạt động và chính xác, việc chỉnh sửa chỉ để giải thích cách vuejs xử lý các thành phần.
Chris Schmitz

3
Bạn nói đúng về chức năng cho thuộc tính dữ liệu, đó là tôi đã cẩu thả. Cảm ơn vì đã chỉnh sửa.
Linus Borg

13
Bây giờ đưa ra một lỗi:[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.
Sankalp Singha

34
@SankalpSingha Vue 2.0 không cho phép bạn làm điều đó nữa. Bạn có thể sử dụng Object.assignthay thế. Đây là mã làm việc: codepen.io/CodinCat/pen/ameraP?editors=1010
CodinCat

3
Đối với vấn đề này - [Vue cảnh báo]: Tránh thay thế dữ liệu gốc $ phiên bản. Sử dụng các thuộc tính dữ liệu lồng nhau, hãy thử điều này. $ Data.propName = "new value";
Stanislav Ostapenko

32

Để đặt lại thành phần datatrong phiên bản thành phần hiện tại, bạn có thể thử cách này:

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

Riêng tư, tôi có thành phần phương thức trừu tượng sử dụng các khe để lấp đầy các phần khác nhau của hộp thoại. Khi phương thức tùy chỉnh bao bọc phương thức trừu tượng đó, dữ liệu được giới thiệu trong các vị trí thuộc phạm vi thành phần mẹ . Đây là tùy chọn của phương thức trừu tượng để đặt lại dữ liệu mỗi khi phương thức tùy chỉnh được hiển thị (mã ES2015):

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

Tất nhiên, bạn có thể tinh chỉnh việc triển khai phương thức của mình - phần trên cũng có thể được thực thi trong một số cancelhook.

Hãy nhớ rằng $parentkhông khuyến khích đột biến tùy chọn từ con, tuy nhiên tôi nghĩ có thể hợp lý nếu thành phần cha chỉ đang tùy chỉnh phương thức trừu tượng và không có gì khác.


1
Kỹ thuật này hiện đưa ra một cảnh báo VueJS; xem stackoverflow.com/questions/40340561/…
Kivi Shapiro

7
Thận trọng, điều này không ràng buộc ngữ cảnh vào data. Vì vậy, nếu bạn đang sử dụng thisvào bạn dataphương pháp bạn có thể áp dụng các bối cảnh với:Object.assign(this.$data, this.$options.data.apply(this))
Ifnot

Ưu điểm của cách này so với location.reload () là gì?
Carlos

29

Thận trọng, Object.assign(this.$data, this.$options.data())không ràng buộc ngữ cảnh vào dữ liệu ().

Vì vậy, hãy sử dụng cái này:

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

cc câu trả lời này ban đầu ở đây


3

Nếu bạn thấy khó chịu với các cảnh báo, đây là một phương pháp khác:

const initialData = () => ({})

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

Không cần phải làm rối với dữ liệu $.


2

Tôi đã phải đặt lại dữ liệu về trạng thái ban đầu bên trong thành phần con, đây là những gì phù hợp với tôi:

Thành phần cha, gọi phương thức của thành phần con:

     <button @click="$refs.childComponent.clearAllData()">Clear All</button >

     <child-component ref='childComponent></child-component>

Thành phần con:

  1. xác định dữ liệu trong một hàm bên ngoài,
  2. gán đối tượng dữ liệu cho và bên ngoài chức năng
  3. định nghĩa phương thức clearallData () sẽ được gọi bởi thành phần mẹ

    function initialState() {
       return { 
         someDataParameters : '',
         someMoreDataParameters: ''
              }
      }
    
    export default {
       data() {
        return initialState();
      },
        methods: {
      clearAllData() {
      Object.assign(this.$data, initialState());
    },
    
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.