Vue
文章目录
Vue基础
el:挂载点
- el是用来设置Vue实例挂载(管理)的元素.
- Vue会管理el选项命中的元素及其内部的后代元素(Vue实例的作用范围)
- 可以使用其他的选择器,但是建议使用ID选择器
- 可以使用其他的双标签,不能使用HTML和BODY
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{{message}}
<div id="app" class="app">
{{message}}
<span> {{message}}</span>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
// el: ".app",
// el: "div",
data: {
message: "易烊千玺"
}
})
</script>
</body>
</html>
data:数据对象
- Vue中用到的数据定义在data中
- data中可以写复杂类型的数据
- 渲染复杂类型数据时,遵守js的语法即可
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{message}}
<h2>{{school.name}} {{school.mobile}}</h2>
<ul>
<li>{{campus[0]}}</li>
<li>{{campus[1]}}</li>
<li>{{campus[2]}}</li>
<li>{{campus[3]}}</li>
</ul>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
message: "你好,易烊千玺!",
school: {
name: "易烊千玺",
mobile: "15575566765"
},
campus: ["北京", "上海", "广州", "深圳"]
}
})
</script>
</body>
</html>
const的使用
注意:
- 一旦给const修饰的标识符被赋值后,不能修改
- 在使用const定义标识符,必须进行赋值
- 常量的含义是指向的对象不能修改,但是可以改变对象内部的属性
建议:在ES6开发中,优先使用const,只有需要改变某一个标识符的时候才使用let.
插值操作
Mustache语法(也就是双大括号)
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
<h2>{{message}},易烊千玺</h2>
<h2>{{firstName + lastName}}</h2>
<h2>{{firstName +' '+lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{Counter * 2}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:'你好啊',
firstName:'Kobe',
lastName:'Amy',
Counter:100
}
})
</script>
</body>
</html>
v-once
- 该指令后面不需要任何表达式(比如之前的v-for后面是由跟表达式的)
- 该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>{{message}}</div>
<div v-once>{{message}}</div>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
}
})
</script>
</body>
</html>
v-html
设置标签的innerHTML
- v-html指令的作用是:设置元素的innerHTML
- 内容中有html结构会被解析为标签
- v-text指令无论内容是什么,只会解析为文本
- 解析文本使用v-text,需要解析html结构使用v-html
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p v-html="content"></p>
<p v-text="content"></p>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
// content: "易烊千玺"
content: "<a href='#'>yyqx</a>"
}
})
</script>
</body>
</html>
v-text
设置标签的文本值(textContent)
- v-text指令的作用是:设置标签的内容(textContent)
- 默认写法会替换全部部分,使用差值表达式{{}} 可以替换指定内容
- 内部支持写表达式
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2 v-text="message +'!'">深圳</h2>
<h2 v-text="info +'!'">深圳</h2>
<h2>{{message +'!'}}深圳</h2>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
message: "易烊千玺!!",
info: "前端开发"
}
})
</script>
</body>
</html>
v-pre
v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
示例:
<p>{{ message }}</p> 输出:Hello World
<p v-pre>{{ message }}</p> 输出:{{ message }}
message='Hello World'
v-cloak
- 在某些情况下,我们浏览器可能会直接显示出未编译的Mustache标签(防止显示)
- cloak: 斗篷
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
{{message}}
</div>
<script src="vue.js"></script>
<script>
//在vue解析之前,div中有一个属性v-cloak
//在vue解析之后,div中没有一个属性v-cloak
setTimeout(function () {
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
}
})
},1000)
</script>
</body>
</html>
动态绑定属性
v-bind
v-bind的基本使用
设置元素的属性(比如:src,title,class)
- v-bind指令的作用是:为元素绑定属性
- 完整的写法是v-bind:属性名
- 简写的话可以直接省略v-bind,只保留 :属性名
- 需要动态的增删class建议使用对象的方法
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.active {
border: 1px solid red;
}
</style>
</head>
<body>
<div id="app">
<img v-bind:src="imgSrc" alt="">
<br>
<!-- 简写 -->
<img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="isActive?'active':''" @click="toggleActive">
<br>
<img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class={active:isActive} @click="toggleActive">
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
imgSrc: "images/yyqx1.jpg",
imgTitle: "易烊千玺",
isActive: false
},
methods: {
toggleActive: function () {
this.isActive = !this.isActive;
}
}
})
</script>
</body>
</html>
v-bind动态绑定class(对象语法)
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.active {
color: red;
}
</style>
</head>
<body>
<div id="app">
<!-- <h2 class="active">{{massage}}</h2>
<h2 :class="active">{{massage}}</h2> -->
<!-- <h2 v-bind:class="{类名1:true,类名2:boolean}"></h2> -->
<!-- <h2 v-bind:class="{active:true,line:false}">{{massage}}</h2> -->
<!--类名会合并-->
<h2 class="title" v-bind:class="{active:isActive,line:isLine}">{{massage}}</h2>
<h2 v-bind:class="getClasses()">{{massage}}</h2>
<button @click="btnClick">按钮</button>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
massage: 'yyqx',
isActive: true,
isLine: true
},
methods: {
btnClick: function () {
this.isActive = !this.isActive;
},
getClasses: function () {
return { active: this.isActive, line: this.isLine }
}
}
})
</script>
</body>
</html>
v-bind动态绑定class(数组语法)
- 用的比较少
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2 class="title" :class="[active,line]">{{massage}}</h2>
<h2 class="title" :class="['active','line']">{{massage}}</h2> <!--加单引号是本身-->
<h2 class="title" :class="[getClasses()]">{{massage}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
massage: 'ni',
active: 'aaaa',
line: 'bbbb'
},
methods: {
getClasses: function () {
return [this.active, this.line]
}
}
})
</script>
</body>
</html>
v-bind动态绑定style(对象语法)
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- <h2 :class="{类名:value}">{{massage}}</h2> -->
<!-- <h2 :style="{key(css属性名):value(属性值)}">{{massage}}</h2> -->
<!-- '50px' 必须加上单引号,否则是当作一个变量去解析 -->
<!-- <h2 :style="{fontSize:'50px'}">{{massage}}</h2> -->
<!-- finalSize当作一个变量使用 -->
<!-- <h2 :style="{fontSize:finalSize}">{{massage}}</h2> -->
<h2 :style="getStyles()">{{massage}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
massage: 'ni',
// finalSize: '100px'
finalSize: 100,
finalColor: 'red'
},
methods: {
getStyles: function () {
return { fontSize: this.finalSize + 'px', backgroundColor: this.finalColor }
}
}
})
</script>
</body>
</html>
v-bind动态绑定style(数组语法)
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2 :style="[baseStyle,baseStyle1]">{{massage}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
massage: 'ni',
baseStyle: { backgroundColor: 'red' },
baseStyle1: { fontSize: '100px' }
}
})
</script>
</body>
</html>
计算属性
计算属性的基本使用
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{fullName}}</h2> <!--不用写括号-->
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Amy',
lastName: 'Andy'
},
//computed: 计算属性()
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
},
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</body>
</html>
计算属性的复杂使用
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2>总价格: {{totalPrice}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
books: [
{ id: 110, name: '背影', price: 119 },
{ id: 111, name: '背影1', price: 114 },
{ id: 112, name: '背影2', price: 113 },
{ id: 113, name: '背影3', price: 111 }
]
},
//computed: 计算属性()
computed: {
totalPrice: function () {
let result = 0;
for (let i = 0; i < this.books.length; i++) {
result += this.books[i].price
}
return result;
}
}
})
</script>
</body>
</html>
计算属性的setter和getter
- 每个计算属性都包含一个getter和一个setter
- 在上面的例子中,我们只是使用getter来获取
- 在某些情况下,你也可以提供一个setter方法(不常用)
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 不要加小括号-->
<h2>{{fullName}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName:'yyqx',
lastName:'yyds'
},
computed:{
// fullName:function () {
// return this.firstName + ' ' +this.lastName
// }
// fullName:{
// set:function () {
//
// },
//计算属性一般是没有set方法,只读属性
// get:function () {
// return this.firstName + ' ' +this.lastName
// }
// },
fullName:function () {
return this.firstName + ' ' +this.lastName
}
}
})
</script>
</body>
</html>
计算属性和methods的对比
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 1.直接拼接:语法过于繁琐 -->
<h2>{{firstName + ' ' + lastName}}</h2>
<!-- 2.通过定义methods -->
<!-- <h2>{{getFullName()}}</h2>-->
<!-- <h2>{{getFullName()}}</h2>-->
<!-- <h2>{{getFullName()}}</h2>-->
<!-- <h2>{{getFullName()}}</h2>-->
<!-- <h2>{{getFullName()}}</h2>-->
<!-- 3.通过computed -->
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName:'yyqx',
lastName:'yyds'
},
methods: {
getFullName() {
console.log('getFullName');//打印5次
return this.firstName + ' ' + this.lastName
}
},
computed: {
fullName: function () {
console.log('fullName');//打印1次
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</body>
</html>
事件监听
v-on的基本使用
为元素绑定事件
- v-on指令的作用是:为元素绑定事件
- 事件名不需要写 on
- 指令可以简写为 @
- 绑定的方法定义在methods属性中
- 方法内部通过this关键字可以访问定义在data中数据
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="v-on指令" v-on:click="doIt">
<input type="button" value="v-on简写" @click="doIt">
<input type="button" value="双击事件" @dblclick="doIt">
<h2 @click="changeFood">{{food}}</h2>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
food: "番茄炒蛋"
},
methods: {
doIt: function () {
alert("做IT");
},
changeFood: function () {
this.food += "好好吃!"
}
},
})
</script>
</body>
</html>
v-on参数传递问题
- 事件绑定的方法写成函数调用的形式,可以传入自定义参数
- 定义方法时需要定义形参来接受传入的实参
- 事件的后面跟上 .修饰符 可以对事件进行限制
- .enter 可以限制触发的按键为回车
- 事件修饰符有多种
- 在事件定义时,写函数时省略了小括号,但是方法本身是需要一个参数的
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="点击" @click="doIt(666,'真帅')">
<input type="text" @keyup.enter="sayHi">
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
methods: {
doIt: function (p1, p2) {
console.log('易烊千玺');
console.log(p1);
console.log(p2);
},
sayHi: function () {
alert('吃了没');
}
},
})
</script>
</body>
</html>
v-on修饰符
Vue提供了修饰符来帮助我们方便的处理一些事件:
-
.stop — 调用event.stopPropagation()。阻止事件冒泡
-
.prevent — 调用event.preventDefault()。阻止默认事件
-
.once — 只触发一次回调。
-
.enter — 可以限制触发的按键为回车
条件判断
v-if的使用
- v-if指令的作用是:根据表达式的真假切换元素的显示状态(操作dom元素)
- 本质是通过操纵dom元素来切换显示状态
- 表达式的值为true,元素存在与dom树中,为false,从dom树中移除
- 频繁的切换v-show,反之使用v-if,前者的切换消耗小
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="切换显示" @click="toggleIsShow">
<p v-if="isShow">易烊千玺</p>
<p v-show="isShow">易烊千玺-v-show修饰</p>
<h2 v-if="temperature>=35">热si了</h2>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
isShow: false,
temperature: 20
},
methods: {
toggleIsShow: function () {
this.isShow = !this.isShow;
}
}
})
</script>
</body>
</html>
v-if和v-else的使用
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 v-if="isShow">
<div>123</div>
<div>123</div>
<div>123</div>
<div>123</div>
{{message}}
</h2>
<h1 v-else>isShow为false时,显示我</h1>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊",
isShow:true
}
})
</script>
</body>
</html>
v-if和v-else-if和v-else的使用
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 v-if="score>=90">优秀</h2>
<h2 v-else-if="score>=80">良好</h2>
<h2 v-else-if="score>=60">及格</h2>
<h2 v-else>不及格</h2>
<h1>{{result}}</h1>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
score:99
},
//推荐使用
computed:{
result(){
let showMessage = '';
if (this.score>=90){
showMessage = '优秀'
} else if (this.score >=80){
showMessage = '良好'
}
//...
return showMessage
}
}
})
</script>
</body>
</html>
用户登录切换的案例
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input type="text" id="username" placeholder="用户账号" key="username">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" id="email" placeholder="用户邮箱" key="email">
</span>
<button @click="isUser = !isUser">切换类型</button>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isUser:true
},
methods:{
}
})
</script>
</body>
</html>
v-show
- v-show指令的作用是:根据真假切换元素的显示状态
- 原理是修改元素的display,实现显示隐藏
- 指令后面的内容,最终都会解析为布尔值
- 值为true元素显示,值为false元素隐藏
- 数据改变之后,对应元素的显示状态会同步更新
- 频繁的切换v-show,反之使用v-if,前者的切换消耗小
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="切换显示状态" @click="changeIsShow">
<input type="button" value="累加年龄" @click="addAge">
<br>
<img v-show="isShow" src="images/yyqx.jpg" alt="">
<img v-show="age>=18" src="images/yyqx.jpg" alt="">
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
isShow: false,
age: 17
},
methods: {
changeIsShow: function () {
this.isShow = !this.isShow;
},
addAge: function () {
this.age++;
}
}
})
</script>
</body>
</html>
循环遍历
v-for
- v-for指令的作用是:根据数据生成列表结构
- 数组经常和v-for结合使用
- 语法是 (item.index) in 数据
- item和index可以结合其他指令一起使用
- 数组长度的更新会同步到页面上,是响应式的
v-for遍历数组
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 1.在遍历的过程中,没有使用索引值(下标值)-->
<ul>
<li v-for="item in names">{{item}}</li>
</ul>
<!-- 2.在遍历的过程中,获取索引值-->
<ul>
<li v-for="(item,index) in names">
{{index+1}}.{{item}}
</li>
</ul>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
names:['yyqx1','yyqx2','yyxq3','yyxq4','yyxq5']
}
})
</script>
</body>
</html>
v-for遍历对象
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 1.在遍历对象的过程中,如果只是获取一个值,那么获取到的是value-->
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
<!-- 2.获取 key 和 value -> 格式:(value,key)-->
<ul>
<li v-for="(value,key) in info">{{value}}-{{key}}</li>
</ul>
<!-- 3.获取 key 和 value 和 index -> 格式:(value,key,index) 用的很少-->
<ul>
<li v-for="(value,key,index) in info">{{value}}-{{key}}-{{index}}</li>
</ul>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
info:{
name:'yyqx',
age: 19,
sex: '男'
}
}
})
</script>
</body>
</html>
v-for使用过程添加key属性

