Repository: DevExpress/devextreme-vue (ts)

Issue:
Support non-scoped slots for templates
For some cases, `slot-scope` in template looks [excess](
https://codesandbox.io/s/0wvq6vnl).
```html
<dx-popup
  contentTemplate="contentTemplate"
  :visible="true"
>
   <div slot="contentTemplate" slot-scope="_">
      This is content template
   </div>
</dx-popup>
```
I tnink we should support syntax without `slot-scope`.



Pull request:
Support non-scoped slots for templates
closes #107 

Patch:
diff --git a/README.md b/README.md
index ef76073..3efbd89 100644
--- a/README.md
+++ b/README.md
@@ -166,7 +166,7 @@ The DevExtreme Vue editors also support [`v-model`](https://vuejs.org/v2/guide/f
 ### <a name="custom-templates"></a>Custom Templates ###
 You can customize widget elements' appearance via the corresponding template properties. 
 
-To specify a DevExtreme Vue Component template, use a [named slot](https://vuejs.org/v2/guide/components-slots.html#Named-Slots) to specify a template's markup. You also should specify a [slot scope](https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots) to access the template element's data.
+To specify a DevExtreme Vue Component template, use a [named slot](https://vuejs.org/v2/guide/components-slots.html#Named-Slots) to specify a template's markup. You also can specify a [slot scope](https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots) to access the template element's data.
 
 For instance, you can specify the itemTemplate:
 
diff --git a/example/components/popup-example.vue b/example/components/popup-example.vue
index 7a7bdc6..6fefd8d 100644
--- a/example/components/popup-example.vue
+++ b/example/components/popup-example.vue
@@ -14,7 +14,15 @@
           :visible.sync="visible"
           width="600"
           height="400"
-        />
+        >
+          <div slot="content">
+            This is popup content
+            <dx-button
+              text="Close popup"
+              @click="handleClick"
+            />            
+          </div>
+        </dx-popup>
     </example-block>
 </template>
 
@@ -37,7 +45,7 @@ export default {
         this.updateText(e.value);
       },
       handleClick: () => {
-        this.toggle(true);
+        this.toggle(!this.visible);
       },
       visible: false
     };
diff --git a/src/core/component.ts b/src/core/component.ts
index 0523d13..724e44f 100644
--- a/src/core/component.ts
+++ b/src/core/component.ts
@@ -38,14 +38,20 @@ const BaseComponent: VueConstructor = Vue.extend({
             this.$_createEmitters(instance);
         },
         $_getIntegrationOptions(): object {
-            if (!this.$scopedSlots || !Object.keys(this.$scopedSlots).length) {
+            const slots: Record<string, any> = {
+                ...this.$scopedSlots,
+                ...this.$slots
+            };
+            delete slots.default;
+
+            if (!Object.keys(slots).length) {
                 return {};
             }
 
             const templates: Record<string, any> = {};
 
-            Object.keys(this.$scopedSlots).forEach((slotName: string) => {
-                templates[slotName] = this.$_fillTemplate(this.$scopedSlots[slotName]);
+            Object.keys(slots).forEach((name: string) => {
+                templates[name] = this.$_fillTemplate(slots[name]);
             });
 
             return {
@@ -61,7 +67,7 @@ const BaseComponent: VueConstructor = Vue.extend({
                     const vm = new Vue({
                         parent: this,
                         render: () => {
-                            return template(data.model);
+                            return typeof template === "function" ? template(data.model) : template[0];
                         }
                     }).$mount();
 


Test patch:
diff --git a/src/core/component.test.ts b/src/core/component.test.ts
index e9e16bc..45c7f47 100644
--- a/src/core/component.test.ts
+++ b/src/core/component.test.ts
@@ -95,17 +95,23 @@ describe("template", () => {
 
     const DX_TEMPLATE_WRAPPER = "dx-template-wrapper";
 
-    function renderItemTemplate(model: object, container: any = null): Element {
+    function renderItemTemplate(model?: object, container?: any): Element {
+        model = model || {};
+        container = container || document.createElement("div");
         const render = WidgetClass.mock.calls[0][1].integrationOptions.templates.item.render;
         return render({
-            container: container || document.createElement("div"),
+            container,
             model
         });
     }
 
     it("passes integrationOptions to widget", () => {
         new Vue({
-            template: "<test-component><div slot='item' slot-scope='data'>1</div></test-component>",
+            template: `<test-component>
+                         <div slot='item' slot-scope='data'>1</div>
+                         <div slot='content'>1</div>
+                         <div>1</div>
+                       </test-component>`,
             components: {
                 TestComponent
             }
@@ -114,23 +120,42 @@ describe("template", () => {
 
         expect(integrationOptions).toBeDefined();
         expect(integrationOptions.templates).toBeDefined();
+
         expect(integrationOptions.templates.item).toBeDefined();
         expect(typeof integrationOptions.templates.item.render).toBe("function");
+
+        expect(integrationOptions.templates.content).toBeDefined();
+        expect(typeof integrationOptions.templates.content.render).toBe("function");
+
+        expect(integrationOptions.templates.default).toBeUndefined();
     });
 
     it("renders", () => {
         new Vue({
             template: `<test-component>
-                            <div slot='item' slot-scope='props'>Template {{props.text}}</div>
+                            <div slot='item'>Template</div>
                         </test-component>`,
             components: {
                 TestComponent
             }
         }).$mount();
-        const renderedTemplate = renderItemTemplate({ text: "with data" });
+        const renderedTemplate = renderItemTemplate();
 
         expect(renderedTemplate.nodeName).toBe("DIV");
         expect(renderedTemplate.className).toBe(DX_TEMPLATE_WRAPPER);
+        expect(renderedTemplate.innerHTML).toBe("Template");
+    });
+
+    it("renders scoped slot", () => {
+        new Vue({
+            template: `<test-component>
+                            <div slot='item' slot-scope='props'>Template {{props.text}}</div>
+                        </test-component>`,
+            components: {
+                TestComponent
+            }
+        }).$mount();
+        const renderedTemplate = renderItemTemplate({ text: "with data" });
         expect(renderedTemplate.innerHTML).toBe("Template with data");
     });