Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
生命太短暂,不要去做一些根本没有人想要的东西。——Ash Maurya
项目结构经历的三个阶段:
后端MVC 我们就可以理解为单体架构,流程控制是由后端控制器来完成
前端MVC 前后端分离开发,后端只负责接收响应请求
MVVM 前端请求后端接口,后端返回数据,前端接收数据,并将接收的数据设置“VM”,HTML从vm取值
M model 数据模型 指的是后端接口返回的数据
V view 视图
VM ViewModel 视图模型 数据模型与视图之间的桥梁,后端返回的model转换前端所需的vm,视图层可以直接从vm中提取数据
MVC | MVVM |
---|---|
Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合.
离线引用:下载vue的js文件,添加到前端项目,在网页中通过script标签引用vue.js文件
CDN引用:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>title>
<script src="js/vue.js">script>
head>
<body>
<div id="container">
从vm中获取的数据为:{{str}}
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
str:"从前有座山"
}
});
script>
body>
html>
{{code}}
{{str}}
-------------------------
data:{
code:10,
str:"test"
}
{{stu.stuNum}}
{{stu.stuName}}
-----------------------------
data{
stu:{
stuNum:"100001",
stuName:"张三",
stuGender:"M",
stuAge:20
}
}
<label v-if="stu.stuGender=='M'">男label><br/>
-------------------------------------------------------
data:{
stu:{
stuNum:"100001",
stuName:"张三",
stuGender:"M",
stuAge:20
}
}
<table border="1" cellspacing="0" width="400">
<tr>
<th>序号th>
<th>学号th>
<th>姓名th>
<th>性别th>
<th>年龄th>
tr>
<tr v-for="s,index in stus">
<td>{{index+1}}td>
<td>{{s.stuNum}}td>
<td>{{s.stuName}}td>
<td>
<label v-if="s.stuGender == 'M'">男label>
<label v-if="s.stuGender == 'F'">女label>
td>
<td>{{s.stuAge}}td>
tr>
table>
---------------------------------------------------------------------
data:{
stus:[
{
stuNum:"100001",
stuName:"张大三",
stuGender:"M",
stuAge:23
},
{
stuNum:"100002",
stuName:"张中三",
stuGender:"M",
stuAge:22
},
{
stuNum:"100003",
stuName:"张小三",
stuGender:"F",
stuAge:20
}
]
}
v-bind:
可简写为 :
<input type="text" v-bind:value="str"/>
<img :src="stu.stuImg"/>
------------------------------------
data{
str:"从前有座山",
stu:{
stuImg:"img/01.jpg"
}
}
<input type="text" v-model:value="str"/>
<input type="text" v-model="str"/>
------------------------------------
data{
str:"从前有座山"
}
每个使用vue进行数据渲染的网页文档都需要创建一个Vue实例 —— ViewModel
vue实例生命周期——vue实例从创建到销毁的过程
为了便于开发者在vue实例生命周期的不同阶段进行特定的操作,vue在生命周期四个阶段的前后分别提供了一个函数,这个函数无需开发者调用,当vue实例到达生命周期的指定阶段会自动调用对应的函数。
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<script type="text/javascript" src="js/vue.js" >script>
head>
<body>
<div id="container">
<label v-once>{{str}}label><br/>
<label>{{str}}label><br/>
<input type="text" v-model="str"/>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{},
beforeCreate:function(){
//1.data初始化之前执行,不能操作data
},
created:function(){
//2.data初始化之后执行,模板加载之前,可以修改/获取data中的值
console.log(this.str);
//this.str = "山里有座庙";
},
beforeMount:function(){
//3.模板加载之后,数据初始渲染(挂载)之前,可以修改/获取data中的值
//this.str = "庙里有口井";
},
mounted:function(){
//4.数据初始渲染(挂载)之后,可以对data中的变量进行修改,但是不会影响v-once的渲染
//this.str = "井里有只蛙";
},
beforeUpdate:function(){
//5.数据渲染之后,当data中的数据发生变化触发重新渲染,渲染之前执行此函数
// data数据被修改之后,重新渲染到页面之前
console.log("-----"+this.str);
this.str = "从前有座山2";
},
updated:function(){
//6.data数据被修改之后,重新渲染到页面之后
//this.str = "从前有座山3";
},
beforeDestroy:function(){
//7.实例销毁之前
},
destroyed:function(){
//8.实例销毁之后
}
});
script>
body>
html>
data中的属性可以通过声明获得,也可以通过在computed通过计算获得
特性:计算属性所依赖的属性值发生变化会影响计算属性的值同时发生变化
示例
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<script type="text/javascript" src="js/vue.js" >script>
head>
<body>
<div id="container">
<input type="text" v-model="str1"/><br/>
<input type="text" v-model="str2"/><br/>
{{str3}}
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
str1:"千锋",
str2:"武汉"
},
computed:{
str3:function(){
return this.str1+this.str2;
}
}
});
script>
body>
html>
侦听器,就是data中属性的监听器,当data中的属性值发生变化就会触发侦听器函数的执行
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<script type="text/javascript" src="js/vue.js" >script>
head>
<body>
<div id="container">
<input type="text" v-model="str1"/><br/>
<input type="text" v-model="str2"/><br/>
{{str3}}
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
str1:"千锋",
str2:"武汉",
str3:"千锋武汉"
},
watch:{
str1:function(){
this.str3 = this.str1 +this.str2;
},
str2:function(){
this.str3 = this.str1 +this.str2;
}
}
});
script>
body>
html>
我们可以使用mustache语法将vue中data的数据绑定到HTML标签及标签的属性,如何将data中的值绑定到标签的class及style属性呢?
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
.mystyle1{
width: 200px;
height: 100px;
background: orange;
}
.mystyle3{
width: 200px;
height: 100px;
background: black;
}
.my-style2{
border-radius: 10px;
}
style>
<script type="text/javascript" src="js/vue.js" >script>
head>
<body>
<div id="container">
<div :class="{mystyle1:b1,'my-style2':b2}">div>
<div :class="[chooseStyle1,chooseStyle2]">div>
<div :class="[b3 ? 'mystyle3' : 'mystyle1']">div>
<div :class="[b3 ? chooseStyle3 : chooseStyle1]">div>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
b1:true,
b2:true,
b3:false,
chooseStyle1:"mystyle1",
chooseStyle2:"my-style2",
chooseStyle3:"mystyle3"
}
});
script>
body>
html>
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<script type="text/javascript" src="js/vue.js" >script>
head>
<body>
<div id="container">
<div v-bind:style="{color: colorname,fontSize: fontsize+'px' }">WH2010div>
<div v-bind:style="mystyle1">千锋Java-WH2010div>
<div v-bind:style="mystyle2">千锋Java-WH2010div>
<div v-bind:style="[mystyle2,mystyle3]">千锋Java-WH2010div>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
colorname:"green",
fontsize:30,
mystyle1:"color:orange;font-size:45px",
mystyle2:{
color:"blue",
fontSize:"40px"
},
mystyle3:{
textShadow:"orange 3px 3px 5px"
}
}
});
script>
body>
html>
在html标签可以添加v-if指令指定一个条件,如果条件成立则显示此HTML标签,如果不成立则不显示当前标签;
条件可以是一个表达式也可以是一个具体的bool类型值
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<script type="text/javascript" src="js/vue.js" >script>
head>
<body>
<div id="container">
<h3 v-if="b">从前有座山h3>
<h3 v-if="code == 1">从前有座山h3>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
code:2,
b:false
}
});
script>
body>
html>
<div id="container">
<h3 v-if="code == 1">从前有座山h3>
<h3 v-else>山里有座庙h3>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
code:1
}
});
script>
<div id="container">
<h3 v-if="code >= 90">优秀h3>
<h3 v-else-if="code >= 80">良好h3>
<h3 v-else-if="code >= 70">中等h3>
<h3 v-else-if="code >= 60">及格h3>
<h3 v-else>不想理你h3>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
code:85
}
});
script>
从功能上将v-show和v-if作用是相同的,渲染过程有区别
v-if
是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show
较好;如果在运行时条件很少改变,则使用 v-if
较好。
将集合数据以表格、列表的形式显示
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<link rel="stylesheet" href="css/bootstrap.css" />
<script type="text/javascript" src="js/jquery-3.4.1.min.js" >script>
<script type="text/javascript" src="js/bootstrap.js" >script>
<script type="text/javascript" src="js/vue.js" >script>
head>
<body>
<div id="container">
<ul>
<li v-for="c in categories">
<a :href="'query?cid='+c.cid">{{c.cname}}a>
li>
ul>
<table class="table table-bordered">
<tr>
<th>学号th>
<th>照片th>
<th>姓名th>
<th>性别th>
<th>年龄th>
<th>操作th>
tr>
<template v-for="s,index in stus">
<tr :id="'tr'+s.stuNum">
<td>{{s.stuNum}}td>
<td>
<img height="30" :src="s.stuImg"/>
td>
<td>{{s.stuName}}td>
<td>
<img v-if="s.stuGender=='M'" src="img/m.bmp">
<img v-else src="img/f.bmp">
td>
<td>{{s.stuAge}}td>
<td>
<a class="btn btn-danger btn-xs" :href="'stu/delete?cid='+s.stuNum">删除a>
<a class="btn btn-success btn-xs" :href="'stu/update?cid='+s.stuNum">修改a>
td>
tr>
template>
table>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
categories:[
{
cid:1,
cname:"华为"
},
{
cid:2,
cname:"小米"
},
{
cid:3,
cname:"OPPO"
},
{
cid:4,
cname:"VIVO"
}
],
stus:[
{
stuNum:"10010",
stuImg:"img/01.jpg",
stuName:"Tom",
stuGender:"M",
stuAge:20
},
{
stuNum:"10011",
stuImg:"img/02.jpg",
stuName:"LiLei",
stuGender:"M",
stuAge:20
},
{
stuNum:"10012",
stuImg:"img/03.jpg",
stuName:"Lucy",
stuGender:"F",
stuAge:20
},
{
stuNum:"10013",
stuImg:"img/04.jpg",
stuName:"Polly",
stuGender:"F",
stuAge:20
}
]
}
});
script>
body>
html>
在使用vue进行数据渲染时,如果使用原生js事件绑定(例如onclick),如果需要获取vue实例中的数据并传参则需要通过拼接来完成
vue提供了v-on指令用于绑定各种事件(v-on:click),简化了从vue取值的过程,但是触发的方法需要定义在vue实例的 methods中
<button type="button" v-on:click="doDelete(s.stuNum,s.stuName)">删除button> <script type="text/javascript"> var vm = new Vue({ el:"#container", data:{}, methods:{ doDelete:function(snum,sname){ console.log("----delete:"+snum+" "+sname) } } }); script>
v-on:clicl
可以缩写为@click
<button type="button" class="btn btn-danger btn-xs" v-on:click="doDelete(s.stuNum,s.stuName)">删除button>
<script>
var vm = new Vue({
el:"#container",
data:{};
methods:{
doDelete:function(snum,sname){
console.log("----delete:"+snum+" "+sname)
}
}
});
script>
<button type="button" class="btn btn-success btn-xs" @click="doUpdate" :data-snum="s.stuNum"
:data-sname="s.stuName" :data-simg="s.stuImg">修改button>
<script>
var vm = new Vue({
el:"#container",
data:{};
methods:{
doUpdate:function(event){
//如果v-on绑定的js函数没有参数,调用的时候可以省略(),同时可以给js函数一个event参数(事件对象)
// 1. event 表示触发当前函数的事件
// 2. event.srcElement 表示发生事件的元素---修改按钮
// 3. event.srcElement.dataset 表示按钮上绑定的数据集(data-开头的属性)
console.log("-----update")
var stu = event.srcElement.dataset;
}
}
});
script>
$event
<button type="button" class="btn btn-danger btn-xs" v-on:click="doDelete(s.stuNum,s.stuName,$event)":data-simg="s.stuImg">删除button>
<script>
var vm = new Vue({
el:"#container",
data:{};
methods:{
doDelete:function(snum,sname,event){
console.log("----delete:"+snum+" "+sname)
console.log(event.srcElement.dataset);
}
}
});
script>
当使用v-on进行事件绑定的时候,可以添加特定后缀,设置事件触发的特性
<button type="submit" @click.prevent="事件函数">测试button>
.prevent 消除元素的默认事件
<div id="container">
<form action="https://www.baidu.com">
<button type="submit" class="btn btn-success btn-xs" @click.prevent="test">测试button>
form>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
},
methods:{
test:function(){
console.log("---test");
}
}
});
script>
.stop 阻止事件冒泡(阻止子标签向上冒泡)
.self 设置只能自己触发事件(子标签不能触发)
<div id="container">
<div style="width: 200px; height: 200px; background: red;" @click.self="method1">
<div style="width: 150px; height: 150px; background: green;" @click="method2">
<button type="button" @click.stop="method3">测试button>
div>
div>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
},
methods:{
method1:function(){
alert("1");
},
method2:function(){
alert("2");
},
method3:function(){
alert("3");
}
}
});
script>
.once 限定事件只触发一次
按键修饰符就是针对键盘事件的修饰符,限定哪个按键会触发事件
<input type="text" @keyup.enter="method4"/>
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
除了以上vue提供按钮的别名之外,我们还可以根据键盘为按键自定义别名
键盘码
示例:
<div id="container">
<input type="text" @keyup.aaa="method4"/>
div>
<script type="text/javascript">
//1.为按键J定于别名为 aaa
Vue.config.keyCodes.aaa =74;
var vm = new Vue({
el:"#container",
data:{},
methods:{
method4:function(){
alert("4");
}
}
});
script>
组合键
示例 ctrl+j触发事件
<div id="container">
<input type="text" @keyup.ctrl.j="method4"/>
div>
<script type="text/javascript">
Vue.config.keyCodes.j =74;
var vm = new Vue({
el:"#container",
data:{},
methods:{
method4:function(){
alert("4");
}
}
});
script>
.ctrl
.alt
.shift
.meta
windows键表单输入绑定,即双向绑定:就是能够将vue实例的data数据渲染到表单输入视图(input\textarea\select),也能够将输入视图的数据同步更新到vue实例的data中
A 3
B 4
C 5
D 6
篮球
足球
羽毛球
乒乓球
接口名称 | |
---|---|
功能描述 | 根据关键字搜索音乐信息 |
请求URL | http://47.96.11.185:9999/music/search |
请求方式 | GET | POST |
请求参数 | s string [必须] 搜索关键字 limit int [可选] 返回的搜索结果的条数,默认为10 type int [可选] 搜索类型(1单曲 10歌单),默认为1 offset int [可选] 搜索结果的偏移 |
返回结果 |
|
java -jar music-1.0.0.jar
请大家根据以上接口实现搜索和列表显示功能
在music.html中定义音频播放器(定义在vue的容器之外)
<audio controls style="width:100%" src="" id="player">audio>
给播放按钮绑定点击事件触发的函数doPlay
<button type="button" class="btn btn-success btn-xs" @click="doPlay" :data-mid="song.id">播放button>
在doPlay中执行播放
<script type="text/javascript">
var player = document.getElementById("player");
var vm = new Vue({
el:"#container",
data:{
keyword:"张韶涵",
songs:[],
currentid:0
},
methods:{
doSearch:function(){
console.log(vm.keyword);
$.get("http://localhost:9999/music/search",{s:vm.keyword,limit:15,offset:0},function(res){
console.log(res);
if(res.code==200){
//获取此关键词搜索的总记录数
var count = res.result.songCount;
//获取音乐集合
var arr = res.result.songs;
vm.songs = arr;
}else{
vm.songs = data;
}
},"json");
},
doPlay:function(event){
vm.currentid = event.srcElement.dataset.mid;
//网易云音乐播放地址: http://music.163.com/song/media/outer/url?id=songId
player.src = "http://music.163.com/song/media/outer/url?id="+vm.currentid;
player.play();
}
}
});
</script>
组件,就是将通用的HTML模块进行封装——可复用
将通用的HTML模块封装注册到vue中
Vue.component("header-bar",{
});
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<div id="container">
<header-bar>header-bar>
div>
<script type="text/javascript" src="js/vue.js" >script>
<script type="text/javascript" src="js/my-components.js" >script>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
});
script>
body>
html>
data
定义组件的模板渲染的数据
template
组件的HTML模块(HTML标签\css样式)
methods
定义组件中的标签事件绑定的JS函数
Vue.component("header-bar",{
data:function(){
//组件中的data是通过函数返回的对象
return {
title:"Java2010电商平台"
};
},
template:`
`,
methods:{
test:function(){
alert("组件中定义的函数");
}
}
});
vue组件封装的目录结构 |
---|
DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>title>
<link rel="stylesheet" href="css/my-components.css" />
head>
<body>
<div id="container">
<header-bar>header-bar>
div>
<script type="text/javascript" src="js/vue.js" >script>
<script type="text/javascript" src="js/my-components.js" >script>
<script type="text/javascript">
var vm = new Vue({
el:"#container"
});
script>
body>
html>
vue实例本身就是一个组件(模板就是el指定容器 ,data就是组件数据,methods就是组件的事件函数)
在vue实例指定的el容器中引用的组件称为子组件 ,当前vue实例就是父组件
vue实例引用组件的时候,传递数据到引用的组件中
示意图 |
---|
通过子组件的按钮“调用”父组件的函数,通过函数传值
调用流程示意图 |
---|
当我们自定义vue组件时,允许组件中的部分内容在调用组件时进行定义——插槽
在自定义组件时通过slot
标签在组件的模版中定义插槽
Vue.component("header-bar",{
data:function(){
//组件中的data是通过函数返回的对象
return {
str2:"子组件中的数据"
};
},
template:`
`,
props:["title"],
methods:{
childMethod:function(){
this.$emit("my-event",this.str2);
}
}
});
在父组件中调用此组件时,指定插槽填充的模版
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="css/my-components.css" />
<script type="text/javascript" src="js/jquery-3.4.1.min.js" >script>
<script type="text/javascript" src="js/bootstrap.js" >script>
<script type="text/javascript" src="js/vue.js" >script>
head>
<body>
<div id="container">
<header-bar :title="sss">
<input/><button>搜索button>
header-bar>
div>
<script type="text/javascript" src="js/my-components.js" >script>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
sss:"自定义标题"
}
});
script>
body>
html>
当组件中的插槽数量>1时,需要给组件中的slot标签添加name属性指定插槽的名字
定义组件:
Vue.component("page-frame",{
template:`
`,
props:["title","cr"]
});
引用组件 template
<div id="container">
<page-frame title="标题" cr="千锋武汉">
<template slot="s1">
<input type="text" placeholder="歌曲名、歌手" />
<button type="button" @click="doSearch">搜索button>
template>
<template slot="s2">
<table class="table table-bordered table-condensed">
<tr>
<th>序号th>
<th>歌曲IDth>
<th>歌曲名th>
<th>歌手th>
<th>专辑th>
<th>时长th>
<th>操作th>
tr>
table>
template>
page-frame>
div>
slot
标签Vue.component("page-frame",{
template:`
`,
props:["title","cr"],
data:function(){
return {
songs:[
{},{}
]
};
}
});
slot-scopt
属性获取插槽绑定的值<page-frame title="标题" cr="千锋武汉">
<template slot="s1">
<input type="text" placeholder="歌曲名、歌手" />
<button type="button" @click="doSearch">搜索button>
template>
<template slot="s2" slot-scope="res">
<table class="table table-bordered table-condensed">
<tr>
<th>序号th>
<th>歌曲IDth>
<th>歌曲名th>
<th>歌手th>
<th>专辑th>
<th>时长th>
<th>操作th>
tr>
<tr v-for="song,index in res.musics">
<td>{{index+1}}td>
<td>{{song.id}}td>
<td>
{{song.name}}
td>
<td>
<span v-for="artist in song.artists">
{{artist.name}}
span>
td>
<td>{{song.album.name}}td>
<td width="8%">
{{ Math.floor( Math.round(song.duration/1000)/60) < 10 ? '0'+Math.floor( Math.round(song.duration/1000)/60) : Math.floor( Math.round(song.duration/1000)/60) }}
:
{{ Math.round(song.duration/1000)%60 <10 ? '0'+( Math.round(song.duration/1000)%60 ) : Math.round(song.duration/1000)%60 }}
td>
<td width="10%">
<button type="button" class="btn btn-primary btn-xs">播放button>
td>
tr>
table>
template>
page-frame>
vue可以实现数据的渲染,但是如何获取数据呢?
vue本身不具备通信能力,通常结合axios—一个专注于异步通信的js框架来使用
- axios 数据通信
- vue 数据渲染
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<script type="text/javascript" src="js/vue.js" >script>
<script type="text/javascript" src="js/axios.min.js" >script>
head>
<body>
<div id="container">
<button type="button" @click="test1">测试1button>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
methods:{
test1:function(){
//发送异步请求
// axios.get(url).then(fn);
// axios.get(url,{}).then(fn)
axios.get("http://localhost:9999/music/detail",{
params:{
id:"25640392"
}
})
.then(function(res){
console.log(res);
});
}
}
});
script>
body>
html>
axios提供了多种异步请求方法,实现对RESTful风格的支持
axios.get(url).then(fn);
axios.get(url,{}).then(fn)
//使用axios的get请求传递参数,需要将参数设置在params下
axios.get("http://localhost:9999/music/detail",{
params:{
id:"25640392"
}
})
.then(function(res){
console.log(res);
});
axios.post(url,{}).then(fn)
axios.post("http://localhost:9999/music/search",{s:"阿刁"})
.then(function(res){
console.log(res);
});
自定义请求:自定义请求方式、请求参数、请求头、请求体(post)
axios({
url:"http://localhost:9999/music/search",
method:"post",
params:{
//设置请求行传值
s:"成都",
limit:15
},
headers:{
//设置请求头
},
data:{
//设置请求体(post/put)
}
}).then(function(res){
console.log(res)
});
<div id="container">
<button type="button" @click="test1">测试1button>
div>
<script type="text/javascript">
var vm = new Vue({
el:"#container",
methods:{
test1:function(){
//发送异步请求
axios.all([listMusics(),getMusicDetail()]).then(axios.spread(function (r1, r2) {
// 两个请求现在都执行完成
console.log(r1);
console.log(r2);
}));
}
}
});
function listMusics() {
return axios.get('http://localhost:9999/music/search?s=成都');
}
function getMusicDetail() {
return axios.get('http://localhost:9999/music/detail?id=25640392');
}
script>
res并不是接口返回的数据,而是表示一个响应对象;res.data才表示接口响应的数据
<script type="text/javascript">
var vm = new Vue({
el:"#container",
data:{
song:{
}
},
methods:{
test1:function(){
//发送异步请求
axios.get("http://localhost:9999/music/detail?id=25640392").then( (res)=>{
// res并不是接口返回的数据,而是表示一个响应对象;res.data才表示接口响应的数据
if(res.data.code == 200){
this.song = res.data.songs[0];
}
});
}
}
});
script>
router是由vue官方提供的用于实现组件跳转的插件
<script type="text/javascript" src="js/vue.js" >script>
<script type="text/javascript" src="js/vue-router.js">script>
<script src="https://unpkg.com/vue/dist/vue.js">script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js">script>
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
body{padding: 0px;margin: 0px;}
ul{list-style: none;}
ul li{display: inline; float: left; margin-left: 15px; margin-bottom: 15px;}
ul li a{text-decoration: none; color: white; font-size: 18px; font-weight: bold;}
ul li a:hover{color: yellow;}
style>
<script type="text/javascript" src="js/vue.js" >script>
<script type="text/javascript" src="js/vue-router.js">script>
head>
<body>
<div id="container">
<div style="width: 100%; height: 70px; background: #00BFFF;">
<table>
<tr>
<td><img src="img/logo.png" height="70" style="margin-left:100px;"/>td>
<td>
<ul>
<li><router-link to="/a">首页router-link>li>
<li><router-link to="/b">Javarouter-link>li>
<li><router-link to="/c">HTML5router-link>li>
<li><router-link to="/d">Pythonrouter-link>li>
ul>
td>
tr>
table>
div>
<div style="width: 100%; height: 680px; background: lemonchiffon;">
<router-view>router-view>
div>
div>
<script type="text/javascript">
// vue的路由旨在为单页面应用开发提供便捷
//1.定义链接跳转的模板(组件)
const t1 = {template:`index
`};
const t2 = {template:`Java
`};
const t3 = {template:`HTML5
`};
const t4 = {template:`PYTHON
`};
const myrouter = new VueRouter({
routes:[
{path:"/a",component:t1},
{path:"/b",component:t2},
{path:"/c",component:t3},
{path:"/d",component:t4}
]
});
var vm = new Vue({
el:"#container",
router:myrouter
});
script>
body>
html>
*
可以匹配任意路径
例如:
/user-*
匹配所有以user-
开头的任意路径/*
匹配所有路径const myrouter = new VueRouter({
routes:[
{path:"/user-*",component:...},
{path:"/*",component:...}
]
});
注意
如果使用通配符定义路径,需要注意路由声明的顺序
/a/:id
可以匹配 /a/
开头的路径<div id="container">
<li><router-link to="/a/101">首页router-link>li>
<router-view>router-view>
div>
<script type="text/javascript">
const t1 = {template:`index:{{$route.params.id}}
`};
const myrouter = new VueRouter({
routes:[
{path:"/a/:id",component:t1}
]
});
var vm = new Vue({
el:"#container",
router:myrouter
});
script>
如果一个路径匹配了多个路由,则按照路由的配置顺序:路由定义的越早优先级就越高。
在一级路由的组件中显示二级路由
<div id="container">
<router-link to="/a">首页router-link>
<router-link to="/a/c1">首页-c1router-link>
<router-link to="/a/c2">首页-c2router-link>
<router-view>router-view>
div>
<script type="text/javascript">
const t1 = {
template:"index
"
};
const t2 = {template:`t2`};
const t3 = {template:`t3`};
const myrouter = new VueRouter({
routes:[
{
path:"/a",
component:t1,
children:[
{
path:"c1",
component:t2
},
{
path:"c2",
component:t3
}
]
}
]
});
var vm = new Vue({
el:"#container",
router:myrouter
});
script>
<div id="container">
<button type="button" @click="test">按钮button>
<router-view>router-view>
div>
<script type="text/javascript">
const t1 = {
template:"index"
};
const myrouter = new VueRouter({
routes:[
{
path:"/a",
component:t1
}
]
});
var vm = new Vue({
el:"#container",
router:myrouter,
methods:{
test:function(){
//js代码实现路由跳转:编程式导航
myrouter.push("/a");
}
}
});
script>
//1.字符串
myrouter.push("/a");
//2.对象
myrouter.push({path:"/a"});
//3.命名的路由 name参数指的是定义路由时指定的名字
myrouter.push({name:"r1",params:{id:101}});
//4.URL传值,相当于/a?id=101
myrouter.push({path:"/a",query:{id:101}});
功能与push一致,区别在于replace()不会向history添加新的浏览记录
参数为一个整数,表示在浏览器历史记录中前后/后退多少步 相当于
window.history.go(-1)
的作用
命名路由:在定义路由的时候可以给路由指定name,我们在进行路由导航时可以通过路由的名字导航
<div id="container">
<input type="text" v-model="rname"/>
<router-link :to="{name:rname}">t1router-link>
<button type="button" @click="test">按钮1button>
<router-view>router-view>
div>
<script type="text/javascript">
const t1 = {
template:"t1"
};
const t2 = {
template:"t2"
};
const myrouter = new VueRouter({
routes:[
{
path:"/a",
name:"r1",
component:t1
},
{
path:"/b",
name:"r2",
component:t2
}
]
});
var vm = new Vue({
el:"#container",
data:{
rname:"r1"
},
router:myrouter,
methods:{
test:function(){
myrouter.push({name:vm.rname});
}
}
});
script>
<div id="container">
<router-link to="/a">t1router-link>
<router-link to="/b">t2router-link>
<router-view name="v1">router-view>
<router-view name="v2">router-view>
div>
<script type="text/javascript">
const t11 = {
template:"t11"
};
const t12 = {
template:"t12"
};
const t21 = {
template:"t21"
};
const t22 = {
template:"t22"
};
const myrouter = new VueRouter({
routes:[
{
path:"/a",
components:{
v1:t11,
v2:t12
}
},
{
path:"/b",
components:{
v1:t21,
v2:t22
}
}
]
});
var vm = new Vue({
el:"#container",
router:myrouter
});
script>
访问/b
,重定向到/a
<div id="container">
<router-link to="/a">路径Arouter-link>
<router-link to="/b">路径Brouter-link>
<router-view>router-view>
div>
<script type="text/javascript">
const t1 = {
template:"index"
};
const myrouter = new VueRouter({
routes:[
{
path:"/a",
component:t1
},
{
path:"/b",
redirect:"/a"
}
]
});
var vm = new Vue({
el:"#container",
router:myrouter
});
script>
const myrouter = new VueRouter({
routes:[
{
path:"/a",
name:"r1",
component:t1
},
{
path:"/b",
//redirect:"/a" //根据路由路径重定向
redirect:{name:"r1"} //根据路由命名重定向
}
]
});
<div id="container">
<router-link to="/a">路径Arouter-link>
<router-link to="/wahaha">路径wahaha(别名)router-link>
<router-view>router-view>
div>
<script type="text/javascript">
const t1 = {
template:"index"
};
const myrouter = new VueRouter({
routes:[
{
path:"/a",
alias:"/wahaha",
component:t1
}
]
});
var vm = new Vue({
el:"#container",
router:myrouter
});
script>
可以通过/url/:attr
方式实现通过路由传值给组件
<div id="container">
<router-link to="/a/101">路径Arouter-link>
<router-view>router-view>
div>
<script type="text/javascript">
const t1 = {
template:`
index:{{$route.params.id}}
`
};
const myrouter = new VueRouter({
routes:[
{
path:"/a/:id",
component:t1
}
]
});
var vm = new Vue({
el:"#container",
router:myrouter
});
script>
通过props传参
<div id="container">
<router-link to="/a/102">路径Arouter-link>
<router-view>router-view>
div>
<script type="text/javascript">
const t1 = {
props:["id"],
template:`
index:{{id}}
`
};
const myrouter = new VueRouter({
routes:[
{
path:"/a/:id",
props:true,
component:t1
}
]
});
var vm = new Vue({
el:"#container",
router:myrouter
});
script>
你们中大多数人都熟悉程序员的美德,有三种:那就是懒惰、急躁和傲慢。– Larry Wall,Perl 語言发明人