Vue入门笔记
1.前瞻
前端需要做的东西
逻辑
- 判断
- 循环
事件
- 浏览器事件BOM windows document
- 文档事件DOM
- jQuery
视图
- html
- css (最难)
通信
- ajax
其它需要掌握的
- PS(美化)
2. Vue
Soc:
HTML+CSS +JS:视图:给用户看,刷新后台给的数据
网络通信:axious
页面跳转:vue-router
状态管理:vuex
Vue-UI
- Ant-Desigm 阿里出品
- ElementUI、ICE 饿了么出品
- Bootstrap Twitter出品
- AmazeUI 妹子UI,开源H5跨屏前端框架
MVVM模式
MVVP即(Model-View-ViewModel)来自于经典的MVC(Model-View-Controller)
所以,Vue.js就是一个MVVM模式的实现者,核心是实现了DOM的监听和数据绑定
3.第一个Vue程序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 导入Vue.js-->
<script crossorigin="anonymous" integrity="sha512-TpgbLHXaTCAZ7ULhjopb1PveTz5Jx6KEQUtMfXhV0m0EArh+6O8ybZjjDN1Yug6oagN6iFm6EoMjuYSiFr0qXQ==" src="https://lib.baomitu.com/vue/2.6.14/vue.common.dev.min.js"></script>
</head>
<body>
<!--view层 模板-->
<div id="app">
{{message}}
</div>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
message: 'hello,vue!'
}
})
</script>
</body>
</html>
{{}}是用来获取model层的data数据
4.基本语法
Vue的七大常用属性
- el
- 用来指示vue编辑器从什么时候开始解析vue语法,可以说是一个占位符
- data
- 用来组织从view中抽象出来的属性,可以说将视图的数据抽象出来放在data中
- template
- 用来设置模板,会替换页面元素,包括占位符
- methods
- 放置页面中的逻辑,比如js的方法都会放在methods中
- render
- 创建真正的virtu Dom
- computed
- 用于计算
- watch
- watch.function(new,old){}
- 监听data中的数据变化
- 两个参数,一个返回新值,一个返回旧值
4.1 v-bind
v-band的作用是绑定一个元素,在这里的作用是将这个元素的title特性和Vue实例的message属性保持一致。像v-band这样带有v-开头的都被称为指令。它们都会在渲染DOM上应用特殊响应行为。
v-band 可以用 : 代替(简写)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 导入Vue.js-->
<script crossorigin="anonymous" integrity="sha512-TpgbLHXaTCAZ7ULhjopb1PveTz5Jx6KEQUtMfXhV0m0EArh+6O8ybZjjDN1Yug6oagN6iFm6EoMjuYSiFr0qXQ==" src="https://lib.baomitu.com/vue/2.6.14/vue.common.dev.min.js"></script>
</head>
<body>
<div id="app">
<!-- span的title属性会在鼠标停留的时候显示内容-->
<span v-bind:title="message">
鼠标放在上面悬停几秒看看
</span>
</div>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
message: 'hello,vue!'
}
})
</script>
</body>
</html>
4.2 判断-循环
1. v-if v-else判断
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 v-if="type==='A'">A</h1>
<h1 v-else-if="type==='B'">B</h1>
<h1 v-else>C</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
type : 'A'
}
})
</script>
</body>
</html>
2. v-for循环
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--注意空格,否则会报错!index-->
<li v-for="(item, index) in items">
{{item.message}}--{{index}}
</li>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
items : [
{message:'jaijia'},
{message: 'tingting'},
{message: 'forever'}
]
}
})
</script>
</body>
</html>
4.3 v-on事件
v-on监听事件
v-on:可以用@代替(简写)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- <button v-on:click="sayHi"></button>-->
<button @click="sayHi">click me</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
message:'jiajia'
},
methods:{
//方法注意定义在Vue的methonds对象中
//method和methods的区别,前者是一个方法,后者是一堆方法
sayHi:function () {
alert(this.message)
}
}
})
</script>
</body>
</html>
5. vue双向绑定
可以用 v-model 在表单<input>,<textarea>以及select元素上创建双向绑定。它会根据控件类型来字典选取正确的方法来更新元素。
注意:v-model会忽略所有表单元素的初始值,如value、checke、selected,而始终将 Vue的数据作为来源。所以要通过JavaScript在组件的data选项中声明初始值
5.1 单行文本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
输入的文本:<input type="text" v-model="message">{{message}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
message: ''
}
})
</script>
</body>
</html>
5.2 多行文本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
<textarea name="" id="" cols="30" rows="10" v-model="message">v-model="message"</textarea>
{{message}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
selected: ''
}
})
</script>
</body>
</html>
5.3 单选按钮
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
<!-- 选择性别:-->
<input type="radio" name="sex" v-model="message" value="man">男
<input type="radio" name="sex" v-model="message" value="woman">女
<p>{{message}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
message: ''
}
})
</script>
</body>
</html>
5.4 下拉框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
下拉框:
<select v-model="selected">
<option value="" disabled>--请选择--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<saan>{{selected}}</saan>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
selected: ''
}
})
</script>
</body>
</html>
注意:v-model表达式的初始值未能匹配任何选项,<select>元素将被渲染为“未选中”状态。在iOS系统中,这会使用户无法选择第一个选项。因为在这种情况下,iOS不会触发change事件。因此,更推荐像上面这样提供一个值为空的禁用选项。
5.5 组件
注册组件并实例化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<jiajia></jiajia>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
Vue.component('jiajia',{
template: '<li>hello</li>'
});
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
});
</script>
</body>
</html>
了解即可,没有意义
使用 props 属性传递参数
注意:props里的值不能大写,即不能使用驼峰命名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<jiajia v-for="item in items" v-bind:jia="item"></jiajia>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
Vue.component('jiajia',{
props: ['jia'],
template: '<li>{{jia}}</li>'
});
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data:{
items:['1','23','456']
}
});
</script>
</body>
</html>
!!以上代码着重理解
- v-for="item in items" 遍历Vue中命名为items的数组赋值给item,并创建同等数量的组件。
- v-bind:jia="item" 将遍历的item绑定到组件中props定义的名为jia的属性;
=号左边jia为props定义的属性名,右边的为item in items中遍历的item值
6. Axios异步通信
6.1 简介
Axios是一个开源的可以用在浏览器端和Node JS的异步通信框架, 她的主要作用就是实现AJAX异步通信,其功能特点如下
- 从浏览器中创建XMLHttpRequests
- 从node.js创建http请求
- 支持Promise API[JS中链式编程]
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF(跨站请求伪造)
由于Vue.js是一个视图层框架并且作者(尤雨溪) 严格准守SoC(关注度分离原则)所以Vue.js并不包含AJAX的通信功能, 为了解决通信问题, 作者单独开发了一个名为vue-resource的插件, 不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios框架。由于jQuery操作Dom太频繁,所以少用
6.2 Vue的生命周期