代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
letters:['a','b','c','d','e']
}
})
</script>
</body>
</html>
哪些数组的方法是响应式的
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in letters">{{item}}</li>
</ul>
<button @click="btnClick">按钮</button>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
letters:['a','b','c','d','e']
},
methods:{
btnClick(){
//1.push方法(可以添加多个)
// this.letters.push('aaa');
// this.letters.push('aaaa','bbbb','cccc');
//2.pop():删除数组中的最后一个元素
// this.letters.pop();
//3.shift():删除数组中的第一个元素
// this.letters.shift();
//4.unshift():在数组最前面添加元素(可以添加多个)
// this.letters.unshift('aaa');
// this.letters.unshift('aaaa','bbbb','cccc');
//5.splice()
//splice作用:删除元素/插入元素/替换元素
//删除元素:第二个参数传入你要删除几个元素(如果没有传,就删除后面所有元素)
//替换元素:第二个参数,表示我们要替换几个元素,后面是用来替换前面的元素
//插入元素:第二个参数,传入0,并且后面跟上要插入的元素
//splice(start)
// this.letters.splice(1,2);
// this.letters.splice(1,3,'m','n','l');
// this.letters.splice(1,0,'x','y','z');
//6.sort():排序
// this.letters.sort();
//7.reverse():反转
// this.letters.reverse();
//注意:通过索引值修改数组中的元素(不是响应式的)
// this.letters[0] = 'bbb';
// this.letters.splice(0,1,'bbbbbb');
//set(要修改的值,索引值,修改后的值)
Vue.set(this.letters,0,'bbbbb');
}
}
})
</script>
</body>
</html>
书籍购物车案例
代码示例:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<div v-if="books.length">
<table>
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in books">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.data}}</td>
<td>{{item.price | showPrice}}</td>
<td>
<button @click="decrement(index)" v-bind:disabled="item.count <= 1">-</button>
{{item.count}}
<button @click="increment(index)">+</button>
</td>
<td><button @click="removeHandle(index)">移除</button></td>
</tr>
</tbody>
</table>
<h2>总价格:{{totalPrice | showPrice}}</h2>
</div>
<h2 v-else>购物车为空</h2>
</div>
<script src="../vue.js"></script>
<script src="main.js"></script>
</body>
</html>
style.css
table {
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th,td {
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: left;
}
th {
background-color: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
main.js
const app = new Vue({
el:'#app',
data:{
books:[
{
id:1,
name:'《c语言》',
data:'2021-1',
price:85.00,
count:1
},
{
id:2,
name:'《c++语言》',
data:'2021-2',
price:99.00,
count:1
},
{
id:3,
name:'《java语言》',
data:'2021-3',
price:105.00,
count:1
},
{
id:4,
name:'《c#语言》',
data:'2021-4',
price:89.00,
count:1
},
]
},
methods:{
// getFinalPrice(price){
// return '¥' + price.toFixed(2)
// }
increment(index){
// console.log('increment',index);
this.books[index].count++
},
decrement(index){
// console.log('decrement',index);
this.books[index].count--
},
removeHandle(index){
this.books.splice(index, 1)
}
},
computed:{
totalPrice() {
//1.普通的for循环
// let totalPrice = 0;
// for(let i = 0;i < this.books.length;i++){
// totalPrice +=this.books[i].count * this.books[i].price;
// }
// return totalPrice;
//2.for(let i in this.books)
// let totalPrice = 0;
// for (let i in this.books){
// totalPrice +=this.books[i].count * this.books[i].price;
// }
// return totalPrice;
//3.for(let i of this.books)
// let totalPrice = 0;
// for (let item of this.books){
// totalPrice += item.price * item.count;
// }
// return totalPrice;
//4. reduce
return this.books.reduce(function (preValue,book) {
return preValue + book.price * book.count
},0)
}
},
filters:{
showPrice(price) {
return '¥' + price.toFixed(2)
}
}
})
js高阶函数的使用
filter/ map/ reduce
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
</div>
<script src="vue.js"></script>
<script>
// js高阶函数的使用
const nums = [10,20,111,222,333,444,30,50,60]
// let total = nums.filter(n => n < 100).map(n => n * 2).reduce((pre, n) => pre + n);
// console.log(total);
let total = nums.filter(function (n) {
return n < 100
}).map(function (n) {
return n * 2
}).reduce(function (preValue,n) {
return preValue + n
},0)
console.log(total);
//1.filter函数的使用
//filter中回调函数有一个要求:必须返回一个boolean值
//true:当返回true时,函数内部会自动将这次回调的n加入到新的数组中
//false:当返回false时,函数内部会过滤调这次的n
// const nums = [10,20,111,222,333,444,30,50,60]
// //10,20,30,50,60
// let newNums = nums.filter(function (n) {
// return n < 100;
// })
// console.log(newNums);
//
// //2.map函数的使用
// let new2Nums = newNums.map(function (n) {
// return n * 2;
// })
// console.log(new2Nums);
//
// //3.reduce函数的使用
// //reduce作用对数组中所有的内容进行汇总
// let total = new2Nums.reduce(function (preValue,n) {
// return preValue + n
// },0)
// console.log(total);
//
//第一次:preValue 0 n 20
//第一次:preValue 20 n 40
//第一次:preValue 60 n 60
//第一次:preValue 120 n 100
//第一次:preValue 220 n 120
//340
</script>
</body>
</html>
v-model
获取和设置表单元素的值(双向数据绑定)
- v-model指令的作用是便捷的设置和获取表单元素的值
- 绑定的数据会和表单元素的值相关联
- 绑定的数据 <-------> 表单元素的值 (双向绑定)
v-model的基本使用
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- <input type="text" v-model="message">-->
<!--等同于-->
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
{{message}}
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
}
})
</script>
</body>
</html>
v-model原理
v-model其实是一个语法糖,它的背后本质上是包含两个操作:
- v-bind 绑定一个 value 属性
- v-on 指令给当前元素绑定 input 事件
<input type="text" v-model="message">
<!--等同于-->
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
v-model结合radio类型使用(单选)
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<label for="male">
<input type="radio" id="male" value="男" v-model="sex">男
</label>
<label for="female">
<input type="radio" id="female" value="女" v-model="sex">女
</label>
<h2>您选择的性别是:{{sex}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊",
sex:'女'
}
})
</script>
</body>
</html>
v-model结合checkbox类型使用(单选框/多选框)
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 1.checkbox单选框-->
<!-- <label for="agree">-->
<!-- <input type="checkbox" id="agree" v-model="agree">同意协议-->
<!-- </label>-->
<!-- <h2>您选择的是:{{isAgree}}</h2>-->
<!-- <button :disabled="!isAgree">下一步</button>-->
<!-- 2.checkbox多选框-->
<label for="">
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
<input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
</label>
<h2>您的爱好是:{{hobbies}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊",
isAgree:false, //单选框
hobbies:[] //多选框
}
})
</script>
</body>
</html>
v-model结合select类型使用
- 和 checkbox 一样,select 也分单选和多选两种情况。

