代码之家  ›  专栏  ›  技术社区  ›  Francesco Casula

Karma/Webpack/Vue。js:属性或方法未在实例上定义,但在渲染期间引用

  •  0
  • Francesco Casula  · 技术社区  · 7 年前

    我已经看到这个问题已经被问了很多次了,但在这种情况下,我认为这与我在Vue中所做的工作更相关。这是因为我只在使用Karma(使用最新的Chrome headless)运行测试时收到警告,但在使用 Web包开发服务器 马上。

    应用程序/网页包。基础配置。js公司 文件:

    module.exports = {
        module: {
            rules: [
                {
                    test: /\.vue$/,
                    loader: 'vue-loader',
                    options: {
                        loaders: {}
                        // other vue-loader options go here
                    }
                },
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/
                },
                {
                    test: /\.css/,
                    loader: 'style-loader!css-loader'
                },
                {
                    test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
                    loader: 'url-loader?limit=10000&mimetype=application/font-woff'
                },
                {
                    test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
                    loader: 'url-loader?limit=10000&mimetype=application/font-woff'
                },
                {
                    test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
                    loader: 'url-loader?limit=10000&mimetype=application/octet-stream'
                },
                {
                    test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
                    loader: 'file-loader'
                }, {
                    test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
                    loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
                },
                {
                    test: /\.(png|jpg|gif|svg)$/,
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]?[hash]'
                    }
                }
            ]
        },
        resolve: {
            alias: {
                'vue$': 'vue/dist/vue.esm.js'
            }
        }
    };
    

    const path = require('path');
    const webpack = require('webpack');
    const mergeConfig = require('webpack-merge');
    const baseConfig = require('./webpack.base.config');
    
    module.exports = mergeConfig(baseConfig, {
        entry: './src/main.js',
        output: {
            path: path.resolve(__dirname, './dist'),
            publicPath: '/dist/',
            filename: 'build.js'
        },
        devServer: {
            historyApiFallback: true,
            noInfo: true,
            hot: true
        },
        performance: {
            hints: false
        },
        devtool: '#eval-source-map',
        plugins: [
            new webpack.HotModuleReplacementPlugin()
        ]
    });
    

    应用程序/测试/卡玛。配置js (仅使用 网页包。基础配置。js公司 在这里归档,不是全部)

    // Karma configuration
    const webpackConfig = require('../webpack.base.config');
    
    process.env.CHROME_BIN = require('puppeteer').executablePath();
    
    module.exports = function (config) {
        config.set({
    
            // base path that will be used to resolve all patterns (eg. files, exclude)
            basePath: '.',
    
            // frameworks to use
            // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
            frameworks: ['jasmine'],
    
            // list of files / patterns to load in the browser
            files: [
                './index.js'
            ],
    
            // list of files to exclude
            exclude: [],
    
            // preprocess matching files before serving them to the browser
            // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
            preprocessors: {
                './index.js': ['webpack']
            },
    
            // karma watches the test entry points
            // (you don't need to specify the entry option)
            // webpack watches dependencies
            webpack: webpackConfig,
    
            webpackMiddleware: {
                noInfo: true
            },
    
            // test results reporter to use
            // possible values: 'dots', 'progress'
            // available reporters: https://npmjs.org/browse/keyword/karma-reporter
            reporters: ['spec'],
    
            // web server port
            port: 8080,
    
            // enable / disable colors in the output (reporters and logs)
            colors: true,
    
            // level of logging
            // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
            logLevel: config.LOG_INFO,
    
            // enable / disable watching file and executing tests whenever any file changes
            autoWatch: true,
    
            // start these browsers
            // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
            browsers: ['ChromeHeadlessNoSandbox'],
    
            customLaunchers: {
                ChromeHeadlessNoSandbox: {
                    base: 'ChromeHeadless',
                    flags: ['--no-sandbox']
                }
            },
    
            // Continuous Integration mode
            // if true, Karma captures browsers, runs the tests and exits
            singleRun: false,
    
            // Concurrency level
            // how many browser should be started simultaneous
            concurrency: 1
        });
    };
    

    import Vue from 'vue';
    
    Vue.config.productionTip = false;
    
    // require all test files (files that ends with .js)
    const testsContext = require.context('./specs', true, /\.js/);
    testsContext.keys().forEach(testsContext);
    

    然后我在我的规格中安装组件时得到警告,如下所示:

    import Vue from 'vue';
    import Extractor from './../../../src/components/Extractor.vue';
    
    describe('Extractor component', () => {
        it('sets the correct default data', () => {
            const component = new Vue(Extractor).$mount();
    
            expect(component.url).toBe('');
            expect(component.responseCode).toBe(null);
            expect(component.body).toBe(null);
            expect(component.errorMessage).toBe(null);
        });
    });
    

    警告: 这种情况会发生 仅限 如果:

    1. 我使用 vue-class-component
    2. 我的组件继承自另一个组件
    3. 通过Karma/Chrome headless运行代码时

    我在日志中得到的错误是:

    [Vue警告] :属性或方法“valid”未在实例上定义,但在渲染期间被引用。通过初始化该属性,确保该属性是反应性的,无论是在数据选项中,还是对于基于类的组件。请参阅: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties .

    它抱怨的“有效”财产在 ApiComponent 班级(基本上是家长)。

    这里有一个组件给了我警告:

    import http from './../modules/http';
    import ApiComponent from './sub/ApiComponent';
    import Component from 'vue-class-component';
    
    // @see https://github.com/vuejs/vue-class-component
    // @see https://github.com/wycats/javascript-decorators/blob/master/README.md
    @Component()
    
    export default class Extractor extends ApiComponent {
        url = '';
    
        sendRequest() {
            return new Promise((resolve, reject) => {
                // some AJAX call here
            });
        }
    }
    

    如果不是 Extractor APIC组件 我让它延伸 Vue APIC组件 内部代码 提取器 然后警告消失。重点是。。。为什么我只有在通过业力运行代码时才收到警告?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Francesco Casula    7 年前

    通过装饰超级类,警告消失了( ApiComponent ).

    import Vue from 'vue';
    import Component from 'vue-class-component';
    
    @Component
    export default class ApiComponent extends Vue {
        // ...
    }