Abdullah Okay
Abdullah Okay

Reputation: 15

Opening a modal component with a button in another ccomponent using Vuetify

I have 2 components. Modal and Navbar. I'm trying to open Modal using a button in Navbar using vuex. I have a state called modalIsOpen. This states value changes from false to true when clicked on the button in Navbar but only a blank row is rendered as a modal and modal content is not shown. I could not figure out what is wrong.

At the beginning i thought it was a vuetify v-dialog problem. But ive tried other libraries too. And as i said nothing worked yet.

Here is the components ,app.vue and store.js.

AddUpdateModal.vue:

<template>
  <v-dialog>
    <v-card width="50%" height="50%">
      <v-card-title class="text-h5 grey lighten-2">
        Privacy Policy
      </v-card-title>
      <v-card-text>
        Lorem
      </v-card-text>
      <v-divider></v-divider>
      <v-card-actions>
        <v-spacer></v-spacer>
        <v-btn color="primary" text @click="dialog = false">
          I accept
        </v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script>
export default {

  name: "AddUpdateModal",
  components: {},

  data: () => ({}),
}
</script>

<style>
.v-card {
  display: block !important;
}

.v-easy-dialog {
  height: 500px !important;
}
</style>

NavBar.vue:

<template>
  <div id="Navbar">
    <v-row>
      <v-btn color="primary" @click.stop="openModal" rounded>
        Add / Update
      </v-btn>
      <v-btn color="primary" @click="closeModal" rounded>
        Refresh
      </v-btn>
    </v-row>
    <v-row>
      <v-divider class="grey darken-4"></v-divider>
    </v-row>
  </div>
</template>

<script>
export default {
  name: 'NavBar',

  components: {},

  data: () => ({}),

  methods: {
    openModal() {
      this.$store.commit('openModal');
    },
    closeModal() {
      this.$store.commit('closeModal')
    }
  },
}

</script>

App.vue:

<template>
  <v-app>
    <v-container>
      <NavBar />
      <br>
      <div class="parent">
        <!-- <AddButton></AddButton> -->
        <v-btn @click="konsol">Konsol</v-btn>
        <div id="modal" v-if="$store.state.modalIsOpen">
          <template>
            <AddUpdateModal></AddUpdateModal>
          </template>
        </div>
        <v-row>
          <v-col>
            <DataTable />
          </v-col>
          <v-divider class="grey darken-4" vertical inset></v-divider>
          <v-col>
            <PieChart />
          </v-col>
        </v-row>
      </div>
    </v-container>
  </v-app>
</template>

<script>
import NavBar from './components/NavBar.vue';
import PieChart from './components/PieChart.vue';
import DataTable from './components/DataTable.vue';
// import AddButton from './components/AddButton';
import AddUpdateModal from './components/AddUpdateModal';
// eslint-disable-next-line no-unused-vars
import store from './store/store'
// import axios from 'axios';

export default {
  name: 'App',

  components: {
    NavBar,
    AddUpdateModal,
    PieChart,
    DataTable,
    // AddButton,
  },

  created() {
    this.$store.dispatch("initApp")
  },

  data: () => ({
  }),

  methods: {
    konsol() {
      console.log("modalIsOpen", this.$store.state.modalIsOpen)
    }
  },


};
</script>

<style>
* {
  margin: 5px;
}

.v-dialog__container {
  display: unset !important;
  position: relative !important;
}
</style>

store.js:

import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    binance24HrData: [],
    modalIsOpen: false,
  },

    mutations: {
        initPortfolioDetails(state, newCoin) {
        state.binance24HrData = newCoin;
        },
        openModal(state) {
        state.modalIsOpen = true;
        },
        closeModal(state) {
        state.modalIsOpen = false;
        },
    },

    actions: {
        initApp(context) {
        axios
            .get("https://api2.binance.com/api/v3/ticker/24hr")
            .then((response) => {
            context.commit("initPortfolioDetails", response.data);
            console.log("Binance", response.data);
            });
        },

        openModal({ commit }) {
        commit("openModal");
        },

        closeModal({ commit }) {
        commit("closeModal");
        },
    },
    
    getters: {
        getCoinsDetails(state) {
        return state.binance24HrData;
        },
    },
});

export default store;

main.js:

import Vue from "vue";
import App from "./App.vue";
import vuetify from "./plugins/vuetify";
import store from "./store/store.js";

Vue.config.productionTip = false;

new Vue({
  vuetify,
  store,
  render: (h) => h(App),
}).$mount("#app");

Upvotes: 0

Views: 107

Answers (1)

Abdullah Okay
Abdullah Okay

Reputation: 15

I figured it out: all I had to do was add v-model to v-dialog. I thought it was unnecessary because I already had a v-if that wrapped the component containing the v-dialog. I assumed that with this requirement fulfilled, it should render the child component, but it didn't because I didn't have v-model in v-dialog.

Upvotes: 0

Related Questions