代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 1.选择一个-->
<select name="abc" v-model="fruit">
<option value="易烊千玺帅" >易烊千玺帅</option>
<option value="易烊千玺帅帅">易烊千玺帅帅</option>
<option value="易烊千玺帅帅帅">易烊千玺帅帅帅</option>
<option value="易烊千玺帅帅帅帅">易烊千玺帅帅帅帅</option>
</select>
<h2>您选择的是:{{fruit}}</h2>
<!-- 1.选择多个 (按Ctrl 多选)-->
<select name="abc" v-model="fruits" multiple>
<option value="易烊千玺帅" >易烊千玺帅</option>
<option value="易烊千玺帅帅">易烊千玺帅帅</option>
<option value="易烊千玺帅帅帅">易烊千玺帅帅帅</option>
<option value="易烊千玺帅帅帅帅">易烊千玺帅帅帅帅</option>
</select>
<h2>您选择的是:{{fruits}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊",
fruit:'易烊千玺帅',
fruits:[]
}
})
</script>
</body>
</html>
input中的值绑定
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 1.checkbox单选框-->
<!-- <label for="agree">-->
<!-- <input type="checkbox" id="agree" v-model="agree">同意协议-->
<!-- </label>-->
<!-- <h2>您选择的是:{{isAgree}}</h2>-->
<!-- <button :disabled="!isAgree">下一步</button>-->
<!-- 2.checkbox多选框-->
<label for="">
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
<input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
</label>
<h2>您的爱好是:{{hobbies}}</h2>
<!-- 值绑定-->
<label v-for="item in originHobbies" :for="item">
<input type="checkbox" :value="item" :id="item" v-model="hobbies">{{item}}
</label>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊",
isAgree:false, //单选框
hobbies:[], //多选框
originHobbies:['篮球','足球','羽毛球','乒乓球','排球']
}
})
</script>
</body>
</html>
v-model修饰符的使用

代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 1.修饰符:lazy-->
<input type="text" v-model.lazy="message">
<h2>{{message}}</h2>
<!-- 2.修饰符:number-->
<input type="text" v-model.number="age">
<h2>{{age}}-{{typeof age}}</h2>
<!-- 3.修饰符:trim(去掉空格)-->
<input type="text" v-model.number.trim="name">
<h2>您输入的名字是:{{name}}</h2>
</div>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊",
age:0,
name:''
}
})
</script>
</body>
</html>
组件化开发
组件的使用分为三个步骤:
- 创建组件构造器
- 注册组件
- 使用组件

组件化的基本使用

