介绍
- Vue.js 中文文档地址:https://cn.vuejs.org/v2/guide/
Vue.js 是什么
- Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
Vue.js 优点
前端三要素
- HTML + CSS + JavaScript
CSS 预处理器
JavaScript 框架
UI 框架
JavaScript 构建工具
常用的 Vue UI 组件库
vue-element-admin
- 简述:vue-element-admin 是一个后台前端解决方案,它基于 vue 和 element-ui实现。它使用了最新的前端技术栈,内置了 i18 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。
- 地址:https://panjiachen.github.io/vue-element-admin-site/zh/
MVVM 模式
为什么使用 MVVM 模式
第一个 Vue 程序
IDEA 安装插件
使用 IDEA 工具开发,可安装 Vue.js 插件!
在 IDEA 中安装插件后,可快速构建 vue 文件:
PS:若安装插件后也没有出现快速构建 vue 文件的选项,可先手动创建 .vue 结尾的空文件,再次新建时,则可成功显示!
CDN 简述
-
智能 dns 让用户可以访问同线路最近的服务器
-
cdn 的缓存机制可以加快访问速度,也可以缓解源站服务器压力(因为根本不会去访问源站)
-
cdn 让大规模的用户请求架构变得简单
-
cdn 性价比高,同带宽需求下 cdn 服务比增加带宽划算
作用:尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输得更快、更稳定。
安装
可使用多种方式进行安装,如直接下载对应类库、使用 CDN 引入、使用 NPM 安装等...
此处使用 CDN:
- 压缩版:
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
- 完整版:
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>first vue</title>
</head>
<body>
<!--view层:模板-->
<div id="app">
<h2>{{message}}</h2>
</div>
<!--使用CDN方式导入Vue.js-->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
//Model: 数据
data: {
message: "hello,vue!"
}
});
</script>
</body>
</html>
相关指令
v-bind
-
作用:与指定属性进行绑定
-
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test</title> </head> <body> <!--view层:模板--> <div id="app"> <h2>{{message}}</h2> <span v-bind:title="message"> 鼠标悬浮几秒查看动态绑定的提示信息! </span> </div> <!--使用CDN方式导入Vue.js--> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", //Model: 数据 data: { message: "hello,vue!" } }); </script> </body> </html>
v-if、v-else-if、v-else
-
作用:判断
-
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test3</title> </head> <body> <div id="app"> <h1 v-if="ok">yes</h1> <h1 v-else>no</h1> <span v-if="type==='A'">A</span> <span v-else-if="type==='B'">B</span> <span v-else>D</span> </div> <!-- 导入vue.js --> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", data: { ok: true, type: 'A' } }); </script> </body> </html>
v-for
-
作用:循环
-
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test4</title> </head> <body> <div id="app"> <ul>编程语言 <li v-for="item in items"> {{item.message}} </li> </ul> <ol>编程语言(显示下标) <li v-for="(item, index) in items"> {{item.message}} --> {{index}} </li> </ol> </div> <!-- 导入vue.js --> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", data: { items: [ {message: "java"}, {message: "python"}, {message: "go"} ] } }); </script> </body> </html>
v-on
-
作用:事件监听
-
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test5</title> </head> <body> <div id="app"> <p>{{message}}</p> <button v-on:click="reverseMessage">反转消息</button> </div> <!-- 导入vue.js --> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", data: { message: "Hello Vue.js!"}, methods: { reverseMessage: function () { this.message = this.message.split('').reverse().join(''); } } }); </script> </body> </html>
v-model
-
作用:实现数据的双向绑定
-
说明:使用该指令可在
<input>、<textarea>、<select>
等元素上创建双向数据绑定,会根据控件类型自动选取正确方法来更新元素。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。 -
注意:
v-model
会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源,所以开发者应该通过 JavaScript 在组件的 data 选项中声明初始值! -
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test6</title> </head> <body> <div id="app"> 单行文本: <input type="text" v-model="message"> {{message}} <br><br> 文本域: <textarea v-model="texts"></textarea> {{texts}} <br><br> 单选按钮:<br> 性别: <input type="radio" name="sex" value="男" v-model="gender">男 <input type="radio" name="sex" value="女" v-model="gender">女 <br> <span>选中了【{{gender}}】</span> <br><br> 下拉框: <select v-model="selected"> <option value="" disabled>--请选择--</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>value:{{selected}}</span> </div> <!-- 导入vue.js --> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", data: { selected: '', message: "123", texts: '', gender: '' } }); </script> </body> </html>
组件化应用构建
组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树:
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test6</title>
</head>
<body>
<div id="app">
<ol>
<!--构建一个组件模板:创建一个 todo-item 组件的实例,使用自定义的Vue组件,遍历数据,将数据传递给绑定的指定属性-->
<todo-item v-for="item in todoList" v-bind:todo="item"></todo-item>
</ol>
</div>
<!-- 导入vue.js -->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script>
//注册组件:定义名为 todo-item 的新组件
Vue.component("todo-item", {
props: ['todo'],
template: '<li>{{todo.text}}</li>'
});
var vm = new Vue({
el: "#app",
data: {
todoList: [
{id: 0, text: "学英语"},
{id: 1, text: "学技术"},
{id: 2, text: "学做饭"}
]
}
});
</script>
</body>
</html>
Axios 异步通信
- Axios 中文文档:http://www.axios-js.com/zh-cn/docs/
使用 IDEA 写代码需要保证设置中 JavaScript 规范为 ECS 6+,如下:
什么是 Axios
- Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中,其主要作用就是实现 AJAX 异步通信。
为什么使用 Axios
- 由于
Vue.js
是一个视图层框架,并且其开发者(尤雨溪)严格遵守 SOC(关注度分离原则),所以Vue.js
并不包含 AJAX 的通信功能,为了解决通信问题,作者单独开发了一个名为vue-resource
的插件,不过在进入 2.0 版本以后,其停止了对该插件的维护并推荐了Axios
框架。建议少用 jQuery,因为它操作 DOM 太频繁。
Axios 特性
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
安装
可使用 npm、bower、cdn 等,此处选择使用 cdn:
-
使用 cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
第一个 Axios 应用程序
因为咱们开发的接口大多数都是采用的 JSON 格式,可以现在项目中模拟一段 JSON 数据,数据内容如下:创建一个名为 data.json 的模拟数据,放在项目的根目录下。
data.json
{
"name": "luis",
"url": "https://www.baidu.com",
"page": 1,
"isNonProfit": true,
"address": {
"street": "广建路",
"city": "江苏苏州",
"country": "中国"
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test8</title>
</head>
<body>
<div id="vue">
<div>{{info.name}}</div>
<div>{{info.address.city}}</div>
<div>{{info.address.street}}</div>
<a v-bind:href="info.url">点击跳转</a>
</div>
<!--引入JS文件(vue.js和axios.js)-->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#vue',
data(){
return{
//请求的返回参数格式,必须和JSON字符串一样(可以少写,但不能写错!)
info:{
name: null,
address: {
street: null,
city: null,
country: null
},
url: null
}
}
},
mounted(){ //钩子函数,链式编程
// axios.get('../data.json').then(response=>(console.log(response.data)));
axios.get('../data.json').then(response=>(this.info=response.data));
}
});
</script>
</body>
</html>
计算属性
计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性,其次,这个属性有计算的能力(计算是动词),这里的计算就是个函数;简单点说,他就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;也可以将其想象成缓存!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test9</title>
<!--引入Vue.js-->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="vue">
<!--注意:一个是方法,一个是属性!-->
<p>调用当前时间的方法:{{currentTime1()}}</p> <!--方法调用需要带括号-->
<p>当前时间的计算属性:{{currentTime2}}</p> <!--属性调用不能带括号-->
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue',
data: {message: 'Hello Vue.js!'},
// 注意:methods 和 computed 里的东西不能重名!
methods: { //在此可定义方法,调用方法需要带()
//currentTime1:这是一个方法!
currentTime1: function () {
return Date.now();
}
},
computed: { //在此可定义计算属性,调用属性不需要带()
//currentTime2:这是一个属性,不是方法!
currentTime2: function () {
this.message; //作用:通过改变该值,观察currentTime2属性值的变化
return Date.now();
}
}
});
</script>
</body>
</html>
测试结果:(F12 --》控制台)
vm.currentTime1()
1656988519767
vm.currentTime1()
1656988521888
vm.currentTime1()
1656988524916
结论:调用方法,每次都需要重新计算
vm.currentTime2()
Uncaught TypeError: vm.currentTime2 is not a function
<anonymous> debugger eval code:1
debugger eval code:1:4
结论:计算属性是属性,调用时不能带括号
vm.currentTime2
1656988393581
vm.currentTime2
1656988393581
vm.currentTime2
1656988393581
结论:计算属性将不经常变化的计算结果缓存了起来,只有发生变化的时候才会重新计算
vm.message = 'new data';
"new data"
vm.currentTime2
1656988775105
vm.currentTime2
1656988775105
结论:计算属性中的值被改变时,计算结果重新计算,并重新进行缓存
说明:如果计算属性中的值发生变化时,则缓存就会刷新,可在控制台使用vm.message = 'new data';
,改变下数据的值,再次测试并观察效果!
结论:调用方法时,每次都需要重新计算,既然有计算过程,则必定会产生系统开销,如果这个结果是不经常变化的,则可以考虑将这个结果缓存起来,采用计算属性就可以很方便的做到这一点!计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约系统开销。
插槽slot
内容分发:在Vue.js
中我们使用<slot>
元素作为承载分发内容的出口,作者称其为插槽,可应用在组合组件的场景中。
测试:如准备一个待办事项组件(to-do),该组件由待办标题(to-do-title)和待办事项(to-do-items)组成,但这三个组件又相互独立,该如何操作?
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽slot</title>
<!--引入Vue.js-->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="app10">
<to-do>
<to-do-title slot="to-do-title" v-bind:title="toDoTitle"></to-do-title>
<to-do-items slot="to-do-items" v-for="item in toDoList" v-bind:item="item"></to-do-items>
</to-do>
</div>
<script type="text/javascript">
Vue.component("to-do", {
// template: '<div>' +
// '<slot></slot>' +
// '<ul>' +
// '<slot></slot>' +
// '</ul>' +
// '</div>'
// 使用折行转义字符,使多行html模板更简洁
template: '<div>\
<slot name="to-do-title"></slot>\
<ul>\
<slot name="to-do-items"></slot>\
</ul>\
</div>'
});
Vue.component("to-do-title", {
props: ['title'],
template: '<p>{{title}}</p>'
});
Vue.component("to-do-items", {
props: ['item'],
template: '<li>{{item}}</li>'
});
var vm = new Vue({
el: "#app10",
data: {
toDoTitle: "待办事项",
toDoList: ['起床', '洗漱', '工作']
}
});
</script>
</body>
</html>
自定义事件内容分发
- 通过组件无法直接操作 Vue 对象的数据,可以通过组件调前端,通过前端操作 Vue 对象的数据,实现组件操作 Vue 对象数据。
- 核心:自定义事件
this.$emit('myEvent')
- 例如:在组件中添加一个删除按钮,要求点击删除,将指定列表数据删除
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽slot之自定义事件分发</title>
<!--引入Vue.js-->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="app10">
<to-do>
<to-do-title slot="to-do-title" v-bind:title="toDoTitle"></to-do-title>
<to-do-items slot="to-do-items"
v-for="(luis, index) in toDoList"
v-bind:item="luis"
v-bind:index="index"
v-on:rm="removeItem(index)"></to-do-items><!--绑定自定义事件-->
</to-do>
</div>
<script type="text/javascript">
Vue.component("to-do", {
// template: '<div>' +
// '<slot></slot>' +
// '<ul>' +
// '<slot></slot>' +
// '</ul>' +
// '</div>'
// 使用折行转义字符,使多行html模板更简洁
template: '<div>\
<slot name="to-do-title"></slot>\
<ul>\
<slot name="to-do-items"></slot>\
</ul>\
</div>'
});
Vue.component("to-do-title", {
props: ['title'],
template: '<p>{{title}}</p>'
});
Vue.component("to-do-items", {
props: ['item', 'index'],
// template: '<li>{{item}} <button @click="remove">删除</button></li>',
template: '<li>{{index}}---{{item}} <button v-on:click="remove">删除</button></li>',
methods: {
remove: function (index) {
//自定义事件分发
//不能直接通过组件控制Vue对象中的方法;可通过组件调前端,再通过前端来控制Vue对象
this.$emit("rm", index);
}
}
});
var vm = new Vue({
el: "#app10",
data: {
toDoTitle: "待办事项",
toDoList: ['起床', '洗漱', '工作']
},
methods: {
removeItem: function (index) {
//删除指定数组下标处指定个数的元素
this.toDoList.splice(index, 1);
}
}
});
</script>
</body>
</html>
Vue 入门小结
核心:数据驱动,组件化
优点:借鉴了 AngularJS 的模块化开发和 React 的虚拟 Dom;虚拟 Dom 就是把 Dom 的操作放到内存中执行。
常用属性:
v-if
v-else-if
v-else
v-for
v-on
绑定事件,简写@
v-model
数据双向绑定v-bind
给组件绑定参数,简写:
组件化:
- 组合组件 slot 插槽
- 组件内部绑定事件需要使用到
this.$emit("事件名", 参数);
- 计算属性的特色,缓存计算数据
遵循 SoC 关注度分离原则,Vue 是纯粹的视图框架,并不包含如 Ajax 之类的通信功能,为了解决通信问题,我们需要使用 Axios 框架做异步通信。
说明:
- 以上属于 Vue 的基础语法,包括示例都是为了演示语法的使用,实际开发不会采用此方式!
- Vue 的开发都是要基于 NodeJS,实际开发都是采用的 vue-cli 脚手架,vue-router 实现路由(跳转),vuex 实现状态管理(会话管理),Vue UI 界面,一般使用 ElementUI(饿了么出品),或使用 ICE(阿里巴巴出品)来快速搭建前端项目!
第一个 vue-cli 程序
什么是 vue-cli
- vue-cli 是官方提供的一个脚手架,用于快速生成一个 vue 的项目模板
- 预先定义好的目录结构以及基础代码,就好比咱们在创建 Maven 项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架,使我们的开发更加的便捷。
主要的功能:
- 统一的目录结构
- 本地调试
- 热部署
- 单元测试
- 集成打包上线
需要的环境
1、安装 Node.js
确认 Node.js 安装成功:
-
cmd 下 输入
node -v
,查看版本号打印信息 -
cmd 下 输入
npm -v
,查看版本号打印信息npm:软件包管理工具,类似 Linux 中 apt 软件安装。
2、安装 cnpm
安装 Node.js 淘宝镜像加速器(cnpm),解决 npm 速度慢的问题:
# -g 就是全局安装(推荐)
npm install cnpm -g
注意:建议优先使用 npm 下载,若 npm 下载缓慢,再考虑 使用 cnpm!(通过淘宝下载的偶尔可能出现问题)
查看安装情况:查看路径C:\Users\linwe\AppData\Roaming\npm\node_modules
3、安装 vue-cli
# 使用 cnpm 选择全局安装的方式安装 vue-cli
cnpm install vue-cli -g
# 测试是否安装成功
# 查看可以基于哪些模板创建 vue 程序,通常使用 webpack
vue list
查看安装情况:查看路径C:\Users\linwe\AppData\Roaming\npm\node_modules
第一个 vue-cli 程序创建
-
电脑上手动创建一个空目录,如
D:\1a-Projects\vue-projects
-
在该目录下,使用 cmd 命令,进入 DOS 窗口,初始化项目:
vue init webpack myvue
依据以下模板,进行项目的创建:(一路都选择 no 即可)
D:\1a-Projects\vue-projects>vue init webpack myvue # 项目名,默认,回车,即可 ? Project name myvue # 项目描述,默认,回车,即可 ? Project description A Vue.js project # 项目作者,默认,回车,即可 ? Author luis # 选择第一种 build 方式 ? Vue build standalone # 不安装 vue-router,选择 n,后续需要再手动添加 ? Install vue-router? No # 是否使用 ESLint 做代码检查,选择 n,后续需要再手动添加 ? Use ESLint to lint your code? No # 单元测试相关,选择 n,后续需要再手动添加 ? Set up unit tests No # 单元测试相关,选择 n,后续需要再手动添加 ? Setup e2e tests with Nightwatch? No # 是否创建完成后直接初始化,选择 n,我们手动执行,运行结果! ? Should we run `npm install` for you after the project has been created? (recommended) no vue-cli · Generated "myvue". # Project initialization finished! # ======================== To get started: cd myvue npm install (or if using yarn: yarn) npm run dev Documentation can be found at https://vuejs-templates.github.io/webpack
-
初始化并运行(可使用IDEA打开该项目,查看相关目录结构)
cd myvue # 进入myvue目录 npm install # 安装依赖环境 npm run dev # 运行项目(运行成功后,可在浏览器输入地址访问)
PS:可使用 Ctrl + C 终止项目
webpack 学习使用
webpack 简介
- webpack 主要作用是打包,其核心存在两个部分,入口和出口,可以把 webpack 想象成香肠加工厂,就是活猪进去,香肠出来的那种,但是如果每次加工都需要员工亲力亲为,那多麻烦,所以我们考虑到了自动化配置。webpack 存在功能类似的配置文件,让 webpack 通过配置,全自动的执行我们需要的编译操作。
- webpack 分成四个部分,其中最核心的就是入口和出口,当然在入口和出口配置的同时我们还需要一些加载器和插件,这就是我们所谓的 webpack 配置文件,这个配置文件我们习惯把其命名为 webpack.config.js,还有 webpackfile.js。
- webpack 是一种模块化的解决方案,其工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),webpack 将从这个文件开始找到你的项目的所有依赖文件,使用 loaders 处理它们,最后打包为一个(或多个)浏览器可识别的 JavaScript 文件。
- webpack 使用 ES6 模块语法
总结一下,webpack 共分为四个部分:入口、出口、加载器、插件。
什么是 webpack
- webpack 可以看做是模块打包机:分析你的项目结构,找到 JavaScript 模块以及其它的一些浏览器不能直接运行的拓展语言(如 Scss,TypeScript 等),并将其转换和打包为合适的格式供浏览器使用。
webpack 能干什么
- 根据入口文件的依赖,加载所有模块 js,然后合并成一个 js
- 标准且纯粹的模块化打包工具
- 依赖一个文件入口,打包所有依赖为当前浏览器可用的代码
安装
npm install webpack -g # 安装打包工具
npm install webpack-cli -g # 安装客户端
webpack -v # 查看安装的版本(是否安装成功)
相关配置参数(了解)
创建webpack.config.js
配置文件
- entry:入口文件,指定 webpack 用哪个文件作为项目的入口
- output:输出,指定 webpack 把处理完成的文件放置到指定路径
- module:模块,用于处理各种类型的文件
- plugins:插件,如:热更新、代码复用等
- resolve:设置路径指向
- watch:监听,用于设置文件改动后直接打包
使用 webpack
目录结构预览:
-
在
D:\1a-Projects\vue-projects
下创建名为webpack-study
的空目录(自定义),作为示例项目,使用 IDEA 打开 -
在项目目录下,创建 modules 目录,用于存放 JS 模块等资源文件
-
在 modules 目录下,创建模块文件,如 hello.js,编写 JS 模块相关代码,如:
hello.js
// 暴露一个方法 sayHi1 exports.sayHi1 = function () { document.write("<h1>luis1 learns ES6</h1>") }; // 暴露一个方法 sayHi2 exports.sayHi2 = function () { document.write("<h2>luis2 learns ES6</h2>") }; // 暴露一个方法 sayHi3 exports.sayHi3 = function () { document.write("<h3>luis3 learns ES6</h3>") };
-
在 modules 目录下,创建一个名为 main.js 的入口文件,用于打包时设置 entry 属性,如:
main.js
// require 导入一个模块,就可以调用这个模块中的方法了 var hello = require("./hello"); hello.sayHi1(); hello.sayHi2(); hello.sayHi3();
-
在项目目录下,创建 webpack.config.js 配置文件,用于配置相关参数
webpack.config.js
module.exports = { entry: './modules/main.js', output: { filename: "./js.bundle.js" } }
-
在项目目录下,地址栏输入 cmd 进入 DOS 窗口,输入
webpack
命令进行打包;打包完成后,在指定的输出路径下就可看到打包压缩后的 js,后面如需使用,则直接引入该 js 即可,不用再使用打包前的那些 js。
D:\1a-Projects\vue-projects\webpack-study>webpack
-
引入打包压缩后的 js:在项目目录下,创建 index.html,在其中直接引入打包压缩后的 js,浏览器打开即可
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--前端的模块化开发--> <script src="dist/js.bundle.js"></script> </body> </html>
总结:
- vue.js 是一个前端 js 框架,是一套构建用户界面的渐进式框架
- 前端的模块化开发:将 js 写好,使用 webpack 打包后,直接在前端引入即可
vue-router 路由
Tips:学习的时候,尽量打开官方文档。
认识 vue-router
目前前端流行的三大框架,都有自己的路由实现:
- Angular 的 ngRouter
- React 的 ReactRouter
- Vue 的 vue-router
vue-router 是 Vue.js 官方的路由插件,它和 vue.js 是深度集成的,适合用于构建单页面应用。可访问其官方网站对其进行学习:https://router.vuejs.org/zh/
vue-router 是基于路由和组件的
- 路由用户设定访问路径,将路径和组件映射起来。
- 在 vue-router 的单页面应用中,页面路径的改变就是组件的切换。
SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是:更新视图而不重新请求页面;vue-router 在实现单页面前端路由时,提供了两种方式:Hash 模式和 History 模式。
功能
vue-router 是 Vue.js 官方的路由管理器,它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌,包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
安装
基于第一个 vue-cli 程序进行测试学习,先查看 node_modules 中是否存在 vue-router(之前创建第一个 vue-cli 程序时可选择是否安装 rue-router)
vue-router 是一个插件包,所以我们还是需要用 npm/cnpm 进行安装!
在第一个 vue-cli 项目目录地址栏输入 cmd 命令,进入 DOS 窗口,输入以下命令,进行安装:
# 方式一:建议使用!(使用 cnpm 方式,安装低版本的 vue-router;经测试,高版本的使用有问题!)
cnpm install vue-router@3.1.3 --save-dev
# 方式二
npm install vue-router --save-dev
# 方式三:若以上方式安装都有问题,就使用此种 cnpm 安装
cnpm install vue-router --save-dev
安装完成后,在 node_modules 目录中就会出现 vue-router 的 js 库,需要使用的地方,导入即可使用!
使用 vue-router
PS:删除无用东西,如初始的 HelloWorld 组件相关
最终目录结构预览:(基于之前创建的第一个 vue-cli 程序)
-
components 目录下新建两个自定义的组件,用于路由组件跳转测试;
Main.vue
<template> <h2>首页</h2> </template> <script> export default { name: "Main" } </script> <style scoped> </style>
Content.vue
<template> <h1>内容页</h1> </template> <script> export default { name: "Content" } </script> <style scoped> </style>
-
在 src 目录下,新建 router 目录,专门存放路由;在 router 目录下,新建 index.js,用来导入、安装并配置路由;
index.js
import Vue from "vue"; import VueRouter from "vue-router"; import Content from "../components/Content"; import Main from "../components/Main"; //安装路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ routes: [ { //路由路径 相当于@RequestMapping path: '/content', name: 'content', //跳转的组件 component: Content }, { //路由路径 path: '/main', name: 'main', //跳转的组件 component: Main } ] });
-
在 main.js 中配置路由
main.js
import Vue from 'vue' import App from './App' //导入之前创建的路由配置目录 import router from './router' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', //配置路由 router, components: { App }, template: '<App/>' })
-
在 App.vue 中使用路由
App.vue
<template> <div id="app"> <h2>路由跳转测试</h2> <h2>Vue-Router</h2> <router-link to="/main">首页</router-link> <router-link to="/content">内容页</router-link> <!--用来展示路由跳转的页面--> <router-view></router-view> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
-
在项目目录,在其地址栏输入 cmd 命令,进入 dos 窗口(或直接在 IDEA 终端中)运行项目:
npm run dev
-
浏览器输入相关地址,进行访问测试
Tips:后续需要添加组件跳转,只需要以下三步即可!
- 在 components 目录下创建自定义组件
- 在 router 目录的 index.js 中配置路由
- 在 App.vue 中使用路由
Vue+ ElementUI
说明:结合之前所学 + 使用 ElementUI 组件库,进行实战训练
Element UI官网:https://element.eleme.cn/#/zh-CN/component/installation
准备
-
创建一个目录如
vue-projects
,用来存放后续创建的 vue 工程,如D:\1a-Projects\vue-projects
-
以管理员权限打开命令行,并切换到该
vue-projects
目录下操作:点击搜索框,输入 cmd,右击以管理员方式运行命令提示符;先切换到 d 盘
d:
,再使用 cd 命令切换到指定目录即可!
步骤
-
在
vue-projects
目录下创建名为 hi-vue 的工程:D:\1a-Projects\vue-projects>vue init webpack hi-vue
安装过程:项目名、描述、作者默认即可;编译环境选第一个;后续一路 no;npm install 选第三个,手动安装!
以上,项目初始化完成!
-
进入到 hi-vue 项目目录下,安装依赖和插件:
Tips:如果使用国外 npm 方式下载有问题,可尝试换国内淘宝 cnpm 方式下载!
Tips:如果安装过程中无 ERR(即错误),则可视为正常,继续后续操作即可!
Tips:如果最后启动失败,找不出原因,可重新新建工程、初始化项目、重新安装!
# 进入工程目录 cd hi-vue # 安装 vue-router # 优选方案(使用 cnpm 方式,安装低版本的 vue-router;经测试,高版本的使用有问题!) cnpm install vue-router@3.1.3 --save-dev # 备选方案 # cnpm install vue-router --save-dev # 安装 element-ui(官网推荐使用npm方式安装)(如果安装有问题,就换 cnpm 方式安装!) npm i element-ui -S # 安装依赖 npm install # 安装 SASS 加载器 cnpm 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 文件的 devDependencies 节点写入依赖,-D
为该命令的缩写
-
启动成功并在浏览器成功访问后;IDEA 打开项目,删除 assets 中图片,删除 components 中 HelloWorld.vue 组件,删除 App.vue 中无用的图片引入和 HelloWorld 组件相关内容;至此,基础工程有了!
-
在 src 目录下,新建 router 目录,存放路由相关;新建 views 目录,存放视图相关(组件);
目录说明:components(放功能性相关组件)、router(放路由相关组件)、views(放视图相关组件)
-
views 下新建
Main.vue
(首页)和Login.vue
(登陆页)作为视图展示页Main.vue
<template> <h1>首页</h1> </template> <script> export default { name: "Main" } </script> <style scoped> </style>
Login.vue
(此登陆模板直接从 ElementUI 官网表单组件库中复制即可)<template> <div> <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box"> <h3 class="login-title">欢迎登录</h3> <el-form-item label="账号" prop="username"> <el-input type="text" placeholder="请输入账号" v-model="form.username"/> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" placeholder="请输入密码" v-model="form.password"/> </el-form-item> <el-form-item> <el-button type="primary" v-on:click="onSubmit( 'loginForm' )">登录</el-button> </el-form-item> </el-form> <el-dialog title="温馨提示" :visible.sync="dialogVisible" width="30%" :before-close="handLeClose"> <span>请输入账号和密码</span> <span slot="footer" class="dialog- footer"> <el-button type="primary" @click="dialogVisible = false">确定</el-button> </span> </el-dialog> </div> </template> <script> export default { name: "Login", data() { return { form: { username: '', password: '' }, //表单验证,需要在el-form-item 元素中增加prop 属性 rules: { username: [ {required: true, message: " 账号不可为空", trigger: 'blur'} ], password: [ {required: true, message: " 密码不可为空 ", trigger: 'blur'} ] }, //对话框显示和隐藏 dialogVisible: false } }, methods: { onSubmit(formName) { //为表单绑定验证功能 this.$refs[formName].validate((valid) => { if (valid) { //使用vue-router路由到指定页面,该方式称之为编程式导航 this.$router.push("/main"); } else { this.dialogVisible = true; return false; } }); } } } </script> <style lang="scss" scoped> .login-box { border: 1px solid #DCDFE6; width: 350px; margin: 180px auto; padding: 35px 35px 15px 35px; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; box-shadow: 0 0 25px #909399; } .login-title { text-align: center; margin: 0 auto 40px auto; color: #303133; } </style>
-
router 目录下新建
index.js
,在其中配置路由index.js
import Vue from 'vue' import VueRouter from 'vue-router' import Main from "../views/Main"; import Login from "../views/Login"; //安装路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ routes: [ { path: '/main', component: Main }, { path: '/login', component: Login } ] });
-
main.js 中引入 ElementUI 和 router
import Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.config.productionTip = false Vue.use(router); Vue.use(ElementUI); new Vue({ el: '#app', router, render: h => h(App) // components: { App }, // template: '<App/>' })
-
App.vue
中展示使用App.vue
<template> <div id="app"> <router-link to="/main">首页</router-link> <router-link to="/login">登陆</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'App' } </script>
-
终端输入
npm run dev
运行,浏览器访问测试http://localhost:8080
http://localhost:8080/#/main
http://localhost:8080/#/login
可能遇到的问题
-
安装的
sass-loader
版本太高?解决:package.json 中将 sass-loader 版本改到指定低版本如 4.0.0;终端执行
npm install
,不行就cnpm install
,重新npm run dev
启动即可。 -
vue-router 版本太高,导致路由声明无效,找不到?
解决:安装低版本的 vue-router,执行
cnpm install vue-router@3.1.3 --save-dev
,重新npm run dev
启动即可。
小结
vue + element-ui 使用要点:
- main.js 中引入 Element
- views 或 components 中创建组件文件,在合适的位置复制进需使用的组件代码
- 在如
App.vue
中使用
路由嵌套
- 路由嵌套又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,如
/user/foo/profile
和/user/foo/posts
。
基于前面 hi-vue 继续举例学习:
-
在 views 目录下新建 user 目录,在 user 目录下创建
List.vue
和Profile.vue
作为用户列表和个人信息展示List.vue
<template> <h2>用户列表</h2> </template> <script> export default { name: "UserList" } </script> <style scoped> </style>
Profile.vue
<template> <h2>个人信息</h2> </template> <script> export default { name: "UserProfile" } </script> <style scoped> </style>
-
在 router 目录的 index.js 中导入新组件,在 Main 中嵌套子路由
index.js
import Vue from 'vue' import VueRouter from 'vue-router' import Main from "../views/Main"; import Login from "../views/Login"; import UserProfile from "../views/user/Profile"; import UserList from "../views/user/List"; import CheckPwd from "../views/CheckPwd"; import Button from "../views/Button"; //安装路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ routes: [ { path: '/main', component: Main, children: [ //路由嵌套(嵌套子路由) { path: '/user/profile', component: UserProfile }, { path: '/user/list', component: UserList } ] }, { path: '/login', component: Login } ] });
-
在 Main.vue 中添加侧边栏组件,实现路由嵌套(在 main 路由中嵌套子路由)的效果(侧边栏代码来自 ElementUI)
Main.vue
<template> <div> <el-container> <!--侧边栏--> <el-aside width="200px"> <el-menu :default-openeds="['1']"> <el-submenu index="1"> <template slot="title"><i class="el-icon-caret-right"></i>用户管理</template> <el-menu-item-group> <el-menu-item index="1-1"> <!--路由跳转--> <router-link to="/user/profile">个人信息</router-link> </el-menu-item> <el-menu-item index="1-2"> <!--路由跳转--> <router-link to="/user/list">用户列表</router-link> </el-menu-item> </el-menu-item-group> </el-submenu> <el-submenu index="2"> <template slot="title"><i class="el-icon-caret-right"></i>内容管理</template> <el-menu-item-group> <el-menu-item index="2-1">分类管理</el-menu-item> <el-menu-item index="2-2">内容列表</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu> </el-aside> <!--顶栏--> <el-container> <el-header style="text-align: right; font-size: 12px"> <el-dropdown> <i class="el-icon-setting" style="margin-right:15px"></i> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>个人信息</el-dropdown-item> <el-dropdown-item>退出登录</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </el-header> <!--主显示页--> <el-main> <!--这里展示路由跳转的组件样式--> <router-view/> </el-main> </el-container> </el-container> </div> </template> <script> export default { name: "Main" } </script> <style scoped> .el-header { background-color: #048bd1; color: #333; line-height: 60px; } .el-aside { color: #333; } </style>
-
终端输入
npm run dev
启动项目,并在浏览器访问http://localhost:8080/#/main
测试
参数传递以及重定向
参数传递
例子1:(整页代码示例)
-
在路由跳转时,不仅仅需要路径,还需要定义参数;
在 Main.vue 中,修改需传参的路由跳转方式:使用 v-bind,以对象形式进行传参,显示声明 name 和 params 属性
Main.vue
<template> <div> <el-container> <!--侧边栏--> <el-aside width="200px"> <el-menu :default-openeds="['1']"> <el-submenu index="1"> <template slot="title"><i class="el-icon-caret-right"></i>用户管理</template> <el-menu-item-group> <el-menu-item index="1-1"> <!--路由跳转--> <!--<router-link to="/user/profile">个人信息</router-link>--> <!--前端传参,需要对象,使用v-bind,name和路由配置中name一致 (v-bind:xx 可简写为 :xx)--> <router-link v-bind:to="{name: 'UserProfile', params: {id: 1}}">个人信息</router-link> </el-menu-item> <el-menu-item index="1-2"> <!--路由跳转--> <router-link to="/user/list">用户列表</router-link> </el-menu-item> <el-menu-item index="1-3"> <!--路由跳转(重定向)--> <router-link to="/goHome">回到首页</router-link> </el-menu-item> </el-menu-item-group> </el-submenu> <el-submenu index="2"> <template slot="title"><i class="el-icon-caret-right"></i>内容管理</template> <el-menu-item-group> <el-menu-item index="2-1">分类管理</el-menu-item> <el-menu-item index="2-2">内容列表</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu> </el-aside> <!--顶栏--> <el-container> <el-header style="text-align: right; font-size: 12px"> <el-dropdown> <i class="el-icon-setting" style="margin-right:15px"></i> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>个人信息</el-dropdown-item> <el-dropdown-item>退出登录</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </el-header> <!--主显示页--> <el-main> <!--这里展示路由跳转的组件样式--> <router-view/> </el-main> </el-container> </el-container> </div> </template> <script> export default { name: "Main" } </script> <style scoped> .el-header { background-color: #048bd1; color: #333; line-height: 60px; } .el-aside { color: #333; } </style>
-
在 router 的 index.js 中,修改需接参路由的路径格式 path,并定义 name 和 props 属性
index.js
import Vue from 'vue' import VueRouter from 'vue-router' import Main from "../views/Main"; import Login from "../views/Login"; import UserProfile from "../views/user/Profile"; import UserList from "../views/user/List"; import CheckPwd from "../views/CheckPwd"; import Button from "../views/Button"; //安装路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ routes: [ { path: '/main', component: Main, children: [ //路由嵌套(嵌套子路由) { // path: '/user/profile', path: '/user/profile/:id', //接参 name: 'UserProfile', //可定义name属性 component: UserProfile, props: true //通过声明props解耦,在任何地方都可使用该组件 }, { path: '/user/list', component: UserList } ] }, { path: '/login', component: Login }, { path: '/goHome', redirect: '/main' //实现重定向 } ] });
-
取参展示:在
Profile.vue
中获取传递的参数,并进行展示下面列举两种方式:{{$route.params.id}} 方式获取;{{id}} 方式是在
index.js
和Profile.vue
均声明 props 后可用!Profile.vue
<template> <!-- 所有元素,不能直接暴露在根节点下!!! --> <div> <h2>个人信息</h2> {{$route.params.id}} <br/><br/> {{id}} </div> </template> <script> export default { props: ['id'], //可通过组件取参,在上面就可以直接用了 name: "UserProfile" } </script> <style scoped> </style>
-
终端输入
npm run dev
启动项目,并在浏览器访问http://localhost:8080/#/main
测试
例子2:(局部代码示例)
-
前端页面跳转时传递用户填写的参数(如下的用户填写的姓名参数)
Login.vue
<script> export default { name: "Login", data() { return { form: { username: '', password: '' }, //表单验证,需要在el-form-item 元素中增加prop 属性 rules: { username: [ {required: true, message: " 账号不可为空", trigger: 'blur'} ], password: [ {required: true, message: " 密码不可为空 ", trigger: 'blur'} ] }, //对话框显示和隐藏 dialogVisible: false } }, methods: { onSubmit(formName) { //为表单绑定验证功能 this.$refs[formName].validate((valid) => { if (valid) { //使用vue-router路由到指定页面,该方式称之为编程式导航 //跳转并且传递参数(将用户填的姓名传递过去) this.$router.push("/main/" + this.form.username); } else { this.dialogVisible = true; return false; } }); } } } </script>
-
路由配置中,配置接参路径,以及 props 属性的声明
index.js
//配置路由 export default new VueRouter({ routes: [ { path: '/main/:name', //接参 props: true, //声明为true,方便前端页面获取参数 component: Main, children: [ //路由嵌套(嵌套子路由) { // path: '/user/profile', path: '/user/profile/:id', //接参 name: 'UserProfile', //可定义name属性 component: UserProfile, props: true //通过声明props解耦,在任何地方都可使用该组件 }, { path: '/user/list', component: UserList } ] }, { path: '/login', component: Login }, { path: '/goHome', redirect: '/main' //实现重定向 } ] });
-
页面展示,声明 props 属性,并接参展示数据
Main.vue
<script> export default { props: ['name'], //接参 name: "Main" } </script> ------------------- <!--顶栏--> <el-container> <el-header style="text-align: right; font-size: 12px"> <el-dropdown> <i class="el-icon-setting" style="margin-right:15px"></i> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>个人信息</el-dropdown-item> <el-dropdown-item>退出登录</el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!--显示用户名--> <span>{{name}}</span> </el-header> <!--主显示页--> <el-main> <!--这里展示路由跳转的组件样式--> <router-view/> </el-main> </el-container>
重定向
以下简述实现方式:
-
在路由配置中使用
redirect
进行路由重定向,如:index.js
{ path: '/goHome', redirect: '/main' //实现重定向 },
-
使用指定路径,以重定向方式进行跳转,如:
Main.vue
<el-menu-item index="1-3"> <!--路由跳转(重定向)--> <router-link to="/goHome">回到首页</router-link> </el-menu-item>
注意
所有元素,不能直接暴露在根节点下!!!
以Profile.vue
说明举例:
错误用法:直接暴露在了<template>
中,程序报错!
<template>
<!-- 所有元素,不能直接暴露在根节点下!!! -->
<button></button>
<a></a>
<p></p>
<div>
<h2>个人信息</h2>
{{$route.params.id}}
<br/><br/>
{{id}}
</div>
</template>
<script>
export default {
props: ['id'], //可通过组件取参,在上面就可以直接用了
name: "UserProfile"
}
</script>
<style scoped>
</style>
正确用法:元素建议套在<div>
中使用!
<template>
<!-- 所有元素,不能直接暴露在根节点下!!! -->
<div>
<button></button>
<a></a>
<p></p>
<h2>个人信息</h2>
{{$route.params.id}}
<br/><br/>
{{id}}
</div>
</template>
<script>
export default {
props: ['id'], //可通过组件取参,在上面就可以直接用了
name: "UserProfile"
}
</script>
<style scoped>
</style>
路由模式、404 和路由钩子
路由模式
默认情况下,如,我们在地址栏中输入地址http://localhost:8080
进行访问,回车后,该地址栏中地址会自动带上#
号,变为http://localhost:8080/#/
,这就是一种默认的路由模式!
路由模式有两种:hash 和 history
- hash:路径带
#
符号,如http://localhost:8080/#/login
- history:路径不带
#
符号,如http://localhost:8080/login
路由模式设置:(不设置的话默认是 hash 模式,带#
)
路由模式在路由配置中设置,一般通过在 router 目录的 index.js
中设置 mode 属性,如下:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from "../views/Main";
import Login from "../views/Login";
import UserProfile from "../views/user/Profile";
import UserList from "../views/user/List";
import CheckPwd from "../views/CheckPwd";
import Button from "../views/Button";
//安装路由
Vue.use(VueRouter);
//配置路由
export default new VueRouter({
//设置路由模式(默认hash,带#号;history,则不带#号)
mode: 'history',
routes: [
{
path: '/main/:name', //接参
props: true, //声明为true,方便前端页面获取参数
component: Main,
children: [ //路由嵌套(嵌套子路由)
{
// path: '/user/profile',
path: '/user/profile/:id', //接参
name: 'UserProfile', //可定义name属性
component: UserProfile,
props: true //通过声明props解耦,在任何地方都可使用该组件
},
{
path: '/user/list',
component: UserList
}
]
},
{
path: '/login',
component: Login
},
{
path: '/goHome',
redirect: '/main' //实现重定向
},
{
path: '/checkPwd',
component: CheckPwd
},
{
path: '/button',
component: Button
}
]
});
404
一般情况下,地址栏输入错误的访问地址,应该给出一个 404 提示页面,而不是什么都不显示!
步骤:
-
views 下创建一个名为
NotFound.vue
的视图组件,如下:NotFoung.vue
<template> <div> 404~ 你的页面走丢了... </div> </template> <script> export default { name: "NotFound" } </script> <style scoped> </style>
-
路由配置(router 目录下
index.js
)import Vue from 'vue' import VueRouter from 'vue-router' import Main from "../views/Main"; import Login from "../views/Login"; import UserProfile from "../views/user/Profile"; import UserList from "../views/user/List"; import CheckPwd from "../views/CheckPwd"; import Button from "../views/Button"; import NotFound from "../views/NotFound"; //安装路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ //设置路由模式(默认hash,带#号;history,则不带#号) mode: 'history', routes: [ { path: '/main/:name', //接参 props: true, //声明为true,方便前端页面获取参数 component: Main, children: [ //路由嵌套(嵌套子路由) { // path: '/user/profile', path: '/user/profile/:id', //接参 name: 'UserProfile', //可定义name属性 component: UserProfile, props: true //通过声明props解耦,在任何地方都可使用该组件 }, { path: '/user/list', component: UserList } ] }, { path: '/login', component: Login }, { path: '/goHome', redirect: '/main' //实现重定向 }, { path: '/checkPwd', component: CheckPwd }, { path: '/button', component: Button }, { path: '*', //匹配不到才走* component: NotFound } ] });
-
npm run dev
启动,浏览器输入规定内的不存在地址如http://localhost:8080/aa
,则会展示 404 视图组件内容
路由钩子与异步请求
钩子函数
-
beforeRouteEnter
:在进入路由前执行 -
beforeRouteLeave
:在离开路由前执行
使用示例:
如在Profile.vue
中
<template>
<!-- 所有元素,不能直接暴露在根节点下!!! -->
<div>
<h2>个人信息</h2>
{{$route.params.id}}
<br/><br/>
{{id}}
</div>
</template>
<script>
export default {
props: ['id'], //可通过组件取参,在上面就可以直接用了
name: "UserProfile",
//路由钩子函数,类似于拦截器,在一些特殊时机自动执行!
beforeRouteEnter: (to, from, next)=>{
console.log("---》进入路由之前执行的!");
next();
},
beforeRouteLeave: (to, from, next)=>{
console.log("离开路由之前执行的!《===");
next();
}
}
</script>
<style scoped>
</style>
参数说明:
- to:路由将要跳转的路径信息
- from:路由跳转前的路径信息
- next:路由的控制参数
next()
:跳入下一个页面next('/path')
:改变路由的跳转方向,使其跳到另一个路由next(false)
:返回原来的页面next((vm)=>{})
:仅在beforeRouteEnter
中可用,vm
是组件实例
钩子函数中使用异步请求
-
安装 Axios:
cnpm install --save axios vue-axios
-
在
main.js
中引用 Axiosimport Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import axios from 'axios' //导入axios import VueAxios from 'vue-axios' //导入axios Vue.config.productionTip = false Vue.use(router); Vue.use(ElementUI); Vue.use(VueAxios, axios) //使用axios new Vue({ el: '#app', router, render: h => h(App) // components: { App }, // template: '<App/>' })
-
在 static 目录下新建 mock 目录,在 mock 目录下创建
data.json
作为测试数据(static 目录下数据,地址栏可直接访问获取)data.json
{ "name": "luis", "url": "https://www.baidu.com", "page": 1, "isNonProfit": true, "address": { "street": "广建路", "city": "江苏苏州", "country": "中国" } }
-
在
Profile.vue
中,演示钩子函数与异步请求的使用Profile.vue
<template> <!-- 所有元素,不能直接暴露在根节点下!!! --> <div> <h2>个人信息</h2> {{$route.params.id}} <br/><br/> {{id}} </div> </template> <script> export default { props: ['id'], //可通过组件取参,在上面就可以直接用了 name: "UserProfile", //路由钩子函数,类似于拦截器,在一些特殊时机自动执行! beforeRouteEnter: (to, from, next)=>{ console.log("---》进入路由之前执行的!"); next((vm)=>{ vm.getData(); //利用组件实例调组件方法,获取数据 }); }, beforeRouteLeave: (to, from, next)=>{ console.log("离开路由之前执行的!《==="); next(); }, methods: { getData: function () { this.axios({ //使用Axios异步通信 method: 'get', url: 'http://localhost:8080/static/mock/data.json' //请求的地址 }).then(function (response) { console.log(response.data); //返回的数据 }); } } } </script> <style scoped> </style>
-
npm run dev
启动,浏览器 F12 打开调试,输入localhost:8080/main/luis
进入首页,点击个人信息链接,观察路由跳转以及控制台打印数据信息,查看是否可成功获取数据。