Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供:
@vue/cli
实现的交互式的项目脚手架。@vue/cli
+ @vue/cli-service-global
实现的零配置原型开发。@vue/cli-service
),该依赖:
Vue CLI 致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。与此同时,它也为每个工具提供了调整配置的灵活性,无需 eject。
关于旧版本
Vue CLI 的包名称由 vue-cli
改成了 @vue/cli
。 如果你已经全局安装了旧版本的 vue-cli
(1.x 或 2.x),你需要先通过 npm uninstall vue-cli -g
或 yarn global remove vue-cli
卸载它。
Node 版本要求
Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)。你可以使用 n,nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。
安装Node.js淘宝镜像加速器(cnpm)
# -g就是全局安装
npm install cnpm -g
# 或使用如下语句解决npm速度慢的问题
npm install --registry=https://registry.npm.taobao.org
可以使用下列任一命令安装这个新的包
npm install -g @vue/cli
# OR
yarn global add @vue/cli
安装之后,你就可以在命令行中访问 vue
命令。你可以通过简单运行 vue
,看看是否展示出了一份所有可用命令的帮助信息,来验证它是否安装成功。
你还可以用这个命令来检查其版本是否正确:
vue --version
升级
如需升级全局的 Vue CLI 包,请运行:
npm update -g @vue/cli
# 或者
yarn global upgrade --latest @vue/cli
项目依赖
上面列出来的命令是用于升级全局的 Vue CLI。如需升级项目中的 Vue CLI 相关模块(以 @vue/cli-plugin-
或 vue-cli-plugin-
开头),请在项目目录下运行 vue upgrade
:
用法: upgrade [options] [plugin-name]
(试用)升级 Vue CLI 服务及插件
选项:
-t, --to 升级 到指定的版本
-f, --from 跳过本地版本检测,默认插件是从此处指定的版本升级上来
-r, --registry 使用指定的 registry 地址安装依赖
--all 升级所有的插件
--next 检查插件新版本时,包括 alpha/beta/rc 版本在内
-h, --help 输出帮助内容
你可以使用 vue serve
和 vue build
命令对单个 *.vue
文件进行快速原型开发,不过这需要先额外安装一个全局的扩展:
npm install -g @vue/cli-service-global
vue serve
的缺点就是它需要安装全局依赖,这使得它在不同机器上的一致性不能得到保证。因此这只适用于快速原型开发。v
vue serve
Usage: serve [options] [entry]
在开发环境模式下零配置为 .js 或 .vue 文件启动一个服务器
Options:
-o, --open 打开浏览器
-c, --copy 将本地 URL 复制到剪切板
-h, --help 输出用法信息
你所需要的仅仅是一个 App.vue
文件:
Hello!
然后在这个 App.vue
文件所在的目录下运行:
vue serve
vue serve
使用了和 vue create
创建的项目相同的默认设置 (webpack、Babel、PostCSS 和 ESLint)。它会在当前目录自动推导入口文件——入口可以是 main.js
、index.js
、App.vue
或 app.vue
中的一个。你也可以显式地指定入口文件:
vue serve MyComponent.vue
如果需要,你还可以提供一个 index.html
、package.json
、安装并使用本地依赖、甚至通过相应的配置文件配置 Babel、PostCSS 和 ESLint。
vue build
Usage: build [options] [entry]
在生产环境模式下零配置构建一个 .js 或 .vue 文件
Options:
-t, --target 构建目标 (app | lib | wc | wc-async, 默认值:app)
-n, --name 库的名字或 Web Components 组件的名字 (默认值:入口文件名)
-d, --dest 输出目录 (默认值:dist)
-h, --help 输出用法信息
你也可以使用 vue build
将目标文件构建成一个生产环境的包并用来部署:
vue build MyComponent.vue
vue build
也提供了将组件构建成为一个库或一个 Web Components 组件的能力。
vue create
运行以下命令来创建一个新项目:
vue create hello-world
警告
如果你在 Windows 上通过 minTTY 使用 Git Bash,交互提示符并不工作。你必须通过 winpty vue.cmd create hello-world
启动这个命令。不过,如果你仍想使用 vue create hello-world
,则可以通过在 ~/.bashrc
文件中添加以下行来为命令添加别名。 alias vue='winpty vue.cmd'
你需要重新启动 Git Bash 终端会话以使更新后的 bashrc 文件生效。
你会被提示选取一个 preset。你可以选默认的包含了基本的 Babel + ESLint 设置的 preset,也可以选“手动选择特性”来选取需要的特性。
这个默认的设置非常适合快速创建一个新项目的原型,而手动设置则提供了更多的选项,它们是面向生产的项目更加需要的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ac1X8LP1-1613885705725)(https://cli.vuejs.org/cli-select-features.png)]
如果你决定手动选择特性,在操作提示的最后你可以选择将已选项保存为一个将来可复用的 preset。我们会在下一个章节讨论 preset 和插件。
~/.vuerc
被保存的 preset 将会存在用户的 home 目录下一个名为 .vuerc
的 JSON 文件里。如果你想要修改被保存的 preset / 选项,可以编辑这个文件。
在项目创建的过程中,你也会被提示选择喜欢的包管理器或使用淘宝 npm 镜像源以更快地安装依赖。这些选择也将会存入 ~/.vuerc
。
vue create
命令有一些可选项,你可以通过运行以下命令进行探索:
vue create --help
用法:create [options] <app-name>
创建一个由 `vue-cli-service` 提供支持的新项目
选项:
-p, --preset <presetName> 忽略提示符并使用已保存的或远程的预设选项
-d, --default 忽略提示符并使用默认预设选项
-i, --inlinePreset <json> 忽略提示符并使用内联的 JSON 字符串预设选项
-m, --packageManager <command> 在安装依赖时使用指定的 npm 客户端
-r, --registry <url> 在安装依赖时使用指定的 npm registry
-g, --git [message] 强制 / 跳过 git 初始化,并可选的指定初始化提交信息
-n, --no-git 跳过 git 初始化
-f, --force 覆写目标目录可能存在的配置
-c, --clone 使用 git clone 获取远程预设选项
-x, --proxy 使用指定的代理创建项目
-b, --bare 创建项目时省略默认组件中的新手指导信息
-h, --help 输出使用帮助信息
使用图形化界面
你也可以通过 vue ui
命令以图形化界面创建和管理项目:
vue ui
上述命令会打开一个浏览器窗口,并以图形化界面将你引导至项目创建的流程。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JXvAdaYR-1613885705726)(https://cli.vuejs.org/ui-new-project.png)]
拉取 2.x 模板 (旧版本)
Vue CLI >= 3 和旧版使用了相同的 vue
命令,所以 Vue CLI 2 (vue-cli
) 被覆盖了。如果你仍然需要使用旧版本的 vue init
功能,你可以全局安装一个桥接工具:
npm install -g @vue/cli-init
# `vue init` 的运行效果将会跟 `[email protected]` 相同
vue init webpack my-project
插件
Vue CLI 使用了一套基于插件的架构。如果你查阅一个新创建项目的 package.json
,就会发现依赖都是以 @vue/cli-plugin-
开头的。插件可以修改 webpack 的内部配置,也可以向 vue-cli-service
注入命令。在项目创建的过程中,绝大部分列出的特性都是通过插件来实现的。
基于插件的架构使得 Vue CLI 灵活且可扩展。如果你对开发一个插件感兴趣,请翻阅插件开发指南。
提示
你可以通过 vue ui
命令使用 GUI 安装和管理插件。
在现有的项目中安装插件
每个 CLI 插件都会包含一个 (用来创建文件的) 生成器和一个 (用来调整 webpack 核心配置和注入命令的) 运行时插件。当你使用 vue create
来创建一个新项目的时候,有些插件会根据你选择的特性被预安装好。如果你想在一个已经被创建好的项目中安装一个插件,可以使用 vue add
命令:
vue add eslint
提示
vue add
的设计意图是为了安装和调用 Vue CLI 插件。这不意味着替换掉普通的 npm 包。对于这些普通的 npm 包,你仍然需要选用包管理器。
警告
我们推荐在运行 vue add
之前将项目的最新状态提交,因为该命令可能调用插件的文件生成器并很有可能更改你现有的文件。
这个命令将 @vue/eslint
解析为完整的包名 @vue/cli-plugin-eslint
,然后从 npm 安装它,调用它的生成器。
# 这个和之前的用法等价
vue add cli-plugin-eslint
如果不带 @vue
前缀,该命令会换作解析一个 unscoped 的包。例如以下命令会安装第三方插件 vue-cli-plugin-apollo
:
# 安装并调用 vue-cli-plugin-apollo
vue add apollo
你也可以基于一个指定的 scope 使用第三方插件。例如如果一个插件名为 @foo/vue-cli-plugin-bar
,你可以这样添加它:
vue add @foo/bar
你可以向被安装的插件传递生成器选项 (这样做会跳过命令提示):
vue add eslint --config airbnb --lintOn save
如果一个插件已经被安装,你可以使用 vue invoke
命令跳过安装过程,只调用它的生成器。这个命令会接受和 vue add
相同的参数。
提示
如果出于一些原因你的插件列在了该项目之外的其它 package.json
文件里,你可以在自己项目的 package.json
里设置 vuePlugins.resolveFrom
选项指向包含其它 package.json
的文件夹。
例如,如果你有一个 .config/package.json
文件:
{
"vuePlugins": {
"resolveFrom": ".config"
}
}
项目本地的插件
如果你需要在项目里直接访问插件 API 而不需要创建一个完整的插件,你可以在 package.json
文件中使用 vuePlugins.service
选项:
{
"vuePlugins": {
"service": ["my-commands.js"]
}
}
每个文件都需要暴露一个函数,接受插件 API 作为第一个参数。
你也可以通过 vuePlugins.ui
选项添加像 UI 插件一样工作的文件:
{
"vuePlugins": {
"ui": ["my-ui.js"]
}
}
Preset
一个 Vue CLI preset 是一个包含创建新项目所需预定义选项和插件的 JSON 对象,让用户无需在命令提示中选择它们。
在 vue create
过程中保存的 preset 会被放在你的 home 目录下的一个配置文件中 (~/.vuerc
)。你可以通过直接编辑这个文件来调整、添加、删除保存好的 preset。
这里有一个 preset 的示例:
{
"useConfigFiles": true,
"cssPreprocessor": "sass",
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-eslint": {
"config": "airbnb",
"lintOn": ["save", "commit"]
},
"@vue/cli-plugin-router": {},
"@vue/cli-plugin-vuex": {}
}
}
Preset 的数据会被插件生成器用来生成相应的项目文件。除了上述这些字段,你也可以为集成工具添加配置:
{
"useConfigFiles": true,
"plugins": {...},
"configs": {
"vue": {...},
"postcss": {...},
"eslintConfig": {...},
"jest": {...}
}
}
这些额外的配置将会根据 useConfigFiles
的值被合并到 package.json
或相应的配置文件中。例如,当 "useConfigFiles": true
的时候,configs
的值将会被合并到 vue.config.js
中。
Preset 插件的版本管理
你可以显式地指定用到的插件的版本:
{
"plugins": {
"@vue/cli-plugin-eslint": {
"version": "^3.0.0",
// ... 该插件的其它选项
}
}
}
注意对于官方插件来说这不是必须的——当被忽略时,CLI 会自动使用 registry 中最新的版本。不过我们推荐为 preset 列出的所有第三方插件提供显式的版本范围。
允许插件的命令提示
每个插件在项目创建的过程中都可以注入它自己的命令提示,不过当你使用了一个 preset,这些命令提示就会被跳过,因为 Vue CLI 假设所有的插件选项都已经在 preset 中声明过了。
在有些情况下你可能希望 preset 只声明需要的插件,同时让用户通过插件注入的命令提示来保留一些灵活性。
对于这种场景你可以在插件选项中指定 "prompts": true
来允许注入命令提示:
{
"plugins": {
"@vue/cli-plugin-eslint": {
// 让用户选取他们自己的 ESLint config
"prompts": true
}
}
}
远程 Preset
你可以通过发布 git repo 将一个 preset 分享给其他开发者。这个 repo 应该包含以下文件:
preset.json
: 包含 preset 数据的主要文件(必需)。generator.js
: 一个可以注入或是修改项目中文件的 Generator。prompts.js
一个可以通过命令行对话为 generator 收集选项的 prompts 文件。发布 repo 后,你就可以在创建项目的时候通过 --preset
选项使用这个远程的 preset 了:
# 从 GitHub repo 使用 preset
vue create --preset username/repo my-project
GitLab 和 BitBucket 也是支持的。如果要从私有 repo 获取,请确保使用 --clone
选项:
vue create --preset gitlab:username/repo --clone my-project
vue create --preset bitbucket:username/repo --clone my-project
# 私有服务器
vue create --preset gitlab:my-gitlab-server.com:group/projectname --clone my-project
vue create --preset direct:ssh://[email protected]/group/projectname.git --clone my-project
加载文件系统中的 Preset
当开发一个远程 preset 的时候,你必须不厌其烦的向远程 repo 发出 push 进行反复测试。为了简化这个流程,你也可以直接在本地测试 preset。如果 --preset
选项的值是一个相对或绝对文件路径,或是以 .json
结尾,则 Vue CLI 会加载本地的 preset:
# ./my-preset 应当是一个包含 preset.json 的文件夹
vue create --preset ./my-preset my-project
# 或者,直接使用当前工作目录下的 json 文件:
vue create --preset my-preset.json my-project
使用命令
在一个 Vue CLI 项目中,@vue/cli-service
安装了一个名为 vue-cli-service
的命令。你可以在 npm scripts 中以 vue-cli-service
、或者从终端中以 ./node_modules/.bin/vue-cli-service
访问这个命令。
这是你使用默认 preset 的项目的 package.json
:
{
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
}
}
你可以通过 npm 或 Yarn 调用这些 script:
npm run serve
# OR
yarn serve
如果你可以使用 npx (最新版的 npm 应该已经自带),也可以直接这样调用命令:
npx vue-cli-service serve
提示
你可以通过 vue ui
命令使用 GUI 运行更多的特性脚本。
这里有一个 GUI 的 webpack Analyzer:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aBoO2yEI-1613885705729)(E:\Users\Jinyong\Desktop\博客\Vue实践.assets\ui-analyzer.png)]
vue-cli-service serve
用法:vue-cli-service serve [options] [entry]
选项:
--open 在服务器启动时打开浏览器
--copy 在服务器启动时将 URL 复制到剪切版
--mode 指定环境模式 (默认值:development)
--host 指定 host (默认值:0.0.0.0)
--port 指定 port (默认值:8080)
--https 使用 https (默认值:false)
vue-cli-service serve
命令会启动一个开发服务器 (基于 webpack-dev-server) 并附带开箱即用的模块热重载 (Hot-Module-Replacement)。
除了通过命令行参数,你也可以使用 vue.config.js
里的 devServer 字段配置开发服务器。
命令行参数 [entry]
将被指定为唯一入口,而非额外的追加入口。尝试使用 [entry]
覆盖 config.pages
中的 entry
将可能引发错误。
vue-cli-service build
用法:vue-cli-service build [options] [entry|pattern]
选项:
--mode 指定环境模式 (默认值:production)
--dest 指定输出目录 (默认值:dist)
--modern 面向现代浏览器带自动回退地构建应用
--target app | lib | wc | wc-async (默认值:app)
--name 库或 Web Components 模式下的名字 (默认值:package.json 中的 "name" 字段或入口文件名)
--no-clean 在构建项目之前不清除目标目录
--report 生成 report.html 以帮助分析包内容
--report-json 生成 report.json 以帮助分析包内容
--watch 监听文件变化
vue-cli-service build
会在 dist/
目录产生一个可用于生产环境的包,带有 JS/CSS/HTML 的压缩,和为更好的缓存而做的自动的 vendor chunk splitting。它的 chunk manifest 会内联在 HTML 里。
这里还有一些有用的命令参数:
--modern
使用现代模式构建应用,为现代浏览器交付原生支持的 ES2015 代码,并生成一个兼容老浏览器的包用来自动回退。--target
允许你将项目中的任何组件以一个库或 Web Components 组件的方式进行构建。更多细节请查阅构建目标。--report
和 --report-json
会根据构建统计生成报告,它会帮助你分析包中包含的模块们的大小。vue-cli-service inspect
用法:vue-cli-service inspect [options] [...paths]
选项:
--mode 指定环境模式 (默认值:development)
你可以使用 vue-cli-service inspect
来审查一个 Vue CLI 项目的 webpack config。更多细节请查阅审查 webpack config。
查看所有的可用命令
有些 CLI 插件会向 vue-cli-service
注入额外的命令。例如 @vue/cli-plugin-eslint
会注入 vue-cli-service lint
命令。你可以运行以下命令查看所有注入的命令:
npx vue-cli-service help
你也可以这样学习每个命令可用的选项:
npx vue-cli-service help [command]
缓存和并行处理
cache-loader
会默认为 Vue/Babel/TypeScript 编译开启。文件会缓存在 node_modules/.cache
中——如果你遇到了编译方面的问题,记得先删掉缓存目录之后再试试看。thread-loader
会在多核 CPU 的机器上为 Babel/TypeScript 转译开启。Git Hook
在安装之后,@vue/cli-service
也会安装 yorkie,它会让你在 package.json
的 gitHooks
字段中方便地指定 Git hook:
{
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,vue}": [
"vue-cli-service lint",
"git add"
]
}
}
注意
yorkie
fork 自 husky
并且与后者不兼容。
配置时无需 Eject
通过 vue create
创建的项目无需额外的配置就已经可以跑起来了。插件的设计也是可以相互共存的,所以绝大多数情况下,你只需要在交互式命令提示中选取需要的功能即可。
不过我们也知道满足每一个需求是不太可能的,而且一个项目的需求也会不断改变。通过 Vue CLI 创建的项目让你无需 eject 就能够配置工具的几乎每个角落。
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
从 webpack v4.0.0 开始,可以不用引入一个配置文件。然而,webpack 仍然还是高度可配置的。在开始前你需要先理解四个核心概念:
入口(entry)
**入口起点(entry point)**指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
每个依赖项随即被处理,最后输出到称之为 bundles 的文件中,我们将在下一章节详细讨论这个过程。
可以通过在 webpack 配置中配置 entry
属性,来指定一个入口起点(或多个入口起点)。默认值为 ./src
。
接下来我们看一个 entry
配置的最简单例子:
webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js'
};
出口(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist
。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output
字段,来配置这些处理过程:
webpack.config.js
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};
在上面的示例中,我们通过 output.filename
和 output.path
属性,来告诉 webpack bundle 的名称,以及我们想要 bundle 生成(emit)到哪里。可能你想要了解在代码最上面导入的 path 模块是什么,它是一个 Node.js 核心模块,用于操作文件路径。
loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
注意,loader 能够
import
导入任何类型的模块(例如.css
文件),这是 webpack 特有的功能,其他打包程序或任务执行器的可能并不支持。我们认为这种语言扩展是有很必要的,因为这可以使开发人员创建出更准确的依赖关系图。
在更高层面,在 webpack 的配置中 loader 有两个目标:
test
属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。use
属性,表示进行转换时,应该使用哪个 loader。webpack.config.js
const path = require('path');
const config = {
output: {
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};
module.exports = config;
以上配置中,对一个单独的 module 对象定义了 rules
属性,里面包含两个必须属性:test
和 use
。这告诉 webpack 编译器(compiler) 如下信息:
注意:
require()
/import
语句中被解析为 ‘.txt’ 的路径」时,在你对它打包之前,先使用 raw-loader
转换一下。”module.rules
中,而不是 rules
。然而,在定义错误时 webpack 会给出严重的警告。为了使你受益于此,如果没有按照正确方式去做,webpack 会“给出严重的警告”插件(plugins)
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
想要使用一个插件,你只需要 require()
它,然后把它添加到 plugins
数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new
操作符来创建它的一个实例。
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件
const config = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
webpack 提供许多开箱可用的插件!
模式
通过选择 development
或 production
之中的一个,来设置 mode
参数,你可以启用相应模式下的 webpack 内置的优化
module.exports = {
mode: 'production'
};
安装:
npm install webpack -g
npm install webpack-cli -g
测试安装成功:
webpack -v
webpack-cli -v
新建webpack-study文件夹
用IDEA打开这个文件夹
在webpack-study文件夹下新建modules文件夹
在modules文件夹下新建hello.js
//暴露一个方法
exports.sayHi = function () {
document.write("hello,暴露一个方法
")
}
在modules文件夹下新建main.js
var hello = require("./hello");
hello.sayHi();
在webpack-study文件夹下新建webpack.config.js
module.exports = {
entry:'./modules/main.js',
output: {
filename:'./js/bundles.js'
}
};
在当前项目文件夹位置用cmd打开,输入webpack,刷新,生成dist文件夹
在webpack-study文件夹下新建index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<script src="dist/js/bundles.js">script>
body>
html>
浏览器输出成功,测试OK
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
https://unpkg.com/vue-router/dist/vue-router.js
Unpkg.com 提供了基于 NPM 的 CDN 链接。上面的链接会一直指向在 NPM 发布的最新版本。你也可以像 https://unpkg.com/[email protected]/dist/vue-router.js
这样指定 版本号 或者 Tag。
在 Vue 后面加载 vue-router
,它会自动安装的:
<script src="/path/to/vue.js">script>
<script src="/path/to/vue-router.js">script>
npm install vue-router
如果在一个模块化工程中使用它,必须要通过 Vue.use()
明确地安装路由功能:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
如果使用全局的 script 标签,则无须如此 (手动安装)。
如果你有一个正在使用 Vue CLI 的项目,你可以以项目插件的形式添加 Vue Router。CLI 可以生成上述代码及两个示例路由。它也会覆盖你的 App.vue
,因此请确保在项目中运行以下命令之前备份这个文件:
vue add router
如果你想使用最新的开发版,就得从 GitHub 上直接 clone,然后自己 build 一个 vue-router
。
git clone https://github.com/vuejs/vue-router.git node_modules/vue-router
cd node_modules/vue-router
npm install
npm run build
用 Vue.js + Vue Router 创建单页应用,感觉很自然:使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 Vue Router 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。下面是个基本例子:
HTML
<script src="https://unpkg.com/vue/dist/vue.js">script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js">script>
<div id="app">
<h1>Hello App!h1>
<p>
<router-link to="/foo">Go to Foorouter-link>
<router-link to="/bar">Go to Barrouter-link>
p>
<router-view>router-view>
div>
JavaScript
// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = { template: 'foo' }
const Bar = { template: 'bar' }
// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')
// 现在,应用已经启动了!
通过注入路由器,我们可以在任何组件内通过 this.$router
访问路由器,也可以通过 this.$route
访问当前路由:
// Home.vue
export default {
computed: {
username() {
// 我们很快就会看到 `params` 是什么
return this.$route.params.username
}
},
methods: {
goBack() {
window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/')
}
}
}
该文档通篇都常使用 router
实例。留意一下 this.$router
和 router
使用起来完全一样。我们使用 this.$router
的原因是我们并不想在每个独立需要封装路由的组件中都导入路由。
要注意,当
对应的路由匹配成功,将自动设置 class 属性值 .router-link-active
。
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User
组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router
的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:
const User = {
template: 'User'
}
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
现在呢,像 /user/foo
和 /user/bar
都将映射到相同的路由。
一个“路径参数”使用冒号 :
标记。当匹配到一个路由时,参数值会被设置到 this.$route.params
,可以在每个组件内使用。于是,我们可以更新 User
的模板,输出当前用户的 ID:
const User = {
template: 'User {{ $route.params.id }}'
}
你可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params
中。例如:
模式 | 匹配路径 | $route.params |
---|---|---|
/user/:username | /user/evan | { username: 'evan' } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: 'evan', post_id: '123' } |
除了 $route.params
外,$route
对象还提供了其它有用的信息,例如,$route.query
(如果 URL 中有查询参数)、$route.hash
等等。
响应路由参数的变化
提醒一下,当使用路由参数时,例如从 /user/foo
导航到 /user/bar
,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route
对象:
const User = {
template: '...',
watch: {
$route(to, from) {
// 对路由变化作出响应...
}
}
}
或者使用 2.2 中引入的 beforeRouteUpdate
导航守卫:
const User = {
template: '...',
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
}
捕获所有路由或 404 Not found 路由
常规参数只会匹配被 /
分隔的 URL 片段中的字符。如果想匹配任意路径,我们可以使用通配符 (*
):
{
// 会匹配所有路径
path: '*'
}
{
// 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
当使用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该放在最后。路由 { path: '*' }
通常用于客户端 404 错误。如果你使用了History 模式,请确保正确配置你的服务器。
当使用一个通配符时,$route.params
内会自动添加一个名为 pathMatch
参数。它包含了 URL 通过通配符被匹配的部分:
// 给出一个路由 { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// 给出一个路由 { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'
高级匹配模式
vue-router
使用 path-to-regexp 作为路径匹配引擎,所以支持很多高级的匹配模式,例如:可选的动态路径参数、匹配零个或多个、一个或多个,甚至是自定义正则匹配。查看它的文档学习高阶的路径匹配,还有这个例子 展示 vue-router
怎么使用这类匹配。
匹配优先级
有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。
实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如:
/user/foo/profile /user/foo/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
借助 vue-router
,使用嵌套路由配置,就可以很简单地表达这种关系。
接着上节创建的 app:
<div id="app">
<router-view>router-view>
div>
const User = {
template: '<div>User {{ $route.params.id }}div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
这里的
是最顶层的出口,渲染最高级路由匹配到的组件。同样地,一个被渲染组件同样可以包含自己的嵌套
。例如,在 User
组件的模板添加一个
:
const User = {
template: `
User {{ $route.params.id }}
`
}
要在嵌套的出口中渲染组件,需要在 VueRouter
的参数中使用 children
配置:
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 中
path: 'posts',
component: UserPosts
}
]
}
]
})
要注意,以 /
开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。
你会发现,children
配置就是像 routes
配置一样的路由配置数组,所以呢,你可以嵌套多层路由。
此时,基于上面的配置,当你访问 /user/foo
时,User
的出口是不会渲染任何东西,这是因为没有匹配到合适的子路由。如果你想要渲染点什么,可以提供一个 空的 子路由:
const router = new VueRouter({
routes: [
{
path: '/user/:id', component: User,
children: [
// 当 /user/:id 匹配成功,
// UserHome 会被渲染在 User 的 中
{ path: '', component: UserHome },
// ...其他子路由
]
}
]
})
除了使用
创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
router.push(location, onComplete?, onAbort?)
注意:在 Vue 实例内部,你可以通过 $router
访问路由实例。因此你可以调用 this.$router.push
。
想要导航到不同的 URL,则使用 router.push
方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
当你点击
时,这个方法会在内部调用,所以说,点击
等同于调用 router.push(...)
。
声明式 | 编程式 |
---|---|
|
router.push(...) |
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
注意:如果提供了 path
,params
会被忽略,上述例子中的 query
并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name
或手写完整的带有参数的 path
:
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
同样的规则也适用于 router-link
组件的 to
属性。
在 2.2.0+,可选的在 router.push
或 router.replace
中提供 onComplete
和 onAbort
回调作为第二个和第三个参数。这些回调将会在导航成功完成 (在所有的异步钩子被解析之后) 或终止 (导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由) 的时候进行相应的调用。在 3.1.0+,可以省略第二个和第三个参数,此时如果支持 Promise,router.push
或 router.replace
将返回一个 Promise。
注意: 如果目的地和当前路由相同,只有参数发生了改变 (比如从一个用户资料到另一个 /users/1
-> /users/2
),你需要使用 beforeRouteUpdate
来响应这个变化 (比如抓取用户信息)。
router.replace(location, onComplete?, onAbort?)
跟 router.push
很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
声明式 | 编程式 |
---|---|
|
router.replace(...) |
router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)
。
例子
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)
操作 History
你也许注意到 router.push
、 router.replace
和 router.go
跟 window.history.pushState
、 window.history.replaceState
和 window.history.go
好像, 实际上它们确实是效仿 window.history
API 的。
因此,如果你已经熟悉 Browser History APIs,那么在 Vue Router 中操作 history 就是超级简单的。
还有值得提及的,Vue Router 的导航方法 (push
、 replace
、 go
) 在各类路由模式 (history
、 hash
和 abstract
) 下表现一致。
有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes
配置中给某个路由设置名称。
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
要链接到一个命名路由,可以给 router-link
的 to
属性传一个对象:
<router-link :to="{ name: 'user', params: { userId: 123 }}">Userrouter-link>
这跟代码调用 router.push()
是一回事:
router.push({ name: 'user', params: { userId: 123 }})
这两种方式都会把路由导航到 /user/123
路径。
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar
(侧导航) 和 main
(主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view
没有设置名字,那么默认为 default
。
<router-view class="view one">router-view>
<router-view class="view two" name="a">router-view>
<router-view class="view three" name="b">router-view>
一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components
配置 (带上 s):
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
我们也有可能使用命名视图创建嵌套视图的复杂布局。这时你也需要命名用到的嵌套 router-view
组件。我们以一个设置面板为例:
/settings/emails /settings/profile
+-----------------------------------+ +------------------------------+
| UserSettings | | UserSettings |
| +-----+-------------------------+ | | +-----+--------------------+ |
| | Nav | UserEmailsSubscriptions | | +------------> | | Nav | UserProfile | |
| | +-------------------------+ | | | +--------------------+ |
| | | | | | | | UserProfilePreview | |
| +-----+-------------------------+ | | +-----+--------------------+ |
+-----------------------------------+ +------------------------------+
Nav
只是一个常规组件。UserSettings
是一个视图组件。UserEmailsSubscriptions
、UserProfile
、UserProfilePreview
是嵌套的视图组件。注意:我们先忘记 HTML/CSS 具体的布局的样子,只专注在用到的组件上。
UserSettings
组件的 部分应该是类似下面的这段代码:
<div>
<h1>User Settingsh1>
<NavBar/>
<router-view/>
<router-view name="helper"/>
div>
嵌套的视图组件在此已经被忽略了,但是你可以在这里找到完整的源代码。
然后你可以用这个路由配置完成该布局:
{
path: '/settings',
// 你也可以在顶级路由就配置命名视图
component: UserSettings,
children: [{
path: 'emails',
component: UserEmailsSubscriptions
}, {
path: 'profile',
components: {
default: UserProfile,
helper: UserProfilePreview
}
}]
}。
重定向也是通过 routes
配置来完成,下面例子是从 /a
重定向到 /b
:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
重定向的目标也可以是一个命名的路由:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
甚至是一个方法,动态返回重定向目标:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
]
})
注意导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。在下面这个例子中,为 /a
路由添加一个 beforeEnter
守卫并不会有任何效果。
“重定向”的意思是,当用户访问 /a
时,URL 将会被替换成 /b
,然后匹配路由为 /b
,那么“别名”又是什么呢?
/a
的别名是 /b
,意味着,当用户访问 /b
时,URL 会保持为 /b
,但是路由匹配则为 /a
,就像用户访问 /a
一样。
上面对应的路由配置为:
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。
在组件中使用 $route
会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
使用 props
将组件和路由解耦:
取代与 $route
的耦合
const User = {
template: 'User {{ $route.params.id }}'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
通过 props
解耦
const User = {
props: ['id'],
template: 'User {{ id }}'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true },
// 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
})
这样你便可以在任何地方使用该组件,使得该组件更易于重用和测试。
如果 props
被设置为 true
,route.params
将会被设置为组件属性。
如果 props
是一个对象,它会被按原样设置为组件属性。当 props
是静态的时候有用。
const router = new VueRouter({
routes: [
{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
]
})
你可以创建一个函数返回 props
。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。
const router = new VueRouter({
routes: [
{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
]
})
URL /search?q=vue
会将 {query: 'vue'}
作为属性传递给 SearchUser
组件。
请尽可能保持 props
函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props
,请使用包装组件,这样 Vue 才可以对状态变化做出反应。
vue-router
默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState
API 来完成 URL 跳转而无须重新加载页面。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id
,也好看!
不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id
就会返回 404,这就不好看了。
所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html
页面,这个页面就是你 app 依赖的页面。
注意:下列示例假设你在根目录服务这个应用。如果想部署到一个子目录,你需要使用 Vue CLI 的 publicPath
选项 和相关的 router base
property。你还需要把下列示例中的根目录调整成为子目录 (例如用 RewriteBase /name-of-your-subfolder/
替换掉 RewriteBase /
)。
Apache
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
除了 mod_rewrite
,你也可以使用 FallbackResource
。
nginx
location / {
try_files $uri $uri/ /index.html;
}
原生 Node.js
const http = require('http')
const fs = require('fs')
const httpPort = 80
http.createServer((req, res) => {
fs.readFile('index.html', 'utf-8', (err, content) => {
if (err) {
console.log('We cannot open "index.html" file.')
}
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8'
})
res.end(content)
})
}).listen(httpPort, () => {
console.log('Server listening on: http://localhost:%s', httpPort)
})
基于 Node.js 的 Express
对于 Node.js/Express,请考虑使用 connect-history-api-fallback 中间件。
Internet Information Services (IIS)
web.config
文件,内容如下:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Handle History Mode and custom 404/500" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
conditions>
<action type="Rewrite" url="/" />
rule>
rules>
rewrite>
system.webServer>
configuration>
Caddy
rewrite {
regexp .*
to {path} /
}
Firebase 主机
在你的 firebase.json
中加入:
{
"hosting": {
"public": "dist",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
给个警告,因为这么做以后,你的服务器就不再返回 404 错误页面,因为对于所有路径都会返回 index.html
文件。为了避免这种情况,你应该在 Vue 应用里面覆盖所有的路由情况,然后在给出一个 404 页面。
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '*', component: NotFoundComponent }
]
})
或者,如果你使用 Node.js 服务器,你可以用服务端路由匹配到来的 URL,并在没有匹配到路由的时候返回 404,以实现回退。
注意:命令行都要使用管理员模式运行
创建一个名为hello-vue的工程vue init webpack hello-vue
安装依赖,我们需要安装vue-router、element-ui、sass-loader和node-sass四个插件
# 进入工程目录
cd hello-vue
# 安装 vue-router
npm install vue-router --save-dev
# 安装 element-ui
npm i element-ui -S
# 安装依赖
npm install
# 安装SASS加载器
npm install sass-loader node-sass --save-dev
#启动测试
npm run dev
npm命令解释
npm install moduleName
:安装模块到项目目录下npm install -g moduleName
:-g的意思是将模块安装到全局,具体安装到磁盘的哪个位置,要看npm config prefix的位置npm install --save moduleName
:–save的意思是将模块安装到项目目录下,并在package文件的dependencies节点写如依赖,-S为该命令的缩写npm install -save-dev moduleName
:–save-dev的意思是将模块安装到项目目录下,并在package文件的decDependencies节点写如依赖,-D为该命令的缩写把没有用的初始化东西删掉,在源码目录中创建如下结构:
在views目录下创建一个名为Main.vue的视图组件
首页
在views目录下创建一个名为Login.vue的视图组件,其中el-*的元素为ElementUI组件
欢迎登录
登录
请输入账号和密码
在项目目录下创建一个router文件夹,在该文件夹下新建index.js
import Vue from 'vue';
import Router from "vue-router";
import Main from "../views/Main";
import Login from "../views/Login";
Vue.use(Router);
export default new Router({
routes:[
{
path: '/main',
component: Main
},
{
path: '/login',
component: Login
}
]
});
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
//路由
import router from "./router";
//ElementUI
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)//ElementUI
})
运行npm run dev
,error!!!
问题一:
Module build failed: TypeError: this.getOptions is not a function
解决问题:
# 卸载已安装版本
npm uninstall sass-loader
# 安装
npm install [email protected] --save-dev
问题二:
Node Sass version 5.0.0 is incompatible with ^4.0.0.
解决问题:
# 卸载已安装版本
npm uninstall node-sass
# 安装
npm install [email protected]
注意点:
vue实例里固定路由器的书写为"router"
运行npm run dev
访问http://localhost:8080/#/login
个人信息
用户列表
用户管理
个人信息
用户列表
回到首页
内容管理
分类管理
内容列表
系统管理
用户设置
个人信息
退出登录
import Vue from 'vue';
import Router from "vue-router";
import Main from "../views/Main";
import Login from "../views/Login";
import List from "../views/user/List";
import Profile from "../views/user/Profile";
Vue.use(Router);
export default new Router({
routes:[
{
path: '/main',
component: Main,
//嵌套路由
children:[
{
path: '/user/list',
component: List
},
{
path: '/user/profile',
component: Profile
}
]
},
{
path: '/login',
component: Login
},
]
});
OK
注意:这里需要双向绑定和name传递的是组件名字
个人信息
{
path: '/user/profile/:id',
name: 'Profile',
component: Profile
}
注意:只能由一个根节点
个人信息
{{$route.params.id}}
OK
增加props支持
{
path: '/user/profile/:id',
name: 'Profile',
component: Profile,
props: true
}
个人信息
{{$route.params.id}}
{{id}}
OK
export default new Router({
routes:[
{
path: '/main',
component: Main,
//嵌套路由
children:[
{
path: '/user/list',
component: List
},
{
path: '/user/profile/:id',
name: 'Profile',
component: Profile,
props: true
}
]
},
{
path: '/login',
component: Login
},
{
path: '/goHome',
redirect: '/main'
}
]
});
回到首页
OK
欢迎登录
登录
请输入账号和密码
import Vue from 'vue';
import Router from "vue-router";
import Main from "../views/Main";
import Login from "../views/Login";
import List from "../views/user/List";
import Profile from "../views/user/Profile";
Vue.use(Router);
export default new Router({
routes:[
{
path: '/main/:name',
component: Main,
props: true,
//嵌套路由
children:[
{
path: '/user/list',
component: List
},
{
path: '/user/profile/:id',
name: 'Profile',
component: Profile,
props: true
}
]
},
{
path: '/login',
component: Login
},
{
path: '/goHome',
redirect: '/main'
}
]
});
用户管理
个人信息
用户列表
回到首页
内容管理
分类管理
内容列表
个人信息
退出登录
{{name}}
登录后右上角显示名字,OK
路由模式有两种:
修改路由模式配置,代码如下
export default new Router({
mode: 'history',
routes:[
]
});
在views文件夹下,创建一个名为NotFound.vue的视图组件
404,您的页面走丢了
import Vue from 'vue';
import Router from "vue-router";
import Main from "../views/Main";
import Login from "../views/Login";
import List from "../views/user/List";
import Profile from "../views/user/Profile";
import NotFound from "../views/NotFound";
Vue.use(Router);
export default new Router({
mode: 'history',
routes:[
{
path: '/main/:name',
component: Main,
props: true,
//嵌套路由
children:[
{
path: '/user/list',
component: List
},
{
path: '/user/profile/:id',
name: 'Profile',
component: Profile,
props: true
}
]
},
{
path: '/login',
component: Login
},
{
path: '/goHome',
redirect: '/main'
},
{
path: '/*',
component: NotFound
}
]
});
访问任意没有定义的网址,走到404页面,OK
个人信息
{{$route.params.id}}
{{id}}
访问个人信息页面和列表页面,发现控制台输出:进入路由之前和进入路由之后,OK
npm install axios -s
npm install --save vue-axios
修改router/index.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
//路由
import router from "./router";
//ElementUI
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
//Axios
import axios from "axios";
import VueAxios from 'vue-axios'
Vue.use(ElementUI);
Vue.use(VueAxios)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)//ElementUI
})
在static文件夹下新建mock文件,在mock文件夹下新建data.json
{
"name": "沈金勇",
"url": "https://github.com/ShenJinyong",
"page": 1,
"isNonProfit": true,
"address": {
"street":"安源北大道",
"city": "江西萍乡",
"country": "中国"
},
"links": [
{
"name": "bilibili",
"url": "https://space.bilibili.com/472436120"
},
{
"name": "shenjinyong",
"url": "https://shenjinyong.github.io/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
个人信息
{{$route.params.id}}
{{id}}
访问个人页面,发现控制台有输出,OK