测试时 Vue JS 组件模板渲染问题

Posted

技术标签:

【中文标题】测试时 Vue JS 组件模板渲染问题【英文标题】:Vue JS Component template rendering issue when testing 【发布时间】:2018-03-08 20:28:25 【问题描述】:

我目前在测试 vue 组件时遇到问题,下面的代码确实有效,但测试不起作用。我做了一些搜索,我知道 Vue 2.0 在导入 vue 时仅使用运行时构建并且我需要使用 vue/esm 或使用渲染功能时存在问题。我遇到的问题是我没有使用 webpack 或任何构建系统(使用 tsconfig)来创建别名。

我试过只使用模板:'',但仍然出错。当我使用 render/createElement 函数时,我似乎无法添加自己的 html 文件/模板,因为它似乎只想创建一个新元素而不是注入模板。

错误:'[Vue 警告]:您正在使用仅运行时构建的 Vue,其中模板编译器不可用。要么将模板预编译成渲染函数,要么使用编译器包含的构建。

组件:

import 
    debounce

from 'npmPackage/debounce';
import Vue from 'vue';
import Component from 'vue-class-component';
import './navigation-bar.styles.less';
import 
    menuItemList,
    secondaryButton

from './types';

 @ Component(
    props: ['panels', 'secondaryButton'],
    // render: (createElement) =>  return createElement('div', require('./navigation-bar.html')); 
    template: require('./navigation-bar.html')
)

export class NavigationBar extends Vue 
    public menuActive: boolean = false;
    public menuClass: string = '';
    public panels: menuItemList;
    public secondaryButton: secondaryButton;

    private animateMenu: () => void = debounce(this.toggleMenuClass, 300, true);

    public toggleMenu(): void 
        this.animateMenu();
    

    private toggleMenuClass(): void 
        this.menuActive = !this.menuActive;
        this.menuClass = this.menuActive ? 'show' : 'hide';
    


Vue.component('navigation-bar', NavigationBar);

单元测试:

import 
    expect

from 'chai';
import 
    spy,
    stub

from 'sinon';
import Vue from 'vue';
import 
    NavigationBar

from '../src/navigation-bar.component'
import 
    IMenuItem

from "../src/types";

describe('Navigation bar component', () => 
    let panels: Array < IMenuItem > ;
    let navigationBar: NavigationBar;

    beforeEach(() => 
        panels = [
                label: 'my-account',
                action: function () 
            , 
                label: 'home',
                action: stub
            
        ];
        navigationBar = new NavigationBar();
        navigationBar.$mount();
    );

    describe('Checks that only one action is being called per panel', () => 
        it('checks actions are called', () => 
            console.log(navigationBar.$el);
            navigationBar.panels = panels;
            const menuItem = navigationBar.$el.querySelectorAll('.menu-item');
            menuItem.length.should.equal(panels.length);

            const menuItem1 = menuItem[0];
            menuItem1.should.be.instanceOf(HTMLElement);
            const html = menuItem1 as HTMLElement;
            html.click();
            panels[0].action.should.have.been.calledOnce;
            panels[1].action.should.not.have.been.called;
        );
    );
);

【问题讨论】:

【参考方案1】:

获取 CDN 版本的 Vue 副本并将其导入,而不是 npm Vue。

或者你也可以import Vue from vue/dist/vue.js

【讨论】:

我也试过这个没有用。它没有从组件中找到 /dist 并且将 CDN 脚本添加到 html 并不能让我在 typescript vue 组件中使用它。 是的,您可能应该放弃打字稿,因为那样您正在交叉编译,并且您最终可能会在某处丢失一些功能。我想知道为什么你的语法看起来如此不同。 或者至少使用 Webpack 和 TypeScript。 在我目前的情况下,我不能这样做。我将其构建为一个 npm 包以放入一个非常大的代码库中。也尽量保持简单。我一直在尝试让 html 在单元测试时进行编译,到目前为止,每种方法都失败了。不过感谢您的帮助,您会认为它会起作用,但我一定是某个地方出了点严重问题 这可能与您正在拉入的类组件有关。您是否尝试在 vue 之前拉入您的类组件?或者,Vue 已经有你在最底层使用的组件语法。尝试在其中插入模板代码,看看它是否有效。

以上是关于测试时 Vue JS 组件模板渲染问题的主要内容,如果未能解决你的问题,请参考以下文章

Vue 组件渲染而不是 Laravel Blade 模板

使用渲染功能时如何在 Vue.js 模板中定义插槽?

Vue.js 3,Quasar 2 - 组件缺少模板或渲染功能

Laravel 6 + Vue.js 无法挂载组件:未定义模板或渲染函数

Vue.js - 组件模板不使用 v-for 渲染

Vue js 2-无法安装组件:未定义模板或渲染功能