6.3 浅试一下
先准备一个json文件
{
"name":"狂神说java",
"url": "http://baidu.com",
"page": "1",
"isNonProfit":"true",
"address": {
"street": "含光门",
"city":"陕西西安",
"country": "中国"
},
"links": [
{
"name": "B站",
"url": "https://www.bilibili.com/"
},
{
"name": "4399",
"url": "https://www.4399.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
然后上代码!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="jia" v-cloak>
<div>{{info.name}}</div>
<div>{{info.address.city}}</div>
<a v-bind:href="info.url">jump!</a>
</div>
<!--导入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<!--导入axios-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
var Learnanxios = new Vue({
el: "#jia",
//这里的data()是方法,data是属性
data(){
return{
info:{
name:null,
address:{
street:null,
city:null,
country:null
}
}
}
},
mounted() {//钩子函数,链式编程,ES6新特性
axios.get('a.json').then(funtion(response){
return this.info = response.data
})
axios.get('a.json').then(response => (this.info = response.data))
}
})
</script>
</body>
</html>

注意:
- 在这里使用了v-bind将a:href的属性值与Vue实例中的数据进行绑定
- 使用axios框架的get方法请求AJAX并自动将数据封装进了Vue实例的数据对象中
- 我们在data中的数据结构必须和
Ajax响应回来的数据格式匹配
通过看评论区,发现了另外一种写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="jia" v-cloak>
<div>{{info.name}}</div>
<div>{{info.address.city}}</div>
<a v-bind:href="info.url">jump!</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
var Learnanxios = new Vue({
el: "#jia",
data: {//主要是这里的data的写法与上面不同,多对照区别。
info: {}
},
mounted() {//钩子函数,链式编程,ES6新特性
axios.get('a.json').then(response => (this.info = response.data))
}
})
</script>
</body>
</html>
7. 计算属性、内容分发、自定义事件
5.1 计算属性
定义
计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
<p>MethodsTime:{{ttiimmee1()}}</p>
<p>ComputeDtime:{{ttiimmee2}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data: {
message : 'hello,tingting'
},
methods:{
ttiimmee1: function () {
return Date.now();
//返回一个时间戳
}
},
computed: {
ttiimmee2: function () {
this.message;
return Date.now();
//返回一个时间戳
}
}
})
</script>
</body>
</html>


注意:methods和conputed不能重名,重名之后,只会调用methods里的方法。
好好理解methods和computed的区别:
- 首先,methods里定义的是一堆方法,方法的调用要加括号
(),而computed名为计算属性,所以是一个属性,调用属性不用加括号直接用属性名调用就好。 - 在调用方法的时候,每次调用都需要从新计算,这样便会产生大量的系统开销。但是如果这个值是不经常变化的,就没必要每次都进行重新计算,就可以将它缓存起来,计算属性就可以做到这一点,以节省系统开销。缓存只有在发生增删改查的变化时会失效然后重新进行计算。
5.2 内容分发(插槽)
1.概念
在Vue.js中我们使用<slot></slot>元素作为承载分发内容的出口,可以称其为插槽,可以应用在组合组件的场景中
2.浅试一下
- 需求:需要把下面的内容,让标题和内容通过插槽插入内容
<p>标题</p>
<ul>
<li>abcd</li>
<li>abcd</li>
<li>abcd</li>
</ul>
- 定义一个代办事情的组件
Vue.component('chacao',{
template:'<div>\
<div>代办事项</div>\
<ul>\
<li>笨蛋</li>\
</ul>\
</div>'
});
- 将上面的代码留出一个插槽,即slot
Vue.component('todo',{
template:'<div>\
<slot"></slot>\
<ul>\
<slot"></slot>\
</ul>\
</div>'
});
- 定义一个名为cc-title的待办标题组件 和 cc-item的待办内容组件
Vue.component('cc-title',{
props:['fake'],
template:'<div>{{fake}}</div>'
});
//这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!
Vue.component("cc-items",{
props:["item","index"],
template:"<li>{{index+1}},{{item}}</li>"
});
- slot通过name和组件绑定
Vue.component('chacao',{
template:'<div>\
<slot name="c-title"></slot>\
<ul>\
<slot name="c-items"></slot>\
</ul>\
</div>'
});
- 实例化Vue并初始化数据
var vm = new Vue({
el:"#vue",
data:{
todoItems:['test1','test2','test3']
}
});
- 将数据通过插槽插入预留出来的位置
<chacao>
<cc-title slot="c-title" :fake="titles"></cc-title>
<cc-item slot="c-items" v-for="item in itemss" :jia="item" ></cc-item>
</chacao>
- 完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<chacao>
<cc-title slot="c-title" :fake="title"></cc-title>
<cc-item slot="c-item" v-for="item in itemss" :jia="item" ></cc-item>
</chacao>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
Vue.component('chacao',{
template:
// '<div>' +
// '<slot name="c-title"></slot>' +
// '<ul>' +
// '<slot name="c-item"></slot>' +
// '</ul>' +
// '</div>'
//上下为两种不同的写法
'<div>\
<slot name="c-title"></slot>\
<ul>\
<slot name="c-item"></slot>\
</ul>\
</div>'
});
Vue.component('cc-title',{
props: ['fake'],
template: '<div>{{fake}}</div>'
});
Vue.component('cc-item',{
props:['jia'],
template:'<li>{{jia}}</li>'
});
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data:{
title:'笨蛋婷婷',
titles:'婷婷笨',
itemss:['婷','婷','笨蛋']
}
});
</script>
</body>
</html>
运行结果:

5.3 自定义事件
怎么理解自定义事件呢,引用网友的一句话。
子组件给父组件传参数用的是props:["参数一","参数二"]
父组件给子组件传方法用的是this.$emit("自定义事件","参数")
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<chacao>
<cc-title slot="c-title" :fake="titles"></cc-title>
<cc-item slot="c-item"
v-for="(item,index) in itemss"
:jia="item"
:wei="index"
@myremove="vueremove(index)" ></cc-item>
</chacao>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
Vue.component('chacao',{
template:
`<div>
<slot name="c-title"></slot>
<ul>
<slot name="c-item"></slot>
</ul>
</div>`
});
Vue.component('cc-title',{
props: ['fake'],
template: '<div>{{fake}}</div>'
});
Vue.component('cc-item',{
props:['jia','wei'],//参数传递
template:'<li>{{wei}}----{{jia}} <button @click="componentremove()">删除</button></li>',
methods:{
componentremove:function (nn) {
// 这里的myremove就是自定义事件
this.$emit('myremove',nn)
}
}
});
var vm = new Vue({
el: '#app', //el是element的简写
//Model层:数据
data:{
titles:'婷是笨蛋',
itemss:['婷','是','笨蛋']
},
methods: {
vueremove: function (abc) {
console.log('删除了'+this.itemss[abc]);
this.itemss.splice(abc,1);
}
}
});
</script>
</body>
</html>
8.第一个vue-cli项目
8.1 简介
vue-cli官方提供的一个脚手架,用于快速生成一个vue的项目模板预先定义好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个估计项目就是脚手架,我们的开发更加的快速
8.2 环境配置
1.node.js
下载地址: http://nodejs.cn/download/ 安装的时候一直下一步直到结束
确认是否安装成功:
- 在cmd中运行node -v命令,查看是否能够输出版本号
- 在cmd中运行npm -v命令,查看是否能够输出版本号

