How to remove slot-scope in vue2.7 - vue.js

I upgraded my vue application to vue2.7 and I want to remove slot-scope from my application as it is removed in vue3. So in the examples, I see this for vue2:
<ItemList>
<template slot="heading" slot-scope="slotProps">
<h1>My Heading for {{ slotProps.items.length }} items</h1>
</template>
</ItemList>
In Vue 3 it is changed to this:
<ItemList>
<template v-slot:heading="slotProps">
<h1>My Heading for {{ slotProps.items.length }} items</h1>
</template>
</ItemList>
So in my application slot-scope is used in default:
<template slot-scope="scope">
...
</template>
So how can I remove slot-scope from my application and also for vue2.7, will it be supported?

slot-scope was deprecated in Vue2 and will never return back (even in Vue3), the syntax has just changed.
So rather than writing this: slot-scope="slotProps" you need to have the following #default="slotProps".
All the details are available here: https://v2.vuejs.org/v2/guide/components-slots.html#Scoped-Slots-with-the-slot-scope-Attribute
# being a shorthand for v-slot as explained here: https://v2.vuejs.org/v2/guide/components-slots.html#Named-Slots-Shorthand

Related

Vue-multiselect - Vue3 - Slots not working

I'm trying to recreate the following example from Vue-multiselect document in Vue 3 but I can't seem to make it work.
<multiselect
v-model="value"
:options="options"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:preserve-search="true"
placeholder="Pick some"
label="name"
track-by="name"
:preselect-first="true">
<template slot="selection" slot-scope="{ values, search, isOpen }">
<span
class="multiselect__single"
v-if="values.length"
v-show="!isOpen">
{{ values.length }} options selected
</span>
</template>
</multiselect>`
The documentation states that "Documentation for v3.0.0 is the same as for v2.x as it is mostly backward compatible." As there's no specific examples or notes about using slots in Vue 3 I thought that if I changed the component name from 'multiselect' to 'VueMultiselect' it would work but it's not.
The select part is working just fine but when I close the dropdown the custom template doesn't show. It's just the normal tags.
Am I missing something or is the feature not fully migrated to Vue 3?
VueMultiselect's documentation concerning named slots is out of date when it comes to Vue 3 syntax. slot and slot-scope attributes were deprecated in Vue 2.6 (but will continue to be supported in Vue 2.x going forward), and have been completely removed in Vue 3. Your slot in Vue 3 should be written like so:
<template v-slot:selection="{ values, search, isOpen }">
or short-hand:
<template #selection="{ values, search, isOpen }">
Documentation with more information: Named Scoped Slots in Vue 3

Vue slots props inside blade template

I have a Vue3 application that mounts on a blade/laravel. In one blade temlate, I have a Vue3 component (zest-dropzone) in which I insert a slot:
<template>
...
<slot name="hits" :button-label="buttonLabel" :files="files" :type="type" :state="state"></slot>
</template>
<script>
...
</script>
Inside the blade template, I have the following:
<zest-dropzone
accepted-files=".psd,application/pdf,audio/*,image/*,video/*"
button-label="{{ Lang::get('admin/button.edit') }}"
categories="{{ json_encode($categories) }}"
type="files">
<template #hits="hitsProps">
#{{ hitsProps.type }}
<zest-dropzone-files-preview :hitsProps="hitsProps" :button-label="buttonLabel" :files="files" :type="type" :state="state"></zest-dropzone-files-preview>
</template>
</zest-dropzone>
ZestDropzoneFilesPreview is another component which is registered globally and is technically rendered on the page, however the props are never coming no matter what I try.
Within the blade template, #{{ hitsProps.type }} renders correctly and the value type exists on hitsProps, however when I try to pass it in the next component, it doesn't come through and I get undefined inside ZestDropzoneFilesPreview.
Anyone knows how to deal with this? Thanks.
Fixed it, props were not passed accordingly (hitsProps -> hits-props).

Vue component within code block, Vue attempting to render the template

i'm trying to display example Vue component's within my documentation, however Vue is also recognizing the template within my Vue component.
vehicle-documents is not a registered component, and is also put into the following code:
Vue.config.ignoredElements = ['slide', 'slider', 'vehicle-documents'];
So Vue is ignoring the component itself:
If you want the modal make sure you add the click event and call the `open` function, and pass the `document` into this function call, as seen below.
```html
<vehicle-documents class="app" vehicle-id="">
<template v-slot:default="slotProps">
<button #click="slotProps.open(slotProps.document)">
{{ slotProps.document.name }}
</button>
</template>
</vehicle-documents>
```
How can I make Vue ignore the template block? I need Vue on this page, so it's not a simple case of just removing Vue.
Try this, add v-pre and type="text/x-template"
<vehicle-documents class="app" vehicle-id="">
<template v-pre type="text/x-template">
<button #click="slotProps.open(slotProps.document)">
{{ slotProps.document.name }}
</button>
</template>
</vehicle-documents>

How to pass v-model to parent in vue-multiselect

i have two components.
One is vselect template and wrapper for vue-multiselect.
<template lang="pug">
field-wrapper.field(:label="label" :caption="caption" :error="error")
multiselect(v-model="value" :options="options")
</template>
Second is page.vue where im including it
vselect(v-model="select.value" :options='select.options')
p {{ select.value }}
But v-model works only inside vselect, how i cant pass selected data to page.vue, from vselect? I cant use new method for emit in page.vue. Vue-multiselect works only with v-model i guess?
When i have a case with input, what works for me
<template lang="pug">
field-wrapper.field(:label="label" :caption="caption" :error="error")
input.form-input(:type="computedType" :value="value" :disabled="disabled" :placeholder="placeholder" #keyup="removeError" #input="$emit('input', $event.target.value)")
</template>
#input="$emit('input', $event.target.value) - i solve problem like this, but ints not work with plugin vuemultiselect

How to make a component use v-for have dynamic slots

I have a child component that uses v-for. I want to be able to have the parent pass down a slot, or something similar of how it wants each item in the v-for display. However, the problem is that the parent does not have access to each individual item in the v-for as it's rendered.
Some things i've tried is passing a slot with specific keys. e.g.
<child-comp :items="items">
<div v-text="item.text" slot="body"/>
</child-comp>
Basic code may look like this for what i'm trying (though it doesn't work)
Parent component would look something like
<template>
<child-comp :items="items>
<div v-text="item.text"
</child-comp>
</template>
items = [{ text: 'hello'}]
Child would look something like this
<template>
<div>
<span v-for="item in items">
<slot></slot>
</span>
</div>
</template>
Note this has to be dynamic because one item might do v-text, another may do something like add more html such as an image, and another may do something completely different.
I believe you're looking for scoped slots.
https://v2.vuejs.org/v2/guide/components-slots.html#Scoped-Slots
Note that the preferred syntax for using scoped slots changed in Vue 2.6.0 so the exact way you write this will depend on which version you're using.
Your child would pass the item to the slot, like this:
<template>
<div>
<span v-for="item in items">
<slot :item="item"></slot>
</span>
</div>
</template>
The parent would look like this for Vue 2.6.0+:
<template>
<child-comp :items="items">
<template v-slot:default="slotProps">
<!-- The parent can put whatever it needs here -->
{{ slotProps.item }}
</template>
</template>
</child-comp>
</template>
Any props passed to the slot by the child will be included in the slotProps. There's no need to call it slotProps and in practice it is usually destructured (see the docs for more details).
For Vue 2.5 you'd use slot-scope instead:
<template>
<child-comp :items="items">
<template slot-scope="slotProps">
<!-- The parent can put whatever it needs here -->
{{ slotProps.item }}
</template>
</template>
</child-comp>
</template>
Prior to Vue 2.5.0 slot-scope was called scope.