代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 3.使用组件-->
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
<script src="vue.js"></script>
<script>
// ES6
//1.创建组件构造器对象
const cpnC = Vue.extend({
template:`
<div>
<h2>我是标题</h2>
<p>我是内容111</p>
<p>我是内容222</p>
</div>`
})
//2.注册组件
Vue.component('my-cpn',cpnC)
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
}
})
</script>
</body>
</html>
全局组件与局部组件
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<div id="app2">
<cpn></cpn>
</div>
<script src="vue.js"></script>
<script>
//1.创建组件构造器对象
const cpnC = Vue.extend({
template:`
<div>
<h2>我是标题</h2>
<p>我是内容111</p>
<p>我是内容222</p>
</div>`
})
//2.注册组件(全局组件,意味着可以在多个Vue的实例下面使用)
// Vue.component('my-cpn',cpnC)
// 疑问:怎么注册的组件才是局部组件?
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
},
//局部组件
components:{
//cpn使用组件时的标签名
cpn:cpnC
}
})
const app2 = new Vue({
el: '#app2'
})
</script>
</body>
</html>
父组件和子组件
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn2></cpn2>
</div>
<script src="vue.js"></script>
<script>
// 1.创建第一个组件构造器(子组件)
const cpnC1 = Vue.extend({
template:`
<div>
<h2>易烊千玺</h2>
<p>帅帅帅</p>
</div>>
`
})
// 2.创建第二个组件构造器(父组件)
const cpnC2 = Vue.extend({
template:`
<div>
<h2>易烊千玺呀</h2>
<p>帅帅帅帅</p>
<cpn1></cpn1>
</div>>
`,
components:{
cpn1: cpnC1
}
})
// root组件
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
},
components: {
cpn2: cpnC2
}
})
</script>
</body>
</html>
注册组件的语法糖写法
主要是省去了调用Vue.extend()的步骤,而是可以直接使用一个对象来代替。
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn1></cpn1>
<cpn2></cpn2>
</div>
<script src="vue.js"></script>
<script>
// 1.全局组件注册的语法糖
//1.创建组件构造器对象
// const cpn1 = Vue.extend()
//2.注册组件
Vue.component('cpn1',{
template:`
<div>
<h2>我是标题</h2>
<p>我是内容111</p>
</div>`
})
// 2.注册局部组件的语法糖
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
},
components:{
'cpn2':{
template:`
<div>
<h2>我是标题</h2>
<p>我是内容222</p>
</div>`
}
}
})
</script>
</body>
</html>
组件模板的分离写法
- 使用 < script > 标签
- 使用 < template >标签
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<!--1.script标签, 注意: 类型必须是text/x-template -->
<!--<script type="text/x-template" id="cpn">-->
<!--<div>-->
<!-- <h2>易烊千玺</h2>-->
<!-- <p>帅帅帅帅帅</p>-->
<!--</div>-->
<!--</script>-->
<!--2.template标签-->
<template id="cpn">
<div>
<h2>易烊千玺</h2>
<p>帅帅帅帅帅</p>
</div>
</template>
<script src="vue.js"></script>
<script>
//1.注册一个全局组件
Vue.component('cpn',{
template:'#cpn'
})
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
}
})
</script>
</body>
</html>
组件数据的存放
- 组件对象也有一个data属性(也可以有methods等属性)
- 只是这个data属性必须是一个函数
- 而且这个函数返回一个对象,对象内部保存着数据
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<!--1.script标签, 注意: 类型必须是text/x-template -->
<!--<script type="text/x-template" id="cpn">-->
<!--<div>-->
<!-- <h2>易烊千玺</h2>-->
<!-- <p>帅帅帅帅帅</p>-->
<!--</div>-->
<!--</script>-->
<!--2.template标签-->
<template id="cpn">
<div>
<h2>{{title}}</h2>
<p>帅帅帅帅帅</p>
</div>
</template>
<script src="vue.js"></script>
<script>
//1.注册一个全局组件
Vue.component('cpn',{
template:'#cpn',
data() {
return {
title: '易烊千玺' //数据存放
}
}
})
const app = new Vue({
el: '#app',
data: {
message:"你好啊",
title:'是易烊千玺呀'
}
})
</script>
</body>
</html>
组件中的data为什么是函数
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>当前计数:{{counter}}</h2>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script src="vue.js"></script>
<script>
//1.注册组件
const obj = {
counter: 0
}
Vue.component('cpn',{
template:'#cpn',
data() {
return obj
},
methods:{
increment() {
this.counter++
},
decrement() {
this.counter--
}
}
})
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
}
})
</script>
</body>
</html>
组件通信
父组件向子组件传递数据
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn :cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="cpn">
<div>
<ul>
<li v-for="item in cmovies">{{item}}</li>
</ul>
<h2>{{cmessage}}</h2>
</div>
</template>
<script src="vue.js"></script>
<script>
//父传子:props
const cpn = {
template:'#cpn',
// props:['cmovies','cmessage'],
props:{
// 1.类型限制
// cmovies: Array,
// cmessage: String,
//2.提供一些默认值,以及一些必传值
cmessage: {
type:String,
default: '易烊千玺',
required: true
},
//类型是对象或者数组时,默认值必须是一个函数
cmovies: {
type: Array,
default() {
return []
}
}
},
data() {
return{}
},
methods: {
}
}
const app = new Vue({
el: '#app',
data: {
message:"你好啊",
movies: ['中国医生','送你一朵小红花','少年的你']
},
components: {
cpn
}
})
</script>
</body>
</html>
父传子(props中的驼峰标识)
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 如果用驼峰: 加- -->
<cpn :c-info="info"></cpn>
</div>
<template id="cpn">
<h2>{{cInfo}}</h2>
</template>
<script src="vue.js"></script>
<script>
const cpn = {
template:'#cpn',
props:{
cInfo: {
type: Object,
default() {
return {}
}
}
}
}
const app = new Vue({
el: '#app',
data: {
info: {
name: '易烊千玺',
age: 100,
height: 1.88
}
},
components: {
cpn
}
})
</script>
</body>
</html>
子传父(自定义事件)
什么时候需要自定义事件?
- 当子组件需要向父组件传递数据时,就要用到自定义事件了。
- 我们之前学习的v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件。
自定义事件的流程:
- 在子组件中,通过 $emit() 来触发事件
- 在父组件中,通过v-on来监听子组件事件
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--父组件模板-->
<div id="app">
<cpn v-on:itemclick="cpnClick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<script src="vue.js"></script>
<script>
//1.子组件
const cpn = {
template:'#cpn',
data() {
return {
categories: [
{id:'aaa', name:'热门推荐'},
{id:'bbb', name:'手机数码'},
{id:'ccc', name:'家用家电'},
{id:'ddd', name:'电脑办公'},
]
}
},
methods: {
btnClick(item) {
//发射事件:自定义事件
this.$emit('itemclick', item)
}
}
}
//2.父组件
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
},
components: {
cpn
},
methods: {
cpnClick(item) {
console.log('cpnClick', item);
}
}
})
</script>
</body>
</html>
父子组件通信案例
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn :number1="num1"
:number2="num2"
@num1change="num1change"
@num2change="num2change">
</cpn>
</div>
<template id="cpn">
<div>
<h2>props:{{number1}}</h2>
<h2>data:{{dnumber1}}</h2>
<!-- <input type="text" v-model="dnumber1">-->
<input type="text" :value="dnumber1" @input="num1Input">
<h2>props:{{number2}}</h2>
<h2>data:{{dnumber2}}</h2>
<!-- <input type="text" v-model="dnumber2">-->
<input type="text" :value="dnumber2" @input="num2Input">
</div>
</template>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
num1: 1,
num2: 0
},
methods: {
num1change(value) {
this.num1 = parseFloat(value)
},
num2change(value) {
this.num2 = parseFloat(value)
}
},
components: {
cpn: {
template:'#cpn',
props: {
number1: Number,
number2: Number
},
data() {
return {
dnumber1: this.number1,
dnumber2: this.number2
}
},
methods: {
num1Input(event) {
//1.将input中的value赋值到dnumber中
this.dnumber1 = event.target.value;
//2.为了让父组件可以修改值,发出一个事件
this.$emit('num1change', this.dnumber1);
//3.同时修改dnumber2的值
this.dnumber2 = this.dnumber1 * 100;
this.$emit('num2change', this.dnumber2)
},
num2Input(event) {
this.dnumber2 = event.target.value;
this.$emit('num2change', this.dnumber2);
//3.同时修改dnumber2的值
this.dnumber1 = this.dnumber2 / 100;
this.$emit('num1change', this.dnumber1)
}
}
}
}
})
</script>
</body>
</html>
父子组件的访问
父访问子-children-refs
-
父组件访问子组件: 使用 $children 或者 $refs
-
this.$children是一个数组类型,它包括所有的子组件对象
-
$refs => 对象类型, 默认是一个空的对象

