VueJS:替换/更新阵列

时间:2017-09-07 12:08:18

标签: javascript vue.js vuejs2

我目前有一个对象数组,我正在渲染到一个表。我试图按照Vuejs提供的例子来使用"单一的事实来源"在同一页面上的多个vues之间共享。

总的来说,我试图在触发vue1.refresh()的时候使用它,所有的vues都会在"单一事实来源时更新他们的数据"已更新。但是,self.surveys =调查;仅更新vue1上的数据。

注意:我正在关注https://vuejs.org/v2/guide/state-management.html

的指南
// The single source of truth
var cache = {
    data: [{...}] // Array of objects
}

var vue1 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        refresh: function(){
            var self = this;                 

            // After getting data back from an ajax call
            .done(function(surveys) {
                self.surveys = surveys;
            });
        },
    }
});

var vue2 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        // Methods
    }
});

4 个答案:

答案 0 :(得分:1)

问题是,您正在使用new而非共享对象替换先前分配给survey变量的共享Cache对象。和解决方案?不要试图改变缓存对象。只需使用Vuex。 Vuex是一种简单,真实的“Vue方式”解决方案。

// The single source of truth
var cache = {
    data: [{...}] // Array of objects
}

var vue1 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        refresh: function(){
            var self = this;                 

            // After getting data back from an ajax call
            .done(function(surveys) {
                self.surveys = surveys; // Problem is right here

            });
        },
    }
});

var vue2 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        // Methods
    }
});

试试这个例子,它就像你的代码一样 - 不正确的方式:

var cache = {
  key1: 'Value1'
}

var vue1 = new Vue({
  el: '#app1',
  data: {
    surveys: cache
  },
  methods: {
    replace () {
      this.surveys = {key1: 'Replaced'}
    }
  }
})

var vue2 = new Vue({
  el: '#app2',
  data: {
    surveys: cache
  },
  methods: {
    replace () {
      this.surveys = {key1: 'Replaced'}
    }
  }
})
<script src="https://unpkg.com/vue@2.4.2/dist/vue.min.js"></script>

<div id="app1">
  Input for Vue1: <input type="text" v-model="surveys.key1">
  <button @click="replace">Replace</button>
  <p>{{ surveys.key1 }}</p>
</div>

<div id="app2">
  Input for Vue1: <input type="text" v-model="surveys.key1">
  <button @click="replace">Replace</button>
  <p>{{ surveys.key1 }}</p>
</div>

然后尝试使用Vuex这个例子,你可以自由地替换“缓存对象”,并且replacint会影响其他实例:

const store = new Vuex.Store({
  state: {
    cache: {
      key1: 'Value1'
    }
  },
  mutations: {
    replace (state) {
      state.cache = {key1: 'Replaced'}
    }
  }
})

var vue1 = new Vue({
  el: '#app1',
  store,
  computed: {
    surveys () {
      return this.$store.state.cache
    }
  },
  methods: Vuex.mapMutations([
    'replace'
  ])
})

var vue2 = new Vue({
  el: '#app2',
  store,
  computed: {
    surveys () {
      return this.$store.state.cache
    }
  },
  methods: Vuex.mapMutations([
    'replace'
  ])
})
<script src="https://unpkg.com/vue@2.4.2/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuex@2.4.0/dist/vuex.min.js"></script>

<div id="app1">
  Input for Vue1: <input type="text" v-model="surveys.key1">
  <button @click="replace">Replace</button>
  <p>{{ surveys.key1 }}</p>
</div>

<div id="app2">
  Input for Vue1: <input type="text" v-model="surveys.key1">
  <button @click="replace">Replace</button>
  <p>{{ surveys.key1 }}</p>
</div>

答案 1 :(得分:0)

您需要改变数组,而不是替换它。

Array.prototype.splice可以为您执行此操作,如果您不想按照Vanojx1的建议使用Vuex之类的内容。

Splice需要特定的元素,而不是插入的完整数组。因为你有一个你想要使用的数组,你需要清除旧数组,语法有点奇怪......你传递这个,开始,删除的数量(整个长度) ,然后添加元素(从新数组连接)。

Array.prototype.splice.apply([self.surveys, 0, self.surveys.length].concat(surveys));

答案 2 :(得分:0)

正如之前的评论中所述,您可以使用vuex来完成您的需求,每当您需要在不同组件之间传递数据时,您可以使用eventBus或上下传递props来执行此操作组件之间。

如果您的应用程序需要传递大量数据并接收它,您可以使用vuex,首先需要install it,然后您可以这样做:

你应该把方法切掉并放置已安装的(),它会在组件加载时触发,我认为这是你需要的

var vue1 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {

    }.
    mounted() {
      var self = this;                 

      // After getting data back from an ajax call
      .done(function(surveys) {
      self.surveys = surveys;
      });
    }
});

当你将响应传递给vuex商店时,你可以使用这样的突变来实现:

this.$store.mutation('handlerFunction', self.surveys)

在vuex中你需要在变异中包含处理函数

  mutations: {
    // appends a section to the tree
    handlerFunction: (state, dataReceived) => {
      //then you can do
      state.surveys = dataReceived
    },

然后在你的另一个组件中,你可以通过一个getter接收它,逻辑与更多deaill相同的watch vuex,你有这里的主要连接逻辑。

希望它有所帮助!

答案 3 :(得分:0)

Vue有两个原则可以帮到你:

  1. 在Vue中,每个data项都是真理的来源。
  2. 只有data项目的所有者才能对其进行修改。
  3. 在您的示例中,您有三个事实来源:您想要成为单一来源的那个,以及另外两个从中初始化的来源。而且,你想成为真理之源的那个不是data项,它在Vue之外。

    首先,您应该有一个代表整个应用程序的Vue,并定义代表应用程序级状态的任何数据:

    new Vue({
      el: '#app',
      data: {
        cache: {
          data: [...]
        }
      }
    });
    

    您创建的两个Vue对象应该是应用程序Vue的子对象,也就是components

    父母通过props告诉孩子真相是什么。孩子可以通过向父母发出events来建议改变真相,但孩子不会直接修改真相。这使得所有真相管理都集中在一个地方。