2.安装node.js淘宝镜像加速器(cnpm)
# -g 就是全局安装
npm install cnpm -g
# 或使用如下语句解决npm速度慢的问题,但是每次install都需要(妈发)
npm install --registry=https://registry.npm.taobao.org
3.安装vue-cli
//3.0之后的版本Vue CLI的包名称由vue-cli改成了@vue/cli
npm install -g @vue/cli
8.3 第一个vue-cli程序
- 找到一个项目路径(空文件夹)
- 创建一个基于webpack模板的vue应用程序()
//这是3.0之后版本的语法
vue create 项目名;//项目名不建议存在大写,中间用-隔开
- 初始化并运行
1.cd 项目名
2.npm run serve 运行项目
- 访问根据提示localhost:8080即可
也可以通过vue ui图形化界面来创建项目
vue ui

9. webpack的使用
9.1 安装webpack
npm install webpack -g
npm install webpack-cli -g
测试安装成功
webpack -v
webpack-cli -v

配置:
- entry:入口文件, 指定Web Pack用哪个文件作为项目的入口
- output:输出, 指定WebPack把处理完成的文件放置到指定路径
- module:模块, 用于处理各种类型的文件
- plugins:插件, 如:热更新、代码重用等
- resolve:设置路径指向
- watch:监听, 用于设置文件改动后直接打包
module.exports = {
entry:"",
output:{
path:"",
filename:""
},
module:{
loaders:[
{test:/\.js$/,;\loade:""}
]
},
plugins:{},
resolve:{},
watch:true
}
打包:直接运行webpack命令
9.2 使用webpack
- 创建项目
- 创建一个名为modules的目录,用于放置JS模块等资源文件
- 在modules下创建模块文件hello.js
//暴露一个方法 sayHi
exports.sayi=function () {
document.write('<h1>嘉嘉学ES6</h1>')
}
- 在modules下创建一个名为main.js的入口文件main.js,用于打包时设置entry属性
//require 导入一个模块,就可以调用这个模块中的方法了
var hello= require('./hello');
hello.sayi();
- 在项目目录下创建webpack.config.js配置文件,使用webpack命令打包
module.exports={
entry:'./modules/main.js',
output:{
filename:'./js/bundle.js'
},
mode:'development'
}
打包的注意事项:
- 新版本要在属性加上mode:'development'
- 注意设使用管理员模式运行
- 遇到别的错误复制去CSDN解决

