Создание корневого экземпляра Vue внутри файла Vue - PullRequest
0 голосов
/ 19 октября 2018

Есть ли способ для файла .vue быть ответственным за создание своего собственного экземпляра Vue в шаблоне Single File Component?

Вот файл Vue.

// MyComponent.vue
<template><div>Hello {{ name }}!</div></template>

<script>
const Vue = require('vue');

// what would usually be exports default
const componentConfig = {
    name: "my-component",
    props: {
        name: String,
    },
};

function create(el, props) {
    const vm = new Vue({
        el,
        render(h) {
            return h(componentConfig, { props });
        });
    vm.$mount();
    return vm;
}

module.exports = { create };
</script>

изатем использование в некотором файле JS:

// index.js
const MyComponent = require('./MyComponent.vue');

const el = '.container';
const props = {
    name: 'Jess',
};

MyComponent.create(el, props);
</script>

Когда я делаю выше, я получаю ошибки о невозможности найти шаблон.

[Vue warn]: Failed to mount component: template or render function not defined.

found in

---> <MyComponent>
       <Root>

Как инстинктивно,Я не понимаю, как компилятор Vue мог бы магическим образом вывести (из тегов скрипта), что я хочу сослаться на шаблон, объявленный выше ... так что ... да.Есть ли объяснение, почему я не могу этого сделать, или мысли о том, как заставить это работать?

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Вы действительно близки к рабочему решению, но вам не хватает только нескольких "склеивающих" частей, чтобы объединить все вместе:

<template>
    <div>Hello {{ name }}!</div>
</template>
<script>
    import HelloWorld from "./components/HelloWorld";
    import Vue from "vue";

    const Component = {
        // Add data here that normally goes into the "export default" section
        name: "my-component",
        props: {
            name: String,
        },
        data() {
            return {
            };
        },

    };
    Component.create = function(el, props) {
        const vm = new Vue({
            el,
            render(h) {
                return h(Component, { props });
            },
        });
        vm.$mount();
        return vm;
    };
    export default Component;
</script>

Это можно затем использовать в других файлах следующим образом:

import App from "./App";
App.create("#app", {
    name: 'Hello World!',
});

Пример кодов и коробки: https://codesandbox.io/s/m61klzlwy

0 голосов
/ 22 октября 2018

То, что вы описываете, делается на этапе предварительной компиляции через Webpack и Vue Loader .Компилятор Vue фактически не анализирует Single File Components .Компилятор Vue может анализировать - это шаблоны, предоставляемые в объекте параметров компонента.Поэтому, если вы предоставите опцию template в вашем componentConfig объекте, ваш пример будет работать.В противном случае вам придется пройти этап предварительной компиляции с Webpack и Vue Loader, чтобы проанализировать шаблон компонента Single File.Для этого вам нужно будет соответствовать структуре SFC , определенной в спецификации .Вот выдержка ..

Шаблон

  • Каждый файл *.vue может содержать не более одного блока <template> за раз.
  • Содержимое будет извлечено и передано в vue-template-compiler, предварительно скомпилировано в функции рендеринга JavaScript и, наконец, введено в экспортируемый компонент в разделе <script>.

Сценарий

  • Каждый файл *.vue может содержать не более одного блока за раз.
  • Сценарий выполняется как модуль ES.
  • экспорт по умолчанию должен быть объектом опций компонента Vue.js .Также поддерживается экспорт расширенного конструктора, созданного с помощью Vue.extend(), но предпочтительным является простой объект.
  • Любые правила веб-пакета, соответствующие файлам .js (или расширению, указанному атрибутом lang) также будет применено к содержимому в блоке <script>.

Чтобы ваш конкретный пример работал, вы можете переписать файл main.js, как этот ..

const MyComponent = require("./MyComponent.vue");

const el = ".container";
const data = {
  name: "Jess"
};

MyComponent.create(el, data);

И ваш файл MyComponent.vue (Это может быть файл js, как и @Ferrybig, упомянутый ниже) ..

<script>
const Vue = require('vue');

function create(el, data) {
  const componentConfig = {
    el,
    name: "my-component",
    data,
    template: `<div>Hello {{ name }}!</div>`
  };
  const vm = new Vue(componentConfig);
  return vm;
}

module.exports = { create };
</script>

См. Этот CodeSandbox

Или, если вы предпочитаете функции рендеринга, ваша MyComponent.vue будет выглядеть следующим образом ..

<script>
const Vue = require('vue');

function create(el, data) {
  const componentConfig = {
    el,
    name: "my-component",
    data,
    render(h) { return h('div', 'Hello ' + data.name) } 
  };
  const vm = new Vue(componentConfig);
  return vm;
}

module.exports = { create };
</script>

CodeSandbox


Последнее, что нужно иметь в виду: В любом компоненте вы можете использовать либо шаблон, либо функцию рендеринга, , но не оба , как вы делали в своем примере.Это потому, что один из них переопределит другой.Например, посмотрите шаблон JSFiddle Vue и обратите внимание, как при добавлении функции рендеринга шаблон переопределяется.Это объясняет ту ошибку, которую вы получаете.Функция рендеринга имела преимущество, но вы передали ей объект параметров компонента, который не предоставляет никакого шаблона для рендеринга.

PS: Я заинтригован целью этого упражнения.Это определенно не рекомендуемый способ ведения дел в Vue.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...