如何在mounted()上获取状态vuex并传递给数据?

时间:2019-04-23 02:31:55

标签: vue.js vuex

我想通过props组件输入传递状态vuex,因为我想在组件输入上输入默认值。我必须在第一次页面加载时从vuex获取数据,但是状态vuex为空。我在Mounted()上使用了Subcribe api vuex,但是无法传递给数据。

form.vue

<template>
input-modal(
  :data="namesAll"
  :validations="'required'"
  name="child"
  v-model="form.input1"
  :username="form.input1"
  class-input="form-control-lg"
  img-icon="https://img.icons8.com/ios/20/495057/user-filled.png"
  placeholder="Child"
  )

</template>

<script>
import inputModal from "~/components/form/inputModal.vue";
...

data: () => ({
    namesAll: []
  }),

mounted() {
    this.$store.dispatch("names/getNames");
    // test load vuex
    this.loadData();

    // get data mutation
    this.$store.subscribe((mutation, state) => {
      // console.log(state.names.all);
      if (mutation.type == "GET_ALL") {
        this.namesAll = state.names.all;
        console.log("na", state.names.all); // empty data
      }
    });
  },

methods: {
    loadData() {
      console.log("data vuex", this.$store.state.names.all); // data vuex empty
    }
  }

...

inputModal.vue

<template lang="pug">
  .input-modal

    .input-group(ref="inputGroup")
        .input-group-prepend(v-if="inputIcon || imgIcon")
          span.input-group-text
            i(v-if="inputIcon" :class="inputIcon")
            img(v-if="imgIcon" :src="imgIcon")

        input.form-control(
          type="text" :placeholder="placeholder"
          v-model="input" :class="[classInput, {'is-invalid': errors.has(name)}]"
          @focus="focus(true)" autocomplete="off"
          v-validate="validations" :name="name"
          )
        .invalid-feedback(v-if="errors.has(name)") {{ errors.first(name) }}

    <!-- modal -->
    transition(name="fade")
      .modal(v-show="focused" ref="modal")
        .modal-dialog.modal-lg(role="document")
          .modal-content
            .modal-header.bg-primary.text-white.justify-content-between
              h6.modal-title Pilih Nama
              button.btn.btn-link.p-0(@focus="focus(false)")
                .h5.m-0.text-white x

            .modal-body
              .row
                .col-md-6.col-12
                  ul.list
                    li.list-item(
                      v-for="name in data" 
                      :key="name.username"
                      @click="select(name.username)"
                      )
                      .name 
                        span.mr-3 {{ name.username }}
                        span.text-muted {{ name.name }}
</template>

<script>
export default {
  inject: ["$validator"],
  props: {
    data: { type: [Object, Array], required: false },
    inputIcon: { type: String, required: false, default: "" },
    imgIcon: { type: String, required: false, default: "" },
    placeholder: { type: String, required: false, default: "" },
    classInput: { type: String, required: false, default: "" },
    username: { type: String, required: true },
    validations: { type: [String, Object], default: "" },
    name: { type: String, required: true }
  },

  data: () => ({
    focused: false,
    input: "",
    selected: ""
  }),

  watch: {
    errors: function(error) {
      this.$emit("has-error");
    },

    username: {
      handler: function(val) {
        if (val == "" || val == undefined) {
          this.input = "";
          this.selected = "";
          return;
        }
        // console.log(val, this.data);
        // can't read vuex state
        this.select(val);
      },
      immediate: true
    }
  },

  created() {
    this.input = this.username || "";
  },

  mounted() {
    // console.log("im", this.data);
    if (this.username !== "") this.select(this.username);
  },

  updated() {
    this.$emit("input", this.selected);
  },

  methods: {
    focus(bol) {
      this.focused = bol;
    },
    select(username) {
      this.input = this.nameInfo(username);
      this.selected = username;
      this.focus(false);
    },
    nameInfo(username) {
      let names = this.data.filter(name => name.username == username);
      console.log("filter", names);
      if (names.length) return `${names[0].name} (${names[0].username})`;
    }
  }
};
</script>

我希望在首次加载页面时从状态vuex获取数据,并且可以传递给道具组件。

2 个答案:

答案 0 :(得分:0)

一旦您从getNames加载了数据,就可以使用mapState轻松地在组件中镜像状态:

computed: {
  ...mapState('namesAll', state => state.namesAll)
},

答案 1 :(得分:0)

您可以使用mapGetters中的vuex。 这是一个例子:

vuex


const state = {
  names: {
    all: []
  }
}

const getters = {
  nameAll: state => state.name.all
}

view.vue

<template>
  <span>{{ nameAll }}</span>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters(['nameAll'])
  }
}
</script>