- 在项目目录下创建HTML页面,如index.html,导入webpack打包后的JS文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--前端的模块化开发-->
<script src="dist/js/bundle.js"></script>
</body>
</html>
- 直接打开index.html
说明:
# 参数--watch 用于监听变化,如果要打包的东西有变化,就重新打包
webpack --watch
10. Vue vue-router路由
10.1 安装vue-router
//正常安装
npm install vue-router --save-dev
//如果运行启动报错,有可能是因为版本太高的问题,则用下面的版本
cnpm install vue-router@3.1.3 --save-dev
安装路由:
import Vue from 'vue'
//导入路由
import VueRouter from 'vue-router'
//安装路由
Vue.use(VueRouter);
10.2 测试路由
- 删除第一个vue-cli项目中的没用的东西
components目录下存放我们自己编写的组件- 定义几个自己的组件 Content.vue 、Main.vue、MyStyle.vue
Content.vue
<template>
<div>
<h1>内容页</h1>
</div>
</template>
<script>
export default {
name:"Content"
}
</script>
Main.vue
<template>
<div>
<h1>首页</h1>
</div>
</template>
<script>
export default {
//可以忽略下一句的语法检查(弹出错误)
// eslint-disable-next-line
name:"Main"
}
</script>
MyStyle.vue
<template>
<h1>我自己的页面</h1>
</template>
<script>
export default {
// eslint-disable-next-line
name: "MyStyle"
}
</script>
注意:组件名有命名规范,应该由多个单词的驼峰命名组成或者-连接,否则会报错,如果一定要使用单个单词,要在上一行加一句 // eslint-disable-next-line
- 安装路由,在src目录下,新建一个文件夹:
router,专门存放路由,配置路由index.js
//注意,这里的index只是一个命名规范,不是代表首页,是代表router的主配置,可以在main.js导入时自动扫描
import Vue from'vue'
//导入路由插件
import Router from 'vue-router'
//导入上面定义的组件
import Content from '../components/Content'
import Main from '../components/Main'
import MyStyle from "@/components/MyStyle";
//安装路由
Vue.use(Router) ;
//配置路由
export default new Router({
routes:[
{
//路由路径
path:'/content',
//路由名称
name:'content',
//跳转到组件
component:Content
},{
//路由路径
path:'/main',
//路由名称
name:'main',
//跳转到组件
component:Main
},
{
//路由路径
path:'/mystyle',
//路由名称
name:'mystyle',
//跳转到组件
component:MyStyle
}
]
});
- 在
main.js中配置路由
import Vue from 'vue'
import App from './App.vue'
import router from './router'//自动扫描里面的路由配置
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router,
}).$mount('#app')
- 在
App.vue中使用路由
<template>
<div id="app">
<!--
router-link:默认会被渲染成一个<a>标签,to属性为指定链接
router-view:用于渲染路由匹配到的组件
-->
<h1>嘉嘉学vue-router路由</h1>
<router-link to="/main">这是首页</router-link>
<!--这是空格符-->
<router-link to="/content">这是内容</router-link>
<router-link to="/mystyle">这是自己的页面</router-link>
<!--显示视图-->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
- 运行npm run serve,然后浏览器访问localhost:8080

11. 小试一下吧~
11.1 创建工程
- 创建一个名为hello-vue的工程
//建议用图形界面来创建
vue ui
- 安装依赖, vue-router、element-ui、sass-loader和node-sass四个插件
#进入工程目录
cd hello-vue
#安装vue-routern
npm install vue-router --save-dev
#安装element-ui
npm i element-ui -S
#安装依赖
npm install
# 安装SASS加载器
cnpm install sass-loader node-sass --save-dev
#启功测试
npm run serve
- 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为该命令的缩写
- 还可以用图形界面来完成