代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="cpn">
<div>我是子组件</div>
</template>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
},
methods: {
btnClick() {
// 1.$children
// console.log(this.$children);
// for (let c of this.$children) {
// console.log(c.name);
// c.showMessage();
// }
// console.log(this.$children[2].name);
// 2.$refs => 对象类型, 默认是一个空的对象 必须加 ref='bbb'
console.log(this.$refs.aaa.name);
}
},
components: {
cpn: {
template: '#cpn',
data() {
return {
name: '我是子组件的name'
}
},
methods: {
showMessage() {
console.log('showMessage');
}
}
},
}
})
</script>
</body>
</html>
子访问父-parent-root
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>我是cpn组件</h2>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<ccpn></ccpn>
</div>
</template>
<template id="ccpn">
<div>
<h2>我是子组件</h2>
<button @click="btnClick">按钮</button>
</div>
</template>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
},
components: {
cpn: {
template: '#cpn',
data() {
return {
name:'我是cpn组件的name'
}
},
components: {
ccpn: {
template: '#ccpn',
methods:{
btnClick() {
//1.访问父组件$parent
console.log(this.$parent);
console.log(this.$parent.name);
//2.访问根组件$root
console.log(this.$root);
console.log(this.$root.message);
}
},
}
}
}
}
})
</script>
</body>
</html>
组件化高级
slot-插槽的基本使用
组件的插槽:
- 组件的插槽也是为了让我们封装的组件更加具有扩展性
- 让使用者可以决定组件内部的一些内容到底展示什么


- 插槽的基本使用 < slot>< /slot>
- 插槽的默认值 < slot>< button>< /button>< /slot>
- 如果有多个值,同时放入到组件进行替换时,一起作为替换元素
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--1.插槽的基本使用 <slot></slot>-->
<!--2.插槽的默认值 <slot><button></button></slot>-->
<!--3.如果有多个值,同时放入到组件进行替换时,一起作为替换元素-->
<div id="app">
<cpn><button>按钮</button></cpn>
<cpn><span>hhh</span></cpn>
<cpn>
<i>啦啦啦</i>
<div>我是div元素</div>
<p>我是p元素</p>
</cpn>
<cpn><button>按钮</button></cpn>
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>我是组件</h2>
<p>我是组件,略略略</p>
<!-- <button>按钮</button>-->
<slot><button>按钮</button></slot>
</div>
</template>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
},
components: {
cpn: {
template: '#cpn'
}
}
})
</script>
</body>
</html>
slot-具名插槽的使用
slot-具名插槽的使用: 非常简单,只要给slot元素一个name属性即可。
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn><span slot="center">标题</span></cpn>
<cpn><button slot="left">返回</button></cpn>
</div>
<template id="cpn">
<div>
<slot name="left"><span>左边</span></slot>
<slot name="center"><span>中间</span></slot>
<slot name="right"><span>右边</span></slot>
</div>
</template>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
},
components: {
cpn: {
template: '#cpn'
}
}
})
</script>
</body>
</html>
什么是编译的作用域
父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- v指令 都会去Vue实例里,不会去组件里 在自己作用域中查找-->
<cpn v-show="isShow"></cpn>
</div>
<template id="cpn">
<div>
<h2>我是子组件</h2>
<p>我是内容,啦啦啦</p>
<button v-show="isShow">按钮</button>
</div>
</template>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊",
isShow: true
},
components: {
cpn: {
template: '#cpn',
data() {
return {
isShow: false
}
}
}
}
})
</script>
</body>
</html>
作用域插槽的案例
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn>
<!-- 目的是获取子组件中的pLanguages-->
<template slot-scope="slot">
<!-- <span v-for="item in slot.data">{{item}} - </span>-->
<span>{{slot.data.join(' - ')}}</span>
</template>
</cpn>
<cpn>
<!-- 目的是获取子组件中的pLanguages-->
<template slot-scope="slot">
<!-- <span v-for="item in slot.data">{{item}} * </span>-->
<span>{{slot.data.join(' * ')}}</span>
</template>
</cpn>
</div>
<template id="cpn">
<div>
<!-- 不一定取名data-->
<slot :data="pLanguages">
<ul>
<li v-for="item in pLanguages">{{item}}</li>
</ul>
</slot>
</div>
</template>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:"你好啊"
},
components: {
cpn: {
template: '#cpn',
data() {
return {
pLanguages: ['html','css','js','jquery','ajax','vue','mysql']
}
},
created() {
this.pLanguages.join(' - ')
}
}
}
})
</script>
</body>
</html>
ES6的模块化实现
代码笔记:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="aaa.js" type="module"></script>
<script src="bbb.js" type="module"></script>
<script src="mmm.js" type="module"></script>
</body>
</html>
aaa.js
var name = '小明'
var age = 18
var flag = true
function sum(num1,num2) {
return num1 + num2
}
if(flag) {
console.log(sum(20,30));
}
//1.导出方式一:
export {
flag, sum
}
//2.导出方式二:
export var num1 = 1000;
export var height = 1.88
//3.导出函数/类
export function mul(num1, num2) {
return num1 * num2
}
export class Person {
run() {
console.log('六六六');
}
}
//4.export default 注意:export default 在同一个模块中,不允许同时存在多个
//某些情况下,一个模块中包含某个功能,我们并不希望给这个功能命名,而且让导入者可以自己来命名
//这个时候就可以使用 export default
// const address = '长沙市'
// export {
// address
// }
// export const address = '长沙市'
// const address = '长沙市'
// export default address
export default function (argument) {
console.log(argument);
}
bbb.js
import {sum} from './aaa.js'
var name = '小红'
var age = 18
var flag = false
console.log(sum(100, 200));
mmm.js
//1.导入的对象{}中定义的变量
import {flag, sum} from "./aaa.js";
if (flag) {
console.log('小明是天才,哈哈哈');
console.log(sum(20, 30));
}
//2.直接导入export定义的变量
import {num1,height} from "./aaa.js";
console.log(num1);
console.log(height);
//3.导入 export的function/ class
import {mul, Person} from "./aaa.js"
console.log(mul(30, 50));
const p = new Person();
p.run()
// 4.导入 export default 中的内容
import addr from "./aaa.js";
addr('你好');
//统一全部导入
import{flag, num, num, num1, height, Person, mul, sum} from "./aaa.js";//导入东西太多,不建议使用
import * as aaa from "./aaa.js"
console.log(aaa.flag);
console.log(aaa.height);
webpack的使用

- export(导出)/ import(导入)
webpack的基本使用
准备工作:

打包: webpack ./src/main.js ./dist/bundle.js

初始化:npm init (建package.json)
npm install
将入口和出口放到一个配置文件里:
建一个webpack.config.js文件

简写:
npm run bulid 打包相当于是使用本地webpack打包的不是全局的

本地安装webpack:
npm install webpack@3.6.0 --save-dev
在终端使用的都是全局的
什么是loader

css文件处理 - css-loader

css文件处理 - style-loader

less文件处理 - less - loader

图片文件处理 - 资源准备阶段

图片文件处理 - url - loader

图片文件处理 - file - loader

图片文件处理 - 修改文件名称

ES6语法处理

webpack配置vue
引入vue.js: npm install vue --save




.vue文件封装处理

示例:


App.vue (代码分离)
<template>
<div>
<h2 class="title">{{message}}</h2>
<button @click="btnClick">按钮</button>
<h2>{{name}}</h2>
</div>
</template>
<script>
export default {
name: "App",
data(){
return {
message: 'Hello Webpack',
name:'yyqx'
}
},
methods: {
btnClick() {
}
}
}
</script>
<style scoped>
.title {
color: pink;
}
</style>
横幅plugin的使用
认识plugin

添加版权的plugin

结果:


打包html的plugin

js压缩的Plugin

搭建本地服务器

Vue CLI相关
什么是Vue CLI

Vue CLI使用前提 - Node
node.js已安装

Vue CLI使用前提 - Webpack
Webpack已安装

Vue CLI的使用

Vue CLI2详解

改Eslint

认识Vue CLI3

配置去哪里了

