Search code examples
vue.jsvuejs3v-modelslots

How to use v-model on a slot in vue 3?


I am trying to find a way to use a model component I made but with the ability to close the model from one of the slots.

I can pass data to the slot but not with v-model and dont believe I can change the slot prop to close the model open state

https://v3.vuejs.org/guide/component-slots.html#scoped-slots

this is my popover in use

<PopoverModal>
    <template #toggleButton>
      <button>A</button>
    </template>
    <template #modalContent="{ toggleModal }">
      <div style="color: #fff; height: 400px; width: 400px;">test2 {{toggleModal}}</div>
      <button @click="toggleModal = false">click me</button>
    </template>
  </PopoverModal>

within the popover component I am trying to be able to send the state var

<slot name="modalContent" :toggleModal="showSelector"></slot>

I'm guessing the answer is its not possible and to find another way but if anyone knows that would be great thanks


Solution

  • You can't change PopoverModal data directly using template, but you can bind some setter methods.

    Some example code:

    HelloWorld.vue

    <template>
      <div class="hello">
        <PopoverModal>
          <template #toggleButton>
            <button>A</button>
          </template>
          <template #modalContent="modelContent">
            <div style="color: #fff; height: 400px; width: 400px;">test2 {{modelContent.toggleModal}}</div>
            <button @click="modelContent.setToggleModal(false)">click me</button>
          </template>
        </PopoverModal>
      </div>
    </template>
    
    <script>
    import PopoverModal from './PopoverModal'
    export default {
      components: {PopoverModal},
      name: 'HelloWorld',
      data () {
        return {
        }
      }
    }
    </script>
    

    PopoverModal.vue

    <template>
      <div>
        <slot name="toggleButton"></slot>
        <slot name="modalContent" :toggleModal="showSelector" :setToggleModal="setShowSelector"></slot>
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          showSelector: true
        }
      },
      methods: {
        setShowSelector(showSelector) {
          this.showSelector = showSelector;
        },
      }
    }
    </script>