注意:这里依赖和插件的区别
-
插件在命令行中通过
vue add安装如:
vue add eslint这个命令将
@vue/eslint解析为完整的包名@vue/cli-plugin-eslint,然后从 npm 安装它,调用它的生成器。# 这个和之前的用法等价 vue add cli-plugin-eslint -
依赖在命令行中通过
npm install安装如:
npm install axios
每个 CLI 插件都会包含一个生成器 (用来创建文件的) 和一个运行时插件 (用来调整 webpack 核心配置和注入命令的) 。
提示:
vue add的设计意图是为了安装和调用 Vue CLI 插件。这不意味着替换掉普通的 npm 包。对于这些普通的 npm 包,你仍然需要选用包管理器。
- idea打开创建好的项目
11.2 创建登录界面
- 先删除没用的文件和没用的代码
- 然后像下面这样建立项目结构

- 在views目录下创建首页视图Main.vue组件
<template>
<div>首页</div>
</template>
<script>
export default {
name:"Main"
}
</script>
<style scoped>
</style>
- 在views目录下创建登录页面视图Login.vue组件
<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="dialogVisiable" 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:"密码不可为空",tigger:"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的vue-router路由配置文件
//导入vue
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
},
]
})
- 编写 APP.vue (这是入口界面)
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name:'App'
}
</script>
- 在
main.js中配置路由 (这是入口文件,加载组件,初始化等)
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
router,
render: h => h(App)//ElementUI
}).$mount('#app')
- 测试npm run serve
说明: 如果出现错误: 可能是因为sass-loader的版本过高导致的编译错误 ,可以去package.json文件中把sass-loder的版本降低,也有可能是node-sass版本过高,看报错内容修改相应的版本
11.3 路由嵌套
定义:嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成
- 创建用户信息组件,在 views/user 目录下创建一个名为 Profile.vue 的视图组件
<template>
<h1>个人信息</h1>
</template>
<script>
export default {
name: "UserProfile"
}
</script>
<style scoped>
</style>
- 在用户列表组件在 views/user 目录下创建一个名为 List.vue 的视图组件
<template>
<h1>用户列表</h1>
</template>
<script>
export default {
name: "UserList"
}
</script>
<style scoped>
</style>
- 修改首页视图,我们修改 Main.vue 视图组件,此处使用了 ElementUI 布局容器组件
<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-submenu index="3">
<template slot="title"><i class="el-icon-caret-right"></i>乱七八糟管理</template>
<el-menu-item-group>
<el-menu-item index="3-1">乱七</el-menu-item>
<el-menu-item index="3-2">八糟</el-menu-item>
<el-menu-item index="3-3">乱七八糟</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 {
// eslint-disable-next-line
name: "Main"
//第七行的语句可以忽略下一行的错误)
}
</script>
<style scoped lang="scss">
.el-header {
background-color: #5fbfff;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
- 添加了组件,去router修改配置文件
import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from "@/views/Main";
import Login from "@/views/Login";
import UserList from "@/views/uesr/List";
import UserProFile from "@/views/uesr/ProFile";
//安装路由
Vue.use(VueRouter)
//导出
const routes = [
{//登录页
path: '/login',
name: 'login',
component: Login
},
{//首页
path: '/main',
name: 'main',
component: Main,
//路由嵌套
children:[
{path:'/user/list',component:UserList},
{path:'/user/profile',component:UserProFile},
]
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
- 运行npm run serve测试

11.4 参数传递和重定向
11.4.1 参数传递
方法一:
- 修改路由配置, 主要是router下的index.js中的 path 属性中增加了 :id 这样的占位符
{
path: '/user/profile/:id',
name:'UserProfile',
component: UserProfile
}
- 视图层传递参数
<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>
说明: 此时我们在Main.vue中的route-link位置处 to 改为了 :to,是为了将这一属性当成对象使用,注意 router-link 中的 name 属性名称 一定要和 路由中的 name 属性名称 匹配,因为这样 Vue 才能找到对应的路由路径
- 接收参数
<template>
<!-- 所有的元素必须在根节点下-->
<div>
<h1>个人信息</h1>
{{$route.params.id}}
</div>
</template>
说明:所有的元素必须在根节点下面,否则会报错
- 测试

(方法一二效果完全相同,建议使用方法二)
方法二:
使用props 减少耦合
- 修改路由配置 , 主要在router下的index.js中的路由属性中增加了 props: true 属性
{
path: '/user/profile/:id',
name:'UserProfile',
component: UserProfile,
props: true //允许使用props传递参数
}
-
传递参数和之前一样
-
在Profile.vue接收参数为目标组件增加 props 属性
<template>
<div>
个人信息
{{ id }}
</div>
</template>
<script>
export default {
props: ['id'],
name: "UserProfile"
}
</script>
<style scoped>
</style>
-
测试

11.4.2 重定向
Vue 中的重定向是作用在路径不同但组件相同的情况
- 在router/index.js配置重定向路径
{
path: '/main',
name: 'Main',
component: Main
},
{
//重定向
path:'/gohome',
name:'gohome',
redirect:'/main'
}
- 视图增加
//以下格式是element-ui的
<el-menu-item index="1-3">
<!--插入的地方-->
<router-link to="/goHome">返回首页</router-link>
</el-menu-item>
11.4.3 小demo(显示当前登录用户)
- 首先在login页面修改methods方法
methods:{
onSubmit(formName){
//为表单绑定验证功能
this.$refs[formName].validate((valid)=>{
if(valid){
//使用vue-router路由到指定界面,该方式称为编程式导航
this.$router.push('/main/'+this.form.username);//先向router多传一个参数username
}else{
this.dialogVisible=true;
return false;
}
});
}
}
2.然后在index.js里接收参数
{//首页
props: true,
path: '/main/:name',//获取router发送过来的参数
name: 'main',
component: Main
}
3.然后在视图层获取显示接收的参数
eport default {
props:['name'],
// eslint-disable-next-line
name: "Main"
}
// 然后在需要显示的地方加上下列代码
11.5 路由模式、404和路由钩子
11.5.1 路由模式
路由模式有两种
- hash:路径带 # 符号,如 http://localhost/#/login
- history:路径不带 # 符号,如 http://localhost/login
可以在vue ui图形界面新建项目的时候就设定
也可以在路由的配置index.js中修改
export default new VueRouter({
mode:'history',
routes: []
)}
11.5.2 404页面
- 在views文件夹下创建一个NotFound.vue视图
<template>
<div>
<h1>404,不见啦!</h1>
</div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
- 修改路由配置index.js
//先导入组件
import NotFound from '../views/NotFound'
{
path: '*',
component: NotFound
}
- 测试

11.5.3 路由钩子
除了之前的钩子函数还存在两个钩子函数
beforeRouteEnter:在进入路由前执行
beforeRouteLeave:在离开路由前执行
- 在 Profile.vue 使用
<script>
export default {
name: "UserProfile",
beforeRouteEnter: (to, from, next) => {
console.log("准备进入个人信息页");
next();
},
beforeRouteLeave: (to, from, next) => {
console.log("准备离开个人信息页");
next();
}
}
</script>
参数说明:
to:路由将要跳转的路径信息
from:路径跳转前的路径信息
next:路由的控制参数
next() 跳入下一个页面
next(’/path’) 改变路由的跳转方向,使其跳到另一个路由
next(false) 返回原来的页面
next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例
-
在钩子函数中进行异步请求
- 安装Axios
npm install --save axios vue-axios- main.js引用 Axios
import axios from 'axios' import VueAxios from 'vue-axios' Vue.use(VueAxios, axios)- 准备数据
{ "name": "cv战士", "url": "https://blog.csdn.net/qq_45408390?spm=1001.2101.3001.5343", "page": 1, "isNonProfit": true, "address": { "street": "含光门", "city": "陕西西安", "country": "中国" }, "links": [ { "name": "bilibili", "url": "https://bilibili.com" }, { "name": "cv战士", "url": "https://blog.csdn.net/qq_45408390?spm=1001.2101.3001.5343" }, { "name": "百度", "url": "https://www.baidu.com/" } ] }说明: 只有我们的 public 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下
- 在 beforeRouteEnter 中进行异步请求
<script> export default { props:['id'], //这里的名字可以和文件名不一样 name: "UserProFile", beforeRouteEnter:(to, from, next) => { console.log("准备进入个人信息页") next(vm => { //进入钩子路由之前执行getData方法 vm.getDate() }); }, beforeRouteLeave:(to, from, next) => { console.log("准备离开个人信息页"), next(); }, //axios methods:{ getDate:function () { this.axios({ method:'get', url:'/a.json' }).then(response=> { console.log(response) }) } } }- 测试


浙公网安备 33010602011771号