vue 理解过程

https://www.red-gate.com/simple-talk/dotnet/net-development/introduction-to-vue-js-with-a-single-page-application-spa-in-visual-studio/

 

Main.js

import Vue from 'vue';

import App from './App.vue';

import Router from './router';

new Vue({

    el: '#app',

    template: '',

    components: { App },

    router: Router

});

这是进入JavaScript应用程序的入口点,所以当设置webpack以创建应用程序包时,您将指向这个文件。

前三行导入设置应用程序所需的模块。Vue是Vue.js库,它是在packages.json文件中建立的devDependencies之一,并通过运行npm安装下拉到开发环境中。接下来是在App.vue中定义的App组件。最后,Router导入在router.js文件中定义的路由信息,它让Vue知道在导航到不同的URL时要显示什么。

在导入部分之后,可以看到一个新的Vue实例被初始化,然后告诉它绑定到index.html页面中定义的#app元素。Vue构造函数对象的模板和组件属性告诉Vue,您希望用App.vue中定义的App组件填充index.html中的#app元素。最后,路由器属性允许将router.js中定义的路由信息传递给Vue实例。

Router.js

该文件用于初始化Vue路由器,并定义以什么URL显示哪些组件。

import Vue from 'vue';

import VueRouter from 'vue-router';

import PageA from './Pages/PageA.vue';

import PageB from './Pages/PageB.vue';

const routes = [

    { path: '/', component: PageA },

    { path: '/pagea', component: PageA },

    { path: '/pageb', component: PageB },

]

Vue.use(VueRouter);

const router = new VueRouter({ mode: 'history', routes: routes });

export default router;

再次从导入开始。这次导入Vue库。Vue Router库,用于管理Vue的路由选择(同时也是package.json中的devDepende.)以及两个PageA和PageB(分别从PageA.vue和PageB.vue导入)的Vue组件。接下来是定义URL和显示哪个组件的路由数组,然后调用Vue.use(VueRouter),它初始化Vue中的路由。之后,您创建一个新的VueRouter实例,并传入定义的路由,以及告诉路由器如何管理页面状态信息(在本例中,我使用“history”模式)。

然后返回初始化的VueRouter实例作为模块的默认导出。

App.vue

这是应用程序中的顶级组件。在应用程序中,它是一个非常重要的组件:

<template>

    <div>

        Hello from App Vue: <strong>{{strong> message <strong>}}strong>

        <router-link to="/pagea">Go to Arouter-link>

        <router-link to="/pageb">Go to Brouter-link>

        <router-view>router-view>

    div>

template>

组件在页面上呈现时显示来自App.vue的message内容。它还有一个组件,其中将显示与路由器中的URL相关联的组件。为了演示该功能,有两个组件,允许用户从PageA切换到PageB。您可以从Vue路由器页面了解有关Vue中路由的更多细节。

PageA.vue / PageB.vue

页面组件也是非常简单的组件,它们可以演示路由是否正常工作。

<template>

    <div>

        Page A - <strong>{{strong> message <strong>}}strong>

    div>

template>

这个内容可以复制到PageA.vue和PageB.vue中,但是显然您想要更新PageB.vue中的任何文本,比如PageB。与App.vue类似,此组件仅显示一条消息,指示文本的定义位置。

 

What is Webpack?

Webpack是一个模块捆绑器带有用于将转换应用到应用程序代码的管道。要使用它,需要在应用程序中指定一个或多个入口点——在本例中,唯一的入口点是Main.js文件。Webpack然后读取该文件并定位其中引用的任何JavaScript模块。然后,它递归地读取这些模块并定位它们所依赖的任何JavaScript模块,等等,直到它具有应用程序中使用的所有代码的图。然后,它将来自所有那些模块的所有代码捆绑到一个包含所有代码的捆绑包中(有一些选项可以将捆绑包分割成多个文件,我在这里将不深入讨论)。在本例中,这看起来类似于:

大多数浏览器都支持ES6和JavaScript模块的概念,因此在构建现代JavaScript应用程序时,不必使用bundler。

单文件Vue组件支持。开发人员倾向于真正理解.vue文件如何允许您为给定组件定义HTML、脚本和CSS。但是,JavaScript不能原生地解释.vue文件。Webpack包含一个加载程序,该加载程序读取.vue文件,将其分解为其组成部分,然后将其打包为可以像正常那样引用的JavaScript模块。

ES5支持。您可能希望使用最新的JavaScript语法编写应用程序。然而,当前版本的IE(在编写本文时)和许多较老版本的浏览器不支持ES6。Webpack允许您添加一个插件来将代码从ES6转换为ES5格式(您将使用Babel)。

 

优化。未优化的包初始化速度大约是相同未包的代码的三倍。优化的包初始化速度大约快4倍(来源)。对于较小的应用程序,差异可以忽略不计,但对于较大的应用程序,您将看到一些好处。

 

The Build Process

应用程序文件就绪后,您最终可以关注构建过程,该过程将如下所示:

 

 

NPM Script 

这是package.json文件中定义的脚本。它们用于设置NODE_ENV变量,以指示要运行的构建类型。

NODE_ENV

这是一个环境变量,用于存储NPM脚本中定义的值。

config.js

这是一个JavaScript模块,它导出包含根据NODE_ENV值而变化的webpack配置设置的JavaScript对象。

webpack.config.js 

这是一个JavaScript模块,它使用config.js模块中的配置设置来设置和导出webpack配置对象。

Webpack 

这是一个命令行实用程序,它读取webpack配置并根据这些设置打包应用程序。

 

注意:Node JS使用公共JS模块语法,而不是ES6模块语法。这意味着模块导入和导出语法在这里与Vue应用程序中稍有不同。

 

 

Config.js

如前所述,该文件是一个Common JS模块,包含可以根据NODE_ENV设置而变化的配置设置。尽管可以将这些配置设置直接放入webpack配置文件中,但是像这样将它们分离出来有一些优点。webpack配置趋向于更长和更复杂,因此这使文档大小更易于管理。其次,它提供了一个隔离,帮助人们避免更改他们应该远离的webpack中的配置设置。

const configuration = {

    // Application settings that can be configured from one environment to the next.  These

    // are output to the app-settings.js file that is then referenced as a plugin within

// webpack so they can be changed manually if needed.

//可以从一个环境配置到下一个环境的应用程序设置。这些设置被输出到//app-settings.js文件,然后作为webpack中的插件引用,以便根据需//要手动更改它们。

    appSettings: {

        settingA: 5,

        settingB: 10

    },

    // Identifies the type of build that has been requested.  Primarily used to vary

// settings for different types of builds.

//标识已请求的构建类型。主要用于不同类型的构建的不同设置。

    buildTarget: process.env.NODE_ENV || 'development',

    // Specifies whether webpack should watch for changes on the file system and

// automatically repack bundles when changes occur.

//指定webpack是否应该监视文件系统的更改,以及当发生更改时,自动重新打包包。

    watch: false,

    // Specifies the webpack mode

    webpackMode: 'development'

};

/*******************************************************************************

* Define watch-only settings

******************************************************************************/

if (configuration.buildTarget === 'watch') {

    configuration.watch = true;

}

/*******************************************************************************

* Define production-only settings

******************************************************************************/

if (configuration.buildTarget === 'production') {

    // Define production-only settings

    configuration.webpackMode = 'production';

}

//Export the configuration

module.exports = configuration;

这个脚本首先创建一个对象并将其存储在配置变量中。这是最终将从这个模块导出的配置对象,并且为开发构建设置默认值。此配置中定义的appSettings用于特定于环境的设置,这些设置将呈现给从index.html页面引用的app-settings.js文件。流程对象在本地可用,并提供各种与流程相关的元数据,包括访问环境变量(通过env属性)。接下来,将watch属性设置为false,将webpackMode属性设置为development。

在配置对象定义之后,有两个if语句检查buildTarget值,'watch' or'production'。在if语句中,将更改配置对象以考虑此类构建所需的设置。如果buildTarget被设置为watch,那么请注意watch属性被翻转为true。如果buildTarget是生产,那么webpackMode被设置为生产。这里只有几个配置设置,因为我希望保持简单。您很可能会在您的webpack构建中遇到需要根据构建类型更改的场景,当这种情况发生时,只需在配置对象中为它们创建一个变量,在适当的if语句中相应地更新它们,然后在webpack配置文件中使用配置设置值。此外,要知道还可以使用环境特定值修改appSettings对象。

导出模块对于公共JS模块的工作方式与ES6模块稍有不同。在ES6中,使用导出关键字。对于Common JS,必须将导出的对象分配给module.export,这是您在脚本的最后一行看到的操作。

 

Webpack.config.js

最后,是时候添加驱动webpack进程的webpack配置文件了。与config.js文件一样,这是一个公共JS模块。该文件从packages.json文件中定义的npm脚本传递到webpack中。

const config = require('./config');                         // Configuration settings 配置设置

const path = require('path');                               // Path library used for building file locations 用于构建文件位置的路径库

const fileSave = require('file-save');                      // Utility for writing files to disk 用于将文件写入磁盘的实用程序

const webpack = require('webpack');      // Webpack library

const VueLoaderPlugin = require('vue-loader/lib/plugin');   // Plugin used for loading single-component vue files 用于加载单个组件vue文件的插件。

// Output the application settings file 输出应用程序设置文件

if (config.appSettings != null) {

    // NOTE: the replace regex on the next line removes the quotes from properties.  It is rudimentary and can be removed 在下一行中 replace regex从属性中删除引号

// if it causes issues (because the quotes are technically OK I just think they look bad).

//如果它引起问题(因为在技术上还可以,我只是觉得它们看起来很糟糕)

    var appSettingsOutput = JSON.stringify(config.appSettings, null, 4).replace(/\"([^(\")"]+)\":/g, "$1:");

    fileSave(path.join(path.resolve(__dirname, "../../wwwroot/js"), "app-settings.js"))

        .write("window.appSettings = " + appSettingsOutput);

}

const webpathConfig = {

    mode: config.webpackMode,   // Specifies whether to use built-in optimizations accordingly (options: production | development | none) 指定是否相应地使用内置优化

    entry: "./App/main.js",     // Specifies the entry point of the application where webpack begins the packaging process.  指定webpack开始打包过程的应用程序的入口点

    output: {

        path: path.resolve(__dirname, "../../wwwroot/js"),  // Specifies the output directory for any wepback output files     指定任何wepback输出文件的输出目录   

 

 filename: "bundle.js",                              // Specifies the file name template for entry chunks (TODO: figure out what an entry point chunk is),指定条目块的文件名模板(找出入口点块是什么)

        publicPath: "/js/"                                  // Specifies the page-relative URL to prefix before assets to ensure they can be resolved by a browser.  (Notice this value is injected into index.html to refer to the bundle.js file created by webpack).

//指定在资产之前前缀的页面相关URL,以确保可以通过浏览器解析它们。注意,这个值被注入index.html以引用由webpack创建的bundle.js文件

    },

    resolve: {

        alias: {

            vue: 'vue/dist/vue.js'  // This is required to avoid the error 'You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.'

//为了避免“您正在使用模板编译器不可用的仅运行时生成的Vue”的错误,需要这样做。要么将模板预编译成渲染函数,要么使用编译器包含的构建。

        }

    },

    module: {

        rules: [

            { test: /\.vue$/, loader: 'vue-loader' },                                   // Specifies that files with the .vue extension should be processed by vue-loader which is what breaks up a single-file vue component into its constituent parts.

//指定具有.vue扩展名的文件应该由vue-loader处理,vue-loader将单个文件vue组件分解为其组成部分。

            { test: /\.js$/, loader: 'babel-loader', query: { presets: ['es2015'] } },  // Specifies that .js files should be run through the babel-loader for ES2015 to ES5 conversion.

//指定.js文件应该在ES2015到ES5转换的babel-loader中运行。

            { test: /\.css$/, use: ['vue-style-loader', 'css-loader'] },                // Specifies that CSS should be included in the bundle from .CSS files as well as processed from the