在之前使用 Vue
的过程,我们所有的代码都是放在一个 script
标签中,所有的代码放在一起,势必会带来维护上的困难,另外,现如今的软件开发模式,都是多人协作,所有的代码都放在一起,也会给多人协作带来困扰,我们需要更加工程的方式来写 Vue
代码。
一般我们要求一个 Vue
组件对应一个以 .vue
结尾的文件,例如
// Hello.vue |
上面就定义了一个局部组件。
安装 vue-cli
对于上述 .vue
文件是无法在浏览器显示的,因为浏览器只认识 html, css, javascript
文件,所以要使得 .vue
文件能够显示在浏览器,我们需要某种工具将上述代码转化为浏览器认识的形式,这就要借助于 vue-cli
,首先对其进行下载
npm install -g @vue/cli |
通过 vue --version
可以查看所安装的 vue-cli
的版本
vue --version |
我们可以通过 vue serve
快速在浏览器显示一个 .vue
文件,不过需要先下载一个全局扩展
npm install -g @vue/cli-service-global |
接着便可查看一个组件的原型(即在浏览器显示该组件)
vue serve Hello.vue |
vue-cli
会对 Hello.vue
进行一番处理,接着会在控制台打印如下信息
我们可以在指定地址 http://localhost:8080/
查看该组件的原型,如下
创建一个项目
vue-create
可以通过如下命令创建一个 Vue
项目
vue create 项目名 |
接着 Vue
便会提示使用何种预设(preset)
创建的项目结构如下所示
其中 main.js
便是入口文件,内容如下
import Vue from 'vue' |
就是引入了 App.vue
组件,并把该组件挂载在了 id
为 app
元素上,App.vue
的内容如下
<template> |
.vue
文件由三部分组成
- template:定义模板内容
- script:在其中定义数据,计算属性,方法,生命周期方法等等
- style:定义组件样式
在 App.vue
中又引入了 HelloWorld.vue
,因为 HelloWorld.vue
的内容比较复杂,这里就不展示了,我们来看渲染后的页面是什么样子,在命令行输入
npm run serve |
项目构建完成之后,我们便可以在 http://localhost:8080/
看到渲染后的页面
vue ui
除了通过命令行的方式创建一个项目,我们还可以通过图形化的界面创建一个项目。在命令行中输入 vue ui
,便会在浏览器打开一个 UI
界面
点击 Create
来创建一个新项目
填写完信息后,便会让你选择预设
选择完预设后便可创建项目了,创建完项目后便可在可视化页面启动项目
简单的 Vue 项目
现在我们使用 .vue
组件的形式来实现下面的功能
这个功能在之前我们已经实现过了,主要分解为一个父组件,两个子组件
- App.vue
- CourseAdd.vue
- CourseDisplay.vue
App.vue
的内容如下
<template> |
在 App.vue
中导入了 CourseAdd
与 CourseDisplay
两个组件,并且为 CourseAdd
组件绑定了自定义事件,目的是为了将数据由子组件传递到父组件,为 CourseDisplay
传递了 courses
以做展示。
CourseAdd.vue
的内容如下
<template> |
我们为 input
绑定了按键事件,当我们按下 enter
键时就会触发 addCourse
方法,在 addCourse
方法中,我们触发了自定义事件 addCourse
,并且向事件传递了数据;或者当我们点击按钮时,也可触发此事件。
CourseDisplay.vue
的内容如下
<template> |
代码十分简单,只是将父组件传入的 courses
进行展示。
最后在 main.js
中引入 App.vue
import Vue from 'vue' |
在命令行输入
npm run serve |
即可在浏览器观察到上述动图功能。
插件
Vue CLI 使用了一套基于插件的架构。如果你查阅一个新创建项目的 package.json
,就会发现依赖都是以 @vue/cli-plugin-
开头的。插件可以修改 webpack 的内部配置,也可以向 vue-cli-service
注入命令。在项目创建的过程中,绝大部分列出的特性都是通过插件来实现的。
我们可以通过 vue add
命令为项目添加一个插件
vue add router |
因为
vue add
命令可能修改你现有的文件,所以推荐在安装插件之前,将当前项目的的最新状态提交。
后续我们使用的组件库都是通过插件的方式添加的。
我们也可以在 UI 页面为项目管理插件。
静态路径
我们可以通过相对路径来引用静态资源文件,例如在 App.vue
中引用 src/assets/logo.png
<template> |
所有通过相对路径引入的资源都会被 Webpack
打包,对于图片资源会被放在根目录下面的 img
文件夹中,所以上面的引用实际上会被解析为
我们也可以通过绝对路径来引入资源文件,因为项目 public
中的文件不会经过 Webpack
处理,而是会被直接复制到项目的根目录中,所以通过绝对路径引用的资源,就是在 public
文件夹中的资源。
<img src="/assets/logo.png" alt=""> |
就相当于访问 public/assets/logo.png
。
默认情况下,vue-cli
假设你是部署在一个域名的根目录下,如 https://www.app.com/
,但是如果你的项目是部署在一个子路径上,则你就需要使用 publicPath
指定这个子路径,例如你的应用被部署在 https://www.app.com/demo/
下,则应当将你的 publicPath
设置为 /demo/
// vue.config.js |
如果通过绝对路径引入资源,则需要在 data
中定义 publicPath
data() { |
接着在修改引入方式
<img :src="`${publicPath}assets/logo.png`" alt=""> |
如果是通过相对路径引入的资源,则不必这么麻烦,
Webpack
会帮我们除了好一切,我们只需要在vue.config.js
中定义好publicPath
即可,所以尽可能使用相对路径引入资源。
Webpack
为我们定义了一个别名,@
,它表示项目的 src
目录,所以我们还可以通过下面的方式引用资源
<img src="@/assets/logo.png" alt=""> |
CSS
Scoped CSS
在组件 style
标签中定义的 CSS
其实是全局 CSS
,它会对其他组件的样式也会产生影响,例如对于如下两个组件
// Component1.vue |
// Component2.vue |
上面定义了两个组件,Component1.vue
中定义了样式,Coponent2.vue
中没有定义样式,但是 Component1.vue
中的样式是全局的,所以 Component2.vue
组件也会受到影响,在 App.vue
中使用者两个组件
// App.vue |
运行 npm run serve
查看页面
要使得 Component1
中的样式不影响其他组件,我们需要为 style
标签添加 scoped
属性
<style scoped> |
这时在观察页面
这时发现只有 Component1.vue
组件有样式。其原理是会为 Component1.vue
组件添加自定义属性
上面的组件是 Component1
,下面的组件是 Component2
,可见 Component1
上有一个自定义属性 data-v-04421304
,接着使用一个属性选择器使得样式只对 Component1
生效
Module CSS
另一种比较流行的方案是 CSS in JS
,也就是 Module CSS
,首先我们需要为 style
标签添加了 module
标签
<style module> |
添加 module
属性后,组件中便会有 $style
这个计算属性,它是一个对象,我们可以通过 $style.类名
的方式为组件添加样式,例如
<template> |
实际的类名为
Component1_com_2ata3
,它的组成为 组件名_类名_哈希串
。
Module CSS
相对于 Scoped CSS
较为灵活
<div :class="$style.com">Hello World</div> |
可以通过数据来控制是否添加类名,从而控制样式,以及我们还可以在 JS
中访问 $style
created() { |
Module CSS
与Scoped CSS
并无高下之分,哪个用起来舒服便使用哪个。