箭头函数
箭头函数的基本使用
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$Title$</title>
</head>
<body>
<script>
// 箭头函数:也是一种定义函数的方式
// 1.定义函数的方式:function
const aaa = function () {
}
// 2.对象字面量中定义函数
const obj = {
bbb() {
}
}
// 3.ES6中的箭头函数
// const ccc = (参数列表) => {
//
// }
const ccc = () => {
}
</script>
</body>
</html>
箭头函数参数和返回值
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$Title$</title>
</head>
<body>
<script>
// 1.参数问题
// 1.1.放入两个参数
const sum = (num1, num2) => {
return num1 + num2
}
//1.2.放入一个参数
const power = num => {
return num * num
}
//2.函数中
//2.1.函数代码块中有多行代码时
const test = () => {
//1.打印 Hello World
console.log('Hello World');
//2.打印 Hello Vuejs
console.log('Hello Vuejs');
}
//2.2.函数代码块中只有一行代码
// const mul = (num1, num2) => {
// return num1 * num2
// }
const mul = (num1, num2) => num1 * num2
console.log(mul(20, 30));
// const demo = () => {
// console.log('Hello Demo');
// }
const demo = () => console.log('Hello Demo');
console.log(demo());
</script>
</body>
</html>
箭头函数中的this的使用
- 结论: 箭头函数中的this引用的就是最近作用域中的this
- 问题: 箭头函数中的this是如何查找的?
- 答案: 向外层作用域中,一层层查找this,直到有this的定义
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$Title$</title>
</head>
<body>
<script>
//什么时候使用箭头函数
// setTimeout(function () {
// console.log(this);
// }, 1000)
// (打印的都是Window)
// setTimeout(() => {
// console.log(this);
// }, 1000)
//结论:箭头函数中的this引用的就是最近作用域中的this
//问题:箭头函数中的this是如何查找的?
//答案:向外层作用域中,一层层查找this,直到有this的定义
// const obj = {
// aaa() {
// setTimeout(function () {
// console.log(this); //打印Window
// }, 1000)
//
// setTimeout(() => {
// console.log(this); //打印Object对象
// }, 1000)
// }
// }
// obj.aaa()
const obj = {
aaa() {
setTimeout(function () {
setTimeout(function () {
console.log(this);//window
})
setTimeout(() => {
console.log(this);//window
})
})
setTimeout(() => {
setTimeout(function () {
console.log(this);//window
})
setTimeout(() => {
console.log(this);//object
})
})
}
}
obj.aaa()
</script>
</body>
</html>
vue-router详解
什么是路由
路由(routing) 就是通过互联的网络把信息从源地址传输到目的地址的活动。

后端路由阶段


改变URL让页面不刷新




认识vue-router
目前前端流行的三大框架,都有自己的路由实现:
- Angular的ngRouter
- React的ReactRouter
- Vue的vue-router
vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。
vue-router是基于路由和组件的
- 路由用于设定访问路径,将路径和组件映射起来
- 在vue-router的单页面应用中,页面的路径的改变就是组件的切换
安装和使用vue-router

router-link


修改linkActiveClass

路由代码跳转

动态路由

认识路由的懒加载

懒加载的方式

嵌套默认路径

vue-router-参数问题

$ route和$router是有区别的

导航守卫
为什么要使用导航守卫

导航守卫使用

keep-alive遇见vue-router

TabBar实现思路

代码实现:TabBar的代码实现文件
Promise
Promise是异步编程的一种解决方案。
那什么时候我们会来处理异步事件呢?
- 一种很常见的场景应该就是网络请求了。
- 我们封装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的3+4=7一样将结果返回。
- 所以往往我们会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。
- 如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦。
但是,当网络请求非常复杂时,就会出现回调地狱。

Promise的基本使用
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
//1.使用setTimeout
// setTimeout(() => {
// console.log('yyqx');
// }, 1000)
//参数 -> 函数(resolve,reject)
//resolve,reject本身它们又是函数
//链式编程
// new Promise((resolve,reject) => {
// // 第一次网络请求的代码
// setTimeout(() => {
// resolve()
// }, 1000)
// }).then(() => {
// // 第一次拿到结果的处理代码
// console.log('yyqx');
// console.log('yyqx');
// console.log('yyqx');
// console.log('yyqx');
// console.log('yyqx');
//
// return new Promise((resolve,reject) =>{
// //第二次网络请求的代码
// setTimeout(() => {
// resolve()
// }, 1000)
// })
// }).then(() => {
// //第二次处理的代码
// console.log('yyqx');
// console.log('yyqx');
// console.log('yyqx');
// console.log('yyqx');
// console.log('yyqx');
//
// return new Promise((resolve, reject) => {
// //第三次网络请求的代码
// setTimeout(() => {
// resolve()
// }, 1000)
// })
// }).then(() => {
// //第三次处理的代码
// console.log('yyqx');
// console.log('yyqx');
// console.log('yyqx');
// console.log('yyqx');
// console.log('yyqx');
// })
// 什么情况下会用到Promise?
// 一般情况下是有异步操作时,使用Promise对这个异步操作进行封装
// new -> 构造函数(1. 保存了一些状态信息 2.执行传入的函数)
// 在执行传入回调函数时,会传入两个参数, resolve,reject本身它们又是函数
new Promise((resolve, reject) => {
setTimeout(() => {
// 成功的时候调用resolve
// resolve('Hello World')
// 失败的时候调用reject
reject('error message')
}, 1000)
}).then((data) => {
// 1.100行的处理代码
console.log(data);
console.log(data);
console.log(data);
console.log(data);
console.log(data);
}).catch((err) => {
console.log(err);
})
</script>
</body>
</html>
Promise的另外处理形式
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
//then 可以传入两个参数 可以不用写catch
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello World')
// reject('error message')
}, 1000)
}).then(data => {
console.log(data);
}, err => {
console.log(err);
})
</script>
</body>
</html>
Promise的链式调用
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// wrapped into
// 网络请求: aaa -> 自己处理(10行)
// 处理: aaa111 -> 自己处理(10行)
// 处理: aaa111222 -> 自己处理
// new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve('aaa')
// }, 1000)
// }).then(res => {
// // 1.自己处理10行代码
// console.log(res, '第一层的10行处理代码');
//
// // 2.对结果进行第一次处理
// return new Promise((resolve,reject) => {
// // resolve(res + '111')
// reject('err')
// })
// }).then(res => {
// console.log(res, '第二层的10行处理代码');
//
// return new Promise(resolve => {
// resolve(res + '222')
// })
// }).then(res => {
// console.log(res, '第三层的10行处理代码')
// }).catch(err => {
// console.log(err);
// })
// new Promise(resolve => resolve(结果)) 简写
// new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve('aaa')
// }, 1000)
// }).then(res => {
// // 1.自己处理10行代码
// console.log(res, '第一层的10行处理代码');
//
// // 2.对结果进行第一次处理
// return Promise.resolve(res + '111')
// }).then(res => {
// console.log(res, '第二层的10行处理代码');
//
// return Promise.resolve(res + '222')
// }).then(res => {
// console.log(res, '第三层的10行处理代码')
// })
// 省略掉Promise.resolve
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
}, 1000)
}).then(res => {
// 1.自己处理10行代码
console.log(res, '第一层的10行处理代码');
// 2.对结果进行第一次处理
// return Promise.reject('error message')
throw 'error message'
}).then(res => {
console.log(res, '第二层的10行处理代码');
return res + '222'
}).then(res => {
console.log(res, '第三层的10行处理代码')
}).catch(err => {
console.log(err);
})
</script>
</body>
</html>
链式调用简写:

Promise的all方法使用
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// let isResult1 = false
// let isResult2 = false
// // 请求一:
// $ajax({
// url: '',
// success: function () {
// console.log('结果1');
// isResult1 = true
// handleResult()
// }
// })
// // 请求二:
// $ajax({
// url: '',
// success: function () {
// console.log('结果2');
// isResult2 = true
// handleResult()
// }
// })
//
// function handleResult() {
// if (isResult1 && isResult2) {
// }
// }
Promise.all([
// new Promise((resolve, reject) => {
// $ajax({
// url: 'url1',
// success: function (data) {
// resolve(data)
// }
// })
// }),
// new Promise((resolve, reject) => {
// $ajax({
// url: 'url2',
// success: function (data) {
// resolve(data)
// }
// })
// })
new Promise((resolve, reject) => {
setTimeout(() => {
resolve({name: 'yyqx', age: 100})
}, 2000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve({name: 'yyqx6', age: 120})
}, 1000)
})
]).then(results => {
console.log(results);
})
</script>
</body>
</html>
Vuex详解
Vuex是做什么的?


单页面的状态管理

Vuex核心概念
Vuex有几个比较核心的概念:
- State
- Getters
- Mutation
- Action
- Module
State单一状态树

Getters基本使用

代码示例:

Getters作为参数和传递参数

代码示例:

Mutation
Mutation状态更新

Mutation传递参数

代码示例:

Mutation提交风格

代码笔记:


Mutation响应规则

代码笔记:

Mutation常量类型
概念:

代码示例:

Mutation同步函数

Action的基本定义
Action类似于Mutation,但是是用来代替Mutation进行异步操作的。
代码示例:


Module

axios

axios的基本使用

