前端工程化之后,如果写Vue,就要搭建Vue工程项目。目前搭建工程项目有两种方法,一是采用Webpack自行搭建环境然后引入Vue,二是使用Vue-cil。
这里先用Webpack实验一下。
Webpack基础环境+Vue相关Loader配置
在前端工程化里搞定了Webpack的配置。现在需要配置Vue的工程文件了。
一个Vue工程与普通Webpack工程的不同就是使用了.vue
文件的单文件组件。所以需要一个对应的vue-loader来解析单文件组件。
创建Vue
工程之前,先按照普通创建好Webpack 4 + Babel 7 +
PostCSS的环境,然后是一个仅带有一个div#app
的index.html
。为了突出结果,就直接使用默认的入口和出口。
vue-loader
为了解析单文件组件,需要先安装vue-loader
,:
npm install -D vue-loader vue-template-compiler
这是根据官网的v15版最新文档,升级Vue包就需要升级对应的vue-template-compiler
。
最后别忘记还需要安装Vue本身:npm i -D vue
最后实际安装的版本如下:
"vue": "^2.6.10", "vue-loader": "^15.7.0", "vue-template-compiler": "^2.6.10",
配置可以参考NPM上的vue-loader和上边的vue-load文档:
const path = require('path'); const ExtractPlugin = require('mini-css-extract-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); module.exports = { //设置模式,可以是development或者production mode: "development", // 入口和输出部分使用默认 // 入口默认值 = ./src/index.js // 输出默认值 = ./dist/main.js //loader部分 module: { rules: [ { //匹配CSS文件类型 test: /\.css$/, //调用了新的插件的方法,这里使用了css-loader use: [ { loader: ExtractPlugin.loader, }, { loader: 'css-loader', options: { importLoaders: 1, } }, { loader: 'postcss-loader' } ] }, //匹配JS文件的loader { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } }, //匹配vue文件的loader { test:/\.vue$/, loader: 'vue-loader' } ] }, // 插件部分 plugins: [ new ExtractPlugin({ filename: "[name].css" }), new VueLoaderPlugin() ] };
其他配置先不改,写一个单文件组件来试试看能不能解析。
单文件组件
什么是单文件组件,其实就是一个以.vue
结尾的文件,类似于一个HTML文件。其中的结构如下:
<template> <p>Hello {{ person }}</p> </template> <script> module.exports = { data:function () { return { person: "jenny" } } } </script> <style scoped> p { font-size: 2em; color: orange; } </style>
这实际上就是把一个组件的内容和对应的样式重新组织。其中:
template
元素内是模板,无需转义拼接字符串,也不像使用x-template那么繁琐,就像普通HTML一样书写。script
元素内是组件的代码,默认返回一个对象,这个对象就是注册组件的时候传入的对象,其中的所有写法都和注册组件是一样的。style
元素是组件的样式。这里需要特别注意属性上的scoped
,表示该样式仅对该组件生效。如果不写scoped
,样式就是全局生效。
在单页面应用中,一般页面上只有一个div#app
,在项目的main.js
文件中,一般会创建一个绑定到该div元素的Vue实例,作为项目的根实例,也就是入口。再通过这个根实例加载其他的组件使用。这样就像写后端一样,一个组件就是一个对象,通过props,slot和事件三种API进行交互,共同构成复杂的应用。
来编写index.js
文件和一个组件来试验一下前边的配置是否成功。
//index.js import Vue from "vue"; import App from "./app.vue"; new Vue({ el: "#app", render: function (createElement) { return createElement(App); } });
这个文件使用了ES6的import语法,从vue包中导入vue。这里查过,导入的vue是一个运行时的common.js。
这里有一点要注意,就是不要在根实例挂载的DIV
标签内直接使用template
模板的内容,比如胡子渲染格式。因为导入的Vue只具备运行时功能,不能直接解析HTML文件中的template,只能解析组件。所以都要采取将DIV
元素渲染为app.vue
组件内容的方式挂载。
如果在index.html
里写了<div id="app">{{name}}<div>
就会看到这个警告。
不要直接从Node安装包中导入Vue的发行版文件,因为后边的路由的use
方法会无法解析。而且将挂载的元素渲染为app.vue
,实际上是将app.vue
作为项目的实际入口,符合一般开发的规范,否则项目入口就变成了index.js
。
可以看到里边导入了一个app.vue
组件,来创建app.vue
文件:
<template> <div> {{person}} </div> </template> <script> export default { name: "app", data() { return { person: "saner" } }, } </script> <style scoped> div { background-color: orange; color: #444444; text-align: center; } </style>
这个组件内容很简单,就显示一个变量值。结合上边的index.js
来看,这个组件将会通过render函数,实际显示在绑定根实例的div#app
元素的位置。
index.html
的内容很简单,只需要注意引入的js和css文件的位置是根路径:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/main.css"> <title>Vue工程</title> </head> <body> <div id="app"> </div> <script src="/main.js"></script> </body> </html>
然后启动DevServer,发现成功了,显示出了这个app组件的内容。通过浏览器开发工具可以发现,实际渲染出的组件内容是:
<div data-v-5ef48958=""> saner </div>
而CSS样式文件是:
div[data-v-5ef48958] { background-color: orange; color: #444444; text-align: center; }
可见8位数的hash值也对应上了,说明无论是JS文件还是CSS文件,都正确得到了解析。
现在就发现,可以像组织后端工程一样,组织Vue的工程目录。按照组件而不是像原来一样写JS的面条代码。
同时也可以发现,index.js
中的写法,实际上是将根Vue实例的内容,显示为app.vue
组件的内容。所以app.vue
实际上可以当做真正的项目根组件,或者说项目入口,在其中引入其他组件。
Vue CLI搭建工程
Vue的官网推荐使用Vue CLI来快速构建Vue工程,而不是通过Webpack,但Vue CLI是基于Webpack的。
先要安装Vue CLI,分为两部分,全局安装@vue/cli
和局部安装@vue/cli-service
。
按照官网指导,先安装全局的@vue/cli
:
npm install -g @vue/cli
这里先关掉Webpack配置的Vue,也无需使用WebStorm。就直接安装,然后新建一个任意目录作为项目目录,npm init
之类的不要忘记:
安装过程提示了@hapi/joi
,@hapi/hoek
,@hapi/topo
需要安装,以覆盖老的不带命名空间的版本。
可以再通过NPM安装一下这几个玩意:
npm i -D @hapi/joi @hapi/hoek @hapi/topo
之后准备创建项目。
创建项目
有两种方式,一种是直接命令行,一种是图形化创建。
命令行运行vue create projectname
,然后有如下配置:
- 测试连接到NPM的速度,如果速度慢会提示连接到taobao的NPM镜像
- 选择preset,默认的是带有babel和eslint的版本。也可以手工选择需要的功能。我选了babel,css预处理和eslint。
- 之后就会开始创建项目目录,目录名称就是projectname实际输入的名称。还会为项目目录自动配置Git。
如果是图形化配置,会更加方便,运行vue ui
,就可以方便的进行创建,推荐把CSS预处理也一起选上,然后在下一步里选Dart:css
实现,这样就非常方便了。
两种安装方式安装完毕后,到项目的目录下边,执行npm run serve
,就可以启动服务器了。
之后访问默认的http://localhost:8081/
,出现Vue的界面,就证明成功配置好了。
到项目目录实际查看文件,可以看到有src目录,node_modules等目录。而这个服务器是基于Webpack-dev-server的。
通过WebStorm创建Vue工程项目
WebStorm可以直接创建Vue项目。选择File | New | Project...
,在左侧选择Vue.js
,右侧可以看到Node和Vue CLI的选项和项目模板。
这里一定要安装好Vue CLI,模板我只有Webpack,就无法更改,然后就点击Next。
然后会运行Vue CLI,之后会选择一个Preset,如果之前有保存自己的就可以选择。然后点击Next,立刻就会出现一个新工程。虽然其中暂时只有package.json
文件,但是WebStorm在后台拼命安装各种NPM包。
再耐心等待一会到后台任务全部结束,可以看到最终的项目目录:
public
目录,放入了项目的目标文件,index.html
就在这里,会在解析的时候自动注入JS和CSS文件,所以并没有像我们自己的index.html
加入了静态文件链接。src
目录,放入了项目的源文件,其中的assets
目录存放静态资源,components
目录存放Vue的单文件组件。一般在src
根目录下边还有App.vue
和main.js
,这两个文件的作用和上边Webpack配置Vue环境一样,共同构成项目入口。node_modules
不用多说,查看其中可以发现,实际上安装了Webpack。- 除此之外就是
package.json
,.gitignore
等老朋友,以及一个babel.config.js
的配置
来实际实验一下,将Webpack配置的Vue工程中的三个组件复制到components
目录下,然后修改main.js
导入我们自己的app.vue
。
启动项目则无需输入命令,WebStorm右上角已经创建好了npm server
,如果没有的话,可以通过Run Configurations
自行添加,package.json
中已经配置好了命令简化。
启动项目,提示如下:
D:\Software\node\node.exe D:\Software\node\node_modules\npm\bin\npm-cli.js run serve --scripts-prepend-node-path=auto > vuestorm@0.1.0 serve D:\Coding\vuestorm > vue-cli-service serve INFO Starting development server... 98% after emitting CopyPlugin DONE Compiled successfully in 5486ms 23:58:54 App running at: - Local: http://localhost:8081/ - Network: http://192.168.100.85:8081/ Note that the development build is not optimized. To create a production build, run npm run build.
打开链接,发现和Webpack配置的项目一样成功了。
与Webpack不同的地方就是之前提到的不用配置静态文件引用。CSS文件没有单独导出,而是被插入到了HEAD
标签中,在BODY
元素的末尾则自动插入了app.js
的链接。
但是最终结果与之前是一样的,用Vue CLI也成功创建了项目。虽然还有一些配置现在还没有完全了解,但是来编写文件基本上没有问题了。
不过又实验了一下,单独的CSS文件不会被编译,而且变量也没有生效。现在还没有Sass经验,估计以后会更了解如何开发,目前全局样式也只能写在组件文件里。
JS方面倒是和Webpack差不多。
至此会搭建Vue项目了,可以继续愉快的学习Vue开发了。