代码示例:
import Vue from 'vue'
import App from './App'
import axios from 'axios'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h => h(App)
})
axios({
url: 'http://123.207.32.32:8000/home/multidata',
method: 'get'
}).then(res => {
console.log(res);
})
axios({
url: 'http://123.207.32.32:8000/home/data',
// 专门针对get请求的参数拼接
params: {
type: 'pop',
page: 1
}
}).then(res => {
console.log(res);
})
发送并发请求
有时候,我们可能需要同时发送两个请求
- 使用axios.all,可以放入多个请求的数组。
- axios.all([ ]) 返回的结果是一个数组,使用 axios.spread 可将数组 [res1, res2] 展开为 res1, res2
代码笔记:
import Vue from 'vue'
import App from './App'
import axios from 'axios'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h => h(App)
})
// 1.axios的基本使用
// axios({
// url: 'http://123.207.32.32:8000/home/multidata',
// method: 'get'
// }).then(res => {
// console.log(res);
// })
//
// axios({
// url: 'http://123.207.32.32:8000/home/data',
// // 专门针对get请求的参数拼接
// params: {
// type: 'pop',
// page: 1
// }
// }).then(res => {
// console.log(res);
// })
// 2.axios发送并发请求
// Promise.all([axios({
// url: 'http://123.207.32.32:8000/home/multidata'
// }), axios({
// url: 'http://123.207.32.32:8000/home/data',
// params: {
// type: 'sell',
// page: 5
// }
// })]).then(results => {
// console.log(results);
// console.log(results[0]);
// console.log(results[1]);
// })
Promise.all([axios({
url: 'http://123.207.32.32:8000/home/multidata'
}), axios({
url: 'http://123.207.32.32:8000/home/data',
params: {
type: 'sell',
page: 5
}
})]).then(axios.spread((res1, res2) => {
console.log(res1);
console.log(res2);
}))
全局配置
在上面的示例中,我们的BaseURL是固定的
- 事实上,在开发中可能很多参数都是固定的。
- 这个时候我们可以进行一些抽取,也可以利用axios的全局配置
// 使用全局的axios和对应的配置在进行网络请求
axios.defaults.baseURL = 'http://123.207.32.32:8000'
axios.defaults.timeout = 5000
Promise.all([axios({
url: '/home/multidata'
}), axios({
url: '/home/data',
params: {
type: 'sell',
page: 5
}
})]).then(axios.spread((res1, res2) => {
console.log(res1);
console.log(res2);
}))
常见的配置选项

axios的实例

axios封装

如何使用拦截器

项目

fastclick-解决移动端300ms延迟
fastclick-解决移动端300ms延迟:
安装:npm install fastclick --save
图片懒加载-vue-lazyload框架
安装: npm install vue-lazyload --save
代码示例:

========================================
本地应用
内容绑定,事件绑定
v-text
设置标签的文本值(textContent)
- v-text指令的作用是:设置标签的内容(textContent)
- 默认写法会替换全部部分,使用差值表达式{{}} 可以替换指定内容
- 内部支持写表达式
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2 v-text="message +'!'">深圳</h2>
<h2 v-text="info +'!'">深圳</h2>
<h2>{{message +'!'}}深圳</h2>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
message: "易烊千玺!!",
info: "前端开发"
}
})
</script>
</body>
</html>
v-html
设置标签的innerHTML
- v-html指令的作用是:设置元素的innerHTML
- 内容中有html结构会被解析为标签
- v-text指令无论内容是什么,只会解析为文本
- 解析文本使用v-text,需要解析html结构使用v-html
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p v-html="content"></p>
<p v-text="content"></p>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
// content: "易烊千玺"
content: "<a href='#'>yyqx</a>"
}
})
</script>
</body>
</html>
v-on基础
为元素绑定事件
- v-on指令的作用是:为元素绑定事件
- 事件名不需要写 on
- 指令可以简写为 @
- 绑定的方法定义在methods属性中
- 方法内部通过this关键字可以访问定义在data中数据
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="v-on指令" v-on:click="doIt">
<input type="button" value="v-on简写" @click="doIt">
<input type="button" value="双击事件" @dblclick="doIt">
<h2 @click="changeFood">{{food}}</h2>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
food: "番茄炒蛋"
},
methods: {
doIt: function () {
alert("做IT");
},
changeFood: function () {
this.food += "好好吃!"
}
},
})
</script>
</body>
</html>
本地应用-计数器
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div class="input-num">
<button @click="sub">-</button>
<span>{{num}}</span>
<button @click="add">+</button>
</div>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
num: 1
},
methods: {
add: function () {
if (this.num < 10) {
this.num++;
} else {
alert('别点了最大了');
}
},
sub: function () {
if (this.num > 0) {
this.num--;
} else {
alert('别点了最小了');
}
}
}
})
</script>
</body>
</html>
显示切换,属性绑定
v-show
- v-show指令的作用是:根据真假切换元素的显示状态
- 原理是修改元素的display,实现显示隐藏
- 指令后面的内容,最终都会解析为布尔值
- 值为true元素显示,值为false元素隐藏
- 数据改变之后,对应元素的显示状态会同步更新
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="切换显示状态" @click="changeIsShow">
<input type="button" value="累加年龄" @click="addAge">
<br>
<img v-show="isShow" src="images/yyqx.jpg" alt="">
<img v-show="age>=18" src="images/yyqx.jpg" alt="">
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
isShow: false,
age: 17
},
methods: {
changeIsShow: function () {
this.isShow = !this.isShow;
},
addAge: function () {
this.age++;
}
}
})
</script>
</body>
</html>
v-if
- v-if指令的作用是:根据表达式的真假切换元素的显示状态(操作dom元素)
- 本质是通过操纵dom元素来切换显示状态
- 表达式的值为true,元素存在与dom树中,为false,从dom树中移除
- 频繁的切换v-show,反之使用v-if,前者的切换消耗小
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="切换显示" @click="toggleIsShow">
<p v-if="isShow">易烊千玺</p>
<p v-show="isShow">易烊千玺-v-show修饰</p>
<h2 v-if="temperature>=35">热si了</h2>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
isShow: false,
temperature: 20
},
methods: {
toggleIsShow: function () {
this.isShow = !this.isShow;
}
}
})
</script>
</body>
</html>
v-bind
设置元素的属性(比如:src,title,class)
- v-bind指令的作用是:为元素绑定属性
- 完整的写法是v-bind:属性名
- 简写的话可以直接省略v-bind,只保留 :属性名
- 需要动态的增删class建议使用对象的方法
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.active {
border: 1px solid red;
}
</style>
</head>
<body>
<div id="app">
<img v-bind:src="imgSrc" alt="">
<br>
<!-- 简写 -->
<img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="isActive?'active':''" @click="toggleActive">
<br>
<img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class={active:isActive} @click="toggleActive">
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
imgSrc: "images/yyqx1.jpg",
imgTitle: "易烊千玺",
isActive: false
},
methods: {
toggleActive: function () {
this.isActive = !this.isActive;
}
}
})
</script>
</body>
</html>
本地应用-图片切换(轮播图)
代码笔记:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="mask">
<div class="center">
<h2 class="title">
<!-- <img src="images/yyqx1.jpg" alt=""> -->
</h2>
<!-- 图片 -->
<img :src="imgArr[index]" alt="" class="y1">
<!-- 左箭头 -->
<a href="javascript:void(0)" v-show="index!=0" @click="prev" class="left">
<img src="images/jiantou.png" alt="">
</a>
<!-- 右箭头 -->
<a href="javascript:void(0)" v-show="index<imgArr.length-1" @click="next" class="right">
<img src="images/jiantou.png" alt="">
</a>
</div>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#mask",
data: {
imgArr: ["images/yyqx1.jpg", "images/yyqx2.jpg", "images/yyqx3.jpg", "images/yyqx4.jpg", "images/yyqx5.jpg"],
index: 0
},
methods: {
prev: function () {
this.index--;
},
next: function () {
this.index++;
}
}
})
</script>
</body>
</html>
列表循环,表单元素绑定
v-for
- v-for指令的作用是:根据数据生成列表结构
- 数组经常和v-for结合使用
- 语法是 (item.index) in 数据
- item和index可以结合其他指令一起使用
- 数组长度的更新会同步到页面上,是响应式的
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="botton" value="添加数据" @click="add">
<input type="botton" value="移除数据" @click="remove">
<ul>
<li v-for="(item,index) in arr">
{{index + 1}}易烊千玺易烊千玺{{item}}
</li>
</ul>
<h2 v-for="item in vegetables" v-bind:title="item.name">
{{item.name}}
</h2>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
arr: ["哈哈", "零零", "星星", "取取"],
vegetables: [
{ name: "西兰花炒蛋" },
{ name: "蛋炒西兰花" }
]
},
methods: {
add: function () {
this.vegetables.push({ name: "花菜炒蛋" })
},
remove: function () {
this.vegetables.shift();
}
},
})
</script>
</body>
</html>
v-on补充
- 事件绑定的方法写成函数调用的形式,可以传入自定义参数
- 定义方法时需要定义形参来接受传入的实参
- 事件的后面跟上 .修饰符 可以对事件进行限制
- .enter 可以限制触发的按键为回车
- 事件修饰符有多种
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="点击" @click="doIt(666,'真帅')">
<input type="text" @keyup.enter="sayHi">
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
methods: {
doIt: function (p1, p2) {
console.log('易烊千玺');
console.log(p1);
console.log(p2);
},
sayHi: function () {
alert('吃了没');
}
},
})
</script>
</body>
</html>
v-model
获取和设置表单元素的值(双向数据绑定)
- v-model指令的作用是便捷的设置和获取表单元素的值
- 绑定的数据会和表单元素的值相关联
- 绑定的数据 <-------> 表单元素的值 (双向绑定)
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="修改message" @click="setM">
<input type="text" v-model="message" @keyup.enter="getM">
<h2>{{ message }}</h2>
</div>
<script src="vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
message: "易烊千玺"
},
methods: {
getM: function () {
alert(this.message);
},
setM: function () {
this.message = "zbc";
}
},
})
</script>
</body>
</html>
v-pre
v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
示例:
<p>{{ message }}</p> 输出:Hello World
<p v-pre>{{ message }}</p> 输出:{{ message }}
message='Hello World'
网络应用
axios基本使用
- axios必须先导入才可以使用
- 使用 get 或 post 方法即可发送对应的请求
- then方法中的回调函数会在请求成功或失败时触发
- 通过回调函数的形参可以获取响应内容,或错误信息
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="button" value="get请求" class="get">
<input type="button" value="post请求" class="post">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
// 接口1:随机笑话
document.querySelector(".get").onclick = function () {
axios.get("https://autumnfish.cn/api/joke/list?num=6")
// axios.get("https://autumnfish.cn/api/joke/list1234?num=6")
.then(function (response) {
console.log(response);
}, function (err) {
console.log(err);
})
}
// 接口2:用户注册
document.querySelector(".post").onclick = function () {
axios.post("https://autumnfish.cn/api/user/reg", { username: "易烊千玺.." })
.then(function (response) {
console.log(response);
}, function (err) {
console.log(err);
})
}
</script>
</body>
</html>
axios加vue
- axios 回调函数中的 this 已经改变,无法访问到 data 中数据
- 把 this 保存起来,回调函数中直接使用保存的 this 即可
- 和本地应用的最大区别就是改变了数据来源
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="获取笑话" @click="getJoke">
<p>{{ joke }}</p>
</div>
<!-- 官网提供的 axios 在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="vue.js"></script>
<script>
// 接口:随机获取一条笑话
// 请求地址:https://autumnfish.cn/api/joke
// 请求方法:get
// 请求参数:无
// 响应内容:随机笑话
var app = new Vue({
el: "#app",
data: {
joke: "很好笑的笑话"
},
methods: {
getJoke: function () {
// console.log(this.joke);
var that = this;
axios.get("https://autumnfish.cn/api/joke").then
(function (response) {
// console.log(response);
console.log(response.data);
// console.log(this.joke);
that.joke = response.data;
}, function (err) { })
}
}
})
</script>
</body>
</html>
综合应用
音乐播放器:

模板.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>悦听player</title>
<!-- 样式 -->
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div class="wrap">
<!-- 播放器主体区域 -->
<div class="play_wrap" id="player">
<div class="search_bar">
<img src="images/player_title.png" alt="" />
<!-- 搜索歌曲 -->
<input type="text" autocomplete="off" v-model="query" @keyup.enter="searchMusic" />
</div>
<div class="center_con">
<!-- 搜索歌曲列表 -->
<div class='song_wrapper'>
<ul class="song_list">
<li v-for="item in musicList">
<a href="javascript:;" @click="playMusic(item.id)"></a>
<b>{{item.name}}</b>
<span v-if="item.mvid!=0" @click="playMV(item.mvid)"><i></i></span>
</li>
</ul>
<img src="images/line.png" class="switch_btn" alt="">
</div>
<!-- 歌曲信息容器 -->
<div class="player_con" :class="{playing:isPlaying}">
<img src="images/player_bar.png" class="play_bar" />
<!-- 黑胶碟片 -->
<img src="images/disc.png" class="disc autoRotate" />
<img :src="musicCover" class="cover autoRotate" />
</div>
<!-- 评论容器 -->
<div class="comment_wrapper">
<h5 class='title'>热门留言</h5>
<div class='comment_list'>
<dl v-for="item in hotComments">
<dt><img :src="item.user.avatarUrl" alt=""></dt>
<dd class="name">{{item.user.nickname}}</dd>
<dd class="detail">
{{item.content}}
</dd>
</dl>
</div>
<img src="images/line.png" class="right_line">
</div>
</div>
<div class="audio_con">
<audio ref='audio' @play="play" @pause="pause" :src="musicUrl" controls autoplay loop class="myaudio"></audio>
</div>
<div class="video_con" v-show="isShow" style="display: none;">
<video :src="mvUrl" controls="controls"></video>
<div class="mask" @click="hide"></div>
</div>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 官网提供的 axios 在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="./js/main0.js"></script>
</body>
</html>
main0.js
/*
1:歌曲搜索接口
请求地址:https://autumnfish.cn/search
请求方法:get
请求参数:keywords(查询关键字)
响应内容:歌曲搜索结果
2:歌曲url获取接口
请求地址:https://autumnfish.cn/song/url
请求方法:get
请求参数:id(歌曲id)
响应内容:歌曲url地址
3.歌曲详情获取
请求地址:https://autumnfish.cn/song/detail
请求方法:get
请求参数:ids(歌曲id)
响应内容:歌曲详情(包括封面信息)
4.热门评论获取
请求地址:https://autumnfish.cn/comment/hot?type=0
请求方法:get
请求参数:id(歌曲id,地址中的type固定为0)
响应内容:歌曲的热门评论
5.mv地址获取
请求地址:https://autumnfish.cn/mv/url
请求方法:get
请求参数:id(mvid,为0表示没有mv)
响应内容:mv的地址
*/
var app = new Vue({
el: "#player",
data: {
query: "",
//歌曲数组
musicList: [],
//歌曲地址
musicUrl: "",
//歌曲方面
musicCover: "",
//歌曲评论
hotComments: [],
//动画播放状态
isPlaying: false,
//遮罩层的显示状态
isShow: false,
//mv地址
mvUrl: ""
},
methods: {
//歌曲搜索
searchMusic: function () {
var that = this;
axios.get("https://autumnfish.cn/search?keywords=" + this.query)
// axios.get("https://v1.alapi.cn/api/music/search?keywords=" + this.query)
.then(function (response) {
// console.log(response);
that.musicList = response.data.result.songs;
console.log(response.data.result.songs);
}, function (err) { })
},
//歌曲播放
playMusic: function (musicId) {
var that = this;
// console.log(musicId);
axios.get("https://autumnfish.cn/song/url?id=" + musicId)
.then(function (response) {
// console.log(response);
// console.log(response.data.data[0].url);
that.musicUrl = response.data.data[0].url;
}, function (err) { })
//歌曲需求获取
axios.get("https://autumnfish.cn/song/detail?ids=" + musicId)
.then(function (response) {
// console.log(response);
console.log(response.data.songs[0].al.picUrl);
that.musicCover = response.data.songs[0].al.picUrl;
}, function (err) { })
//歌曲评论获取
axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + musicId)
.then(function (response) {
// console.log(response);
console.log(response.data.hotComments);
that.hotComments = response.data.hotComments;
}, function (err) { })
},
//歌曲播放
play: function () {
// console.log("play");
this.isPlaying = true;
},
//歌曲暂停
pause: function () {
// console.log("pause");
this.isPlaying = false;
},
//播放mv
playMV: function (mvid) {
var that = this;
axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
.then(function (response) {
// console.log(response);
console.log(response.data.data.url);
that.isShow = true;
that.mvUrl = response.data.data.url;
}, function (err) { })
},
//隐藏
hide: function () {
this.isShow = false;
this.mvUrl = "";
}
}
})
32万+

被折叠的 条评论
为什么被折叠?



