前言
Vue 是一个渐进式的 JavaScript 框架,用于构建用户界面。它的核心库专注于视图层,使得 Vue 易于上手且便于与第三方库或既有项目整合。Vue 的设计允许开发者从简单的组件开始,逐步构建到复杂的前端应用程序。它采用组件化、模板语法、响应式数据绑定和虚拟 DOM 等核心概念,使得开发人员可以更轻松地构建和维护复杂的应用程序。Vue 的生态系统非常强大,拥有许多第三方库和插件,可以解决各种问题和扩展 Vue 的功能。
Vue 的优点包括:
- 轻量级框架,只关注视图层,易于学习和使用。
- 双向数据绑定,保留了 Angular 的特点,在数据操作方面更为简单。
- 组件化,实现了 HTML 的封装和重用,在构建单页面应用方面有着独特的优势。
- 视图、数据、结构分离,使得数据变得更为简单,不需要进行逻辑代码修改,只需要操作数据就可以完成相关操作。
- 虚拟 DOM,极大解放了 DOM 操作,提高了性能。
要开始学习 Vue,首先需要掌握 HTML 和 CSS、JavaScript 基础知识,包括 ES6+ 特性。此外,熟悉前端开发工具如 VSCode、Node.js 和 Git 也很有帮助。Vue 的官方文档和在线教程是深入学习 Vue 的重要资源。
Vue.js - 渐进式 JavaScript 框架 | Vue.jsVue.js - 渐进式的 JavaScript 框架https://cn.vuejs.org/
1,hello.vue
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue学习</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style type="text/css">
.box{
width: 200px;
height: 200px;
background-color: aquamarine;
}
</style>
</head>
<body>
<!-- 容器 -->
<!-- 第一层 -->
<div id="box">
<h1>第一个:{{msg}}</h1>
</div>
</body>
<script type="text/javascript">
//一个Vue对象管理一个容器
//id一般给javascript使用 class给样式使用
//生产模式Vue:没有错误提示,代码被压缩。
//开发者模式Vue:是有错误提示,没有被压缩的。
//关掉开发环境的警告
Vue.config.productionTip = false;
/*
var 经常使用 没有值的时候输出 undefined
let 块级变量方法内不受影响
const 必须给一个初始化的值
*/
const v = new Vue({
el:'#box',
data:{
msg:'Hello Vue'
}
});
</script>
</html>
2,插值语法和指令语法的基本使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>插值语法和指令语法</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1>插值语法</h1>
<h3>你好:{{name}}</h3>
<h1>指令语法</h1>
<a v-bind:href="webUrl">{{webName}}</a>
<a href="#" v-bind:del="del">删除</a>
<a href="" :chage="chage">修改</a>
<!--
指令语法的两种写法:
v-bind:属性="data的key"
:属性="data的key"
-->
<h3>ID:{{user.id}} 姓名:{{user.name}} 性别:{{user.sex}}</h3>
</div>
<!--
为什么Script的标签会放在body结束标签之前?
一、避免堵塞
二、HTML2.0起放在</body>下是不符合标准的
-->
<script type="text/javascript">
//关掉开发环境的警告
Vue.config.productionTip = false;
const v = new Vue({
el:'#box',
data:{
name:'张三',
webName:'百度',
webUrl:"http://www.baidu.com",
del:"101",
chage:"101",
user:{
id:1,
name:'张三',
sex:'男'
}
}
});
</script>
</body>
</html>
3, 数据绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>数据绑定</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1>单项数据绑定</h1>
用户名:<input type="text" name="name" v-bind:value="name"/><br>
<h1>双向数据绑定</h1>
用户名:<input type="text" name="name" v-model:value="name"/><br>
<!-- 注意:v-model 只能用在表单元素上 -->
<!--
单项绑定:
v-bind 或 :
双向绑定
v-model:value 或 v-model
-->
<!-- 以下是这两个的简写方式 -->
<h1>单项数据绑定</h1>
用户名:<input type="text" name="name" :value="name"/><br>
<h1>双向数据绑定</h1>
用户名:<input type="text" name="name" v-model="name"/><br>
</div>
<script type="text/javascript">
/*
const v = new Vue({
data:{
name:'张三'
}
});
*/
//目前两种都可以,学到组件过后只能用这种
const v = new Vue({
data:function(){
return{
name:'张三'
}
}
});
//ES6函数写法
setTimeout(() => {
//手动挂载
v.$mount("#box");
},3000);
/* setTimeout(function(){
},3000); */
</script>
</body>
</html>
4,MVVM
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MVVM</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1>你好{{name}}</h1>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
name:'张三'
}
})
console.log(vm);
</script>
</body>
</html>
5,数据代理
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue - 数据代理</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<script type="text/javascript">
Vue.config.productionTip = false;
let user = {
age:18,
name:'张三'
}
let rSex = "男";
//不可修改
Object.defineProperty(user,'sex',{
//value:'男', 不能和set get同时使用
//writable:true, //设置值是否可修改 默认false 不能和set get 同时使用
configurable:true,//设置属性是否可删除 默认false
enumerable:true,//设置属性是否可枚举 默认false
get:()=>{
//console.log("有人在读值");
return rSex;
},
set:(value)=>{
rSex = value;
}
})
//循环枚举
for(let key in user){
console.log(user[key]);
}
setTimeout(()=>{
rSex = "女";
},3000);
console.log(user);
</script>
</body>
</html>
6,插值语法高级
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue插值语法2</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1>你好{{name}}</h1>
<h1>{{1+1}}</h1>
<h1>{{1==1}}</h1>
<h1>{{$options}}</h1>
<!--
插值语法:
可以进行算术运算,可以进行判断,插值语法实际上找的就是vm,vm里面有什么这里就可以放什么。
-->
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
name:'张三'
}
})
console.log(vm);
</script>
</body>
</html>
7,点击事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue的点击事件</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
.myul{
width: 300px;
height: 90px;
overflow-y: auto;
}
.myul > li{
width: 100%;
height: 20px;
}
.myul > li:nth-child(odd){
background-color: coral;
}
</style>
</head>
<body>
<div id="box">
<h1 v-on:click="msg">你点我试试</h1>
<button type="button" @click="deleteUser(1001,$event)">删除</button><br>
<a href="http://www.baidu.com" @click.prevent="baiduMsg">阻止默认行为</a><br><br><br><br>
<div @click="msg2" style="width: 300px;height: 200px;background-color: aquamarine;">
<button type="button" @click.stop="msg1">阻止事件冒泡</button>
</div><br>
<button type="button" @click.once="delete2">删除2(只执行一次)</button>
<ul class="myul" @scroll="mywhell">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
</ul>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
methods:{
msg(){
alert("试试就试试");
},
deleteUser(uid,event){
alert("删除成功"+1001);
console.log(event);
},
baiduMsg(){
alert("点击了百度");
},
msg1(){
alert("消息1触发");
},
msg2(){
alert("消息2触发");
},
delete2(){
alert("我被删除了");
},
mywhell(){
console.log("正在滚动");
}
}
})
</script>
</body>
</html>
8,键盘事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>键盘事件</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<input type="text" placeholder="请输入用户名" @keydown="userName"/><br>
<!-- 自定义别名 -->
<input type="text" placeholder="自定义别名" @keydown.caps-lock="capsLock"><br>
<!-- 组合按键 -->
<input type="text" placeholder="组合按键" @keydown.ctrl.s="save">
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
methods:{
userName(e){
console.log(e.key,e.keyCode);
},
capsLock(){
console.log("你打开了大小写");
},
save(){
console.log("保存成功");
}
}
})
</script>
</body>
</html>
9,小练习
a,插值语法实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>插值语法实现</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
姓名:<input type="text" v-model="name"><br>
公司:<input type="text" v-model="company"><br>
<h2>{{name}}@{{company}}.com</h2>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
name:'',
company:''
}
})
</script>
</body>
</html>
b,方法实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>通过方法实现</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
姓名:<input type="text" v-model="name"><br>
公司:<input type="text" v-model="company"><br>
<h2>{{email()}}</h2>
<h2>{{email()}}</h2>
<h2>{{email()}}</h2>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
name:'',
company:''
},
methods:{
email(){
console.log("执行");
return this.name + "@" + this.company + ".com";
}
}
})
</script>
</body>
</html>
10,计算属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>计算属性</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
姓名:<input type="text" v-model="name"><br>
公司:<input type="text" v-model="company"><br>
<h2>{{email}}</h2>
<h2>{{email}}</h2>
<h2>{{email}}</h2>
</div>
<script>
/*
计算属性:
多处调用只会执行一次,用方法会执行多次,使用计算属性可以提高代码运行效率。
和methods相比最大的好处是计算属性有缓存
*/
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
name:'',
company:''
},
computed:{
email:{
//当有人使用email这个属性时调用
get(){
console.log("执行")
return this.name + "@" + this.company + ".com";
}
}
}
})
</script>
</body>
</html>
11,计算属性的简写
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>计算属性的简写</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
姓名:<input type="text" v-model="name"><br>
公司:<input type="text" v-model="company"><br>
<h2>{{email}}</h2>
<h2>{{email}}</h2>
<h2>{{email}}</h2>
</div>
<script>
/*
计算属性:
多处调用只会执行一次,用方法会执行多次,使用计算属性可以提高代码运行效率。
和methods相比最大的好处是计算属性有缓存
*/
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
name:'',
company:''
},
computed:{
email:function(){
console.log("执行")
return this.name + "@" + this.company + ".com";
}
}
})
</script>
</body>
</html>
12,天气案例-监视属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>监视属性</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<!-- 不推荐 -->
<!-- <h1>今天的天气是{{isHot ? '炎热' : '凉爽'}}</h1> -->
<!-- 计算属性实现 -->
<h1>今天的天气是{{weather}}</h1>
<button type="button" @click="change">切换天气</button>
<button type="button" @click="isHot = !isHot">切换天气简洁版</button>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
isHot:true
},
computed:{//计算属性
weather(){//属性名称
return this.isHot ? '炎热' : '凉爽';//返回值
}
},
methods:{
change(){
/* if(this.isHot){
this.isHot = false;
}else{
this.isHot = true;
} */
this.isHot = !this.isHot;
}
}
/* ,watch:{//监视属性
isHot:{//被监视的属性
handler(nv,ov){//nv 新值 ov 改之前的值
console.log("isHot被修改了");
console.log(nv,ov);
},
immediate:true//初始化就立即执行一次
}
} */
})
// 第二种监视属性打开方法
setTimeout(() =>{//5秒后开始监视
vm.$watch('isHot',{
handler(nv,ov){//nv 新值 ov 改之前的值
console.log("isHot被修改了");
console.log(nv,ov);
}
})
},5000);
</script>
</body>
</html>
13,深度监视
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>深度监视</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1>{{number.a}}</h1>
<button type="button" @click="number.a++">number增加</button>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
number:{
a:1,
b:5
}
}
,watch:{//监视属性
/* 'number.a':{//被监视的属性
handler(nv,ov){//nv 新值 ov 改之前的值
console.log("number被修改了");
console.log(nv,ov);
}
}, */
number:{
deep:true,//深度监视的开启,监视多级属性中所有的属性发生变化
//缺点:只能获取属性值改变之后的值,获取不了改变之前的值
handler(nv,ov){//nv 新值 ov 改之前的值
console.log("number被修改了");
console.log(nv,ov);
}
}
}
})
</script>
</body>
</html>
14,样式绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>样式绑定</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style type="text/css">
.ball{
width: 200px;
height: 200px;
background-color: aquamarine;
}
.ballRadius{
border-radius: 50%;
}
.ballAlign{/* 文本左右居中 */
text-align: center;
font-size: 35px;
}
.ballLine{/* 文本上下居中 */
line-height: 200px;
color: azure;
}
</style>
</head>
<body>
<div id="box">
<!-- 样式绑定第一种方式 :class 单个属性 -->
<div class="ball" :class="ballRadius">
{{ball}}
</div>
<!-- 样式绑定第二种方式 :class 数组-->
<div class="ball" :class="ballStyle">
{{ball}}
</div>
<!-- 样式绑定第三种方式 :class 对象 true 和 false 控制样式的加载和移除 -->
<div class="ball" :class="ballObj" @click="ballObj.ballRadius = !ballObj.ballRadius">
{{ball}}
</div>
<!-- 样式绑定第四种方式 :style -->
<div class="ball" :class="ballObj" :style="ballColor">
{{ball}}
</div>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
ball:'这是一个球',
ballRadius:'ball-radius',//单样式
ballStyle:['ballRadius','ballAlign','ballLine'],//多样式
ballObj:{
ballRadius:true,
ballAlign:true,
ballLine:true
},
ballColor:{
color: 'green',
'font-size': '20px'
}
}
})
</script>
</body>
</html>
15,条件渲染
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>条件渲染</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<!-- v-show 做条件渲染 -->
<div v-show="false">第一个{{ball}}</div>
<div v-show="1===1">第二个{{ball}}</div>
<!-- v-if 做条件渲染 -->
<!-- v-if移除代码 v-show隐藏代码 -->
<div v-if="false">第三个{{ball}}</div>
<!-- 练习一 v-show 完成-->
<h1 v-show="number === 1">Angualr</h1>
<h1 v-show="number === 2">React</h1>
<h1 v-show="number === 3">Vue</h1>
<button type="button" @click="number++">切换</button>
<!-- 练习二 if 完成-->
<h1 v-if="number === 1">Angualr</h1>
<h1 v-else-if="number === 2">React</h1>
<h1 v-else-if="number === 3">Vue</h1>
<h1 v-else>都不会</h1>
<button type="button" @click="number++">切换</button>
<!--
注意:
变化频率大使用show频率小使用if if会不停在Dom中进行增删
-->
<!-- template 模板的意思,本身是不显示的,只会在渲染时起作用 -->
<!-- template 只能配合v-if使用 -->
<template v-if="number === 4">
<h1>Angualr</h1>
<h1>React</h1>
<h1>Vue</h1>
</template>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
ball:'球',
number:1
}
})
</script>
</body>
</html>
16,列表渲染
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>列表渲染</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<ul>
<li v-for="u in userList">
id:{{u.id}} 姓名:{{u.name}} 年龄:{{u.age}}
</li>
</ul>
<!-- 显示序号 -->
<ul>
<li v-for="(u,index) in userList">
序号:{{index+1}} 姓名:{{u.name}} 年龄:{{u.age}}
</li>
</ul>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
userList:[
{id:'1001',name:'张三',age:18},
{id:'1002',name:'李四',age:28},
{id:'1003',name:'王五',age:38}
]
}
})
</script>
</body>
</html>
17,key的原理
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>key的原理</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<ul>
<li v-for="u in userList" :key="u.id">
姓名:{{u.name}} 年龄:{{u.age}}
<input type="text" />
</li>
</ul>
<button type="button" @click="addUser">添加数据</button>
</div>
<script>
//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
//key一般使用数据的id
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
userList:[
{id:'1001',name:'张三',age:18},
{id:'1002',name:'李四',age:28},
{id:'1003',name:'王五',age:38}
]
},
methods:{
addUser(){
var u = {id:'1004',name:'赵六',age:48};
//添加数据(前面追加)
//this.userList.unshift(u);
//添加数据(后面追加)
this.userList.push(u);
}
}
})
</script>
</body>
</html>
18,音乐搜索案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>音乐搜索案例</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
搜索: <input type="text" v-model="searchValue">
<ul>
<li v-for="m in searchList" :key="m.id">
<div style='width:200px;float: left;'>
音乐:{{m.name}}
</div>
<div style='width:200px;float: left;'>
歌手:{{m.sname}}
</div>
</li>
</ul>
</div>
<script>
//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
//key一般使用数据的id
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
searchValue:'',//用户搜索
musicList:[],//数据
searchList:[]//搜索结果
}
})
vm.musicList = [
{id:'1', name:'想唱就唱',sname:'张含韶'}
,{id:'2', name:'冰点与沸点',sname:'张含韶'}
,{id:'3', name:'夕阳无限好',sname:'陈奕迅'}
,{id:'4', name:'爱的证明',sname:'沈建祥'}
,{id:'5', name:'刻下纹身之后' ,sname:'小鸣'}
,{id:'6', name:'双面人' ,sname:'伍佰'}
,{id:'7', name:'长情' ,sname:'黎明'}
,{id:'8', name:'我得你' ,sname:'张学友'}
,{id:'9', name:'人人望放假' ,sname:'张学友'}
,{id:'10', name:'太平洋的风' ,sname:'胡德夫'}
,{id:'11', name:'吻下留人' ,sname:'许志安'}
,{id:'12', name:'顺时针' ,sname:'梁咏琪'}
,{id:'13', name:'回来我的爱' ,sname:'阳一'}
,{id:'14', name:'两只蝴蝶' ,sname:'庞龙'}
,{id:'15', name:'老鼠爱大米' ,sname:'杨臣刚'}
,{id:'16', name:'丁香花' ,sname:'唐磊'}
,{id:'17', name:'爱你' ,sname:'冷草莓'}
,{id:'18', name:'美梦成真' ,sname:'冷草莓'}
,{id:'19', name:'老鼠爱大米' ,sname:'huanggm2'}
,{id:'20', name:'谢谢你的爱1999' ,sname:'cznana'}
,{id:'21', name:'老鼠爱大米' ,sname:'英文版'}
,{id:'22', name:'猪之歌' ,sname:'香香'}
,{id:'23', name:'“吻别”英文版' ,sname:'Michael..'}
,{id:'24', name:'别说我的眼泪你无..' ,sname:'东来东往'}
,{id:'25', name:'追杀邱比特' ,sname:'蔡依林'}
,{id:'26', name:'被风吹过的夏天' ,sname:'金莎'}
,{id:'27', name:'你到底爱谁' ,sname:'刘嘉亮'}
,{id:'28', name:'六月的雨' ,sname:'胡歌'}
,{id:'29', name:'酸酸甜甜就是我' ,sname:'张含韵'}
,{id:'30', name:'你好,周杰伦' ,sname:'安又淇'}
,{id:'31', name:'江南' ,sname:'林俊杰'}
,{id:'32', name:'情人' ,sname:'刀郎'}
,{id:'33', name:'两只蝴蝶' ,sname:'庞龙'}
,{id:'34', name:'2002年的第一场雪' ,sname:'刀郎'}
,{id:'35', name:'看我七十二变' ,sname:'蔡依林'}
,{id:'36', name:'恭喜发财' ,sname:'刘德华'}
,{id:'37', name:'童话' ,sname:'光良'}
,{id:'38', name:'寓言' ,sname:'张韶涵'}
,{id:'39', name:'宁夏' ,sname:'梁静茹'}
,{id:'40', name:'断点' ,sname:'张敬轩'}
,{id:'41', name:'快乐崇拜' ,sname:'潘玮柏'}
,{id:'42', name:'一首简单的歌' ,sname:'王力宏'}
,{id:'43', name:'孤单北半球' ,sname:'欧得洋'}
,{id:'44', name:'十年' ,sname:'陈奕迅'}
,{id:'45', name:'男人海洋' ,sname:'周传雄'}
,{id:'46', name:'挥着翅膀的女孩' ,sname:'容祖儿'}
,{id:'47', name:'我们的爱' ,sname:'F.I.R'}
,{id:'48', name:'第一次爱的人' ,sname:'王心凌'}
];
//监视属性
vm.$watch('searchValue',function(nv){
//console.log("用户搜索"+nv);
//filter会把数据进行循环,如果为false则会移除数据,为true保留数据,最终返回一个集合。
this.searchList = this.musicList.filter((p) => {//ES6
if(p.name.indexOf(nv) !== -1){//包含
return true;
}else{
return false;
}
});
},{
//初始化执行一次
immediate:true,
});
</script>
</body>
</html>
19,音乐播放案例(带排序)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>音乐搜索案例</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
搜索: <input type="text" v-model="searchValue">
<button @click="sortType = !sortType">排序</button>
<ul>
<li v-for="m in searchList" :key="m.id">
<div style='width:300px;float: left;'>
ID :{{m.id}}音乐:{{m.name}}
</div>
<div style='width:300px;float: left;'>
歌手:{{m.sname}}
</div>
</li>
</ul>
</div>
<script>
//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
//key一般使用数据的id
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
searchValue:'',//用户搜索
musicList:[],//数据
searchList:[],//搜索结果
sortType:true//true代表升序false代表降序
}
})
vm.musicList = [
{id:'1', name:'想唱就唱',sname:'张含韶'}
,{id:'2', name:'冰点与沸点',sname:'张含韶'}
,{id:'3', name:'夕阳无限好',sname:'陈奕迅'}
,{id:'4', name:'爱的证明',sname:'沈建祥'}
,{id:'5', name:'刻下纹身之后' ,sname:'小鸣'}
,{id:'6', name:'双面人' ,sname:'伍佰'}
,{id:'7', name:'长情' ,sname:'黎明'}
,{id:'8', name:'我得你' ,sname:'张学友'}
,{id:'9', name:'人人望放假' ,sname:'张学友'}
,{id:'10', name:'太平洋的风' ,sname:'胡德夫'}
,{id:'11', name:'吻下留人' ,sname:'许志安'}
,{id:'12', name:'顺时针' ,sname:'梁咏琪'}
,{id:'13', name:'回来我的爱' ,sname:'阳一'}
,{id:'14', name:'两只蝴蝶' ,sname:'庞龙'}
,{id:'15', name:'老鼠爱大米' ,sname:'杨臣刚'}
,{id:'16', name:'丁香花' ,sname:'唐磊'}
,{id:'17', name:'爱你' ,sname:'冷草莓'}
,{id:'18', name:'美梦成真' ,sname:'冷草莓'}
,{id:'19', name:'老鼠爱大米' ,sname:'huanggm2'}
,{id:'20', name:'谢谢你的爱1999' ,sname:'cznana'}
,{id:'21', name:'老鼠爱大米' ,sname:'英文版'}
,{id:'22', name:'猪之歌' ,sname:'香香'}
,{id:'23', name:'“吻别”英文版' ,sname:'Michael..'}
,{id:'24', name:'别说我的眼泪你无..' ,sname:'东来东往'}
,{id:'25', name:'追杀邱比特' ,sname:'蔡依林'}
,{id:'26', name:'被风吹过的夏天' ,sname:'金莎'}
,{id:'27', name:'你到底爱谁' ,sname:'刘嘉亮'}
,{id:'28', name:'六月的雨' ,sname:'胡歌'}
,{id:'29', name:'酸酸甜甜就是我' ,sname:'张含韵'}
,{id:'30', name:'你好,周杰伦' ,sname:'安又淇'}
,{id:'31', name:'江南' ,sname:'林俊杰'}
,{id:'32', name:'情人' ,sname:'刀郎'}
,{id:'33', name:'两只蝴蝶' ,sname:'庞龙'}
,{id:'34', name:'2002年的第一场雪' ,sname:'刀郎'}
,{id:'35', name:'看我七十二变' ,sname:'蔡依林'}
,{id:'36', name:'恭喜发财' ,sname:'刘德华'}
,{id:'37', name:'童话' ,sname:'光良'}
,{id:'38', name:'寓言' ,sname:'张韶涵'}
,{id:'39', name:'宁夏' ,sname:'梁静茹'}
,{id:'40', name:'断点' ,sname:'张敬轩'}
,{id:'41', name:'快乐崇拜' ,sname:'潘玮柏'}
,{id:'42', name:'一首简单的歌' ,sname:'王力宏'}
,{id:'43', name:'孤单北半球' ,sname:'欧得洋'}
,{id:'44', name:'十年' ,sname:'陈奕迅'}
,{id:'45', name:'男人海洋' ,sname:'周传雄'}
,{id:'46', name:'挥着翅膀的女孩' ,sname:'容祖儿'}
,{id:'47', name:'我们的爱' ,sname:'F.I.R'}
,{id:'48', name:'第一次爱的人' ,sname:'王心凌'}
];
//监视属性
vm.$watch('searchValue',function(nv){
//console.log("用户搜索"+nv);
//filter会把数据进行循环,如果为false则会移除数据,为true保留数据,最终返回一个集合。
const arr = this.musicList.filter((p) => {//ES6
if(p.name.indexOf(nv) !== -1 || p.sname.indexOf(nv) !== -1){//包含
return true;
}else{
return false;
}
});
//排序
//sort如果返回p1-p2升序 如果返回p2-p1就是降序
arr.sort((p1,p2) => {
if(this.sortType){//升序
return p1.id-p2.id;
}else{//降序
return p2.id-p1.id;
}
});
//赋值
this.searchList = arr;
},{
//初始化执行一次
immediate:true,
});
</script>
</body>
</html>
20,音乐播放案例(计算属性实现)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>音乐搜索案例(计算属性)</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
搜索: <input type="text" v-model="searchValue">
<button @click="sortType = !sortType">排序</button>
<ul>
<li v-for="m in searchList" :key="m.id">
<div style='width:300px;float: left;'>
ID :{{m.id}}音乐:{{m.name}}
</div>
<div style='width:300px;float: left;'>
歌手:{{m.sname}}
</div>
</li>
</ul>
</div>
<script>
//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
//key一般使用数据的id
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
searchValue:'',//用户搜索
musicList:[],//数据
sortType:true//true代表升序false代表降序
},
computed:{//计算属性
searchList(){
//console.log("用户搜索"+nv);
//filter会把数据进行循环,如果为false则会移除数据,为true保留数据,最终返回一个集合。
const arr = this.musicList.filter((p) => {//ES6
if(p.name.indexOf(this.searchValue) !== -1 || p.sname.indexOf(this.searchValue) !== -1){//包含
return true;
}else{
return false;
}
});
//排序
//sort如果返回p1-p2升序 如果返回p2-p1就是降序
arr.sort((p1,p2) => {
if(this.sortType){//升序
return p1.id-p2.id;
}else{//降序
return p2.id-p1.id;
}
});
//赋值
return arr;
}
}
})
vm.musicList = [
{id:'1', name:'想唱就唱',sname:'张含韶'}
,{id:'2', name:'冰点与沸点',sname:'张含韶'}
,{id:'3', name:'夕阳无限好',sname:'陈奕迅'}
,{id:'4', name:'爱的证明',sname:'沈建祥'}
,{id:'5', name:'刻下纹身之后' ,sname:'小鸣'}
,{id:'6', name:'双面人' ,sname:'伍佰'}
,{id:'7', name:'长情' ,sname:'黎明'}
,{id:'8', name:'我得你' ,sname:'张学友'}
,{id:'9', name:'人人望放假' ,sname:'张学友'}
,{id:'10', name:'太平洋的风' ,sname:'胡德夫'}
,{id:'11', name:'吻下留人' ,sname:'许志安'}
,{id:'12', name:'顺时针' ,sname:'梁咏琪'}
,{id:'13', name:'回来我的爱' ,sname:'阳一'}
,{id:'14', name:'两只蝴蝶' ,sname:'庞龙'}
,{id:'15', name:'老鼠爱大米' ,sname:'杨臣刚'}
,{id:'16', name:'丁香花' ,sname:'唐磊'}
,{id:'17', name:'爱你' ,sname:'冷草莓'}
,{id:'18', name:'美梦成真' ,sname:'冷草莓'}
,{id:'19', name:'老鼠爱大米' ,sname:'huanggm2'}
,{id:'20', name:'谢谢你的爱1999' ,sname:'cznana'}
,{id:'21', name:'老鼠爱大米' ,sname:'英文版'}
,{id:'22', name:'猪之歌' ,sname:'香香'}
,{id:'23', name:'“吻别”英文版' ,sname:'Michael..'}
,{id:'24', name:'别说我的眼泪你无..' ,sname:'东来东往'}
,{id:'25', name:'追杀邱比特' ,sname:'蔡依林'}
,{id:'26', name:'被风吹过的夏天' ,sname:'金莎'}
,{id:'27', name:'你到底爱谁' ,sname:'刘嘉亮'}
,{id:'28', name:'六月的雨' ,sname:'胡歌'}
,{id:'29', name:'酸酸甜甜就是我' ,sname:'张含韵'}
,{id:'30', name:'你好,周杰伦' ,sname:'安又淇'}
,{id:'31', name:'江南' ,sname:'林俊杰'}
,{id:'32', name:'情人' ,sname:'刀郎'}
,{id:'33', name:'两只蝴蝶' ,sname:'庞龙'}
,{id:'34', name:'2002年的第一场雪' ,sname:'刀郎'}
,{id:'35', name:'看我七十二变' ,sname:'蔡依林'}
,{id:'36', name:'恭喜发财' ,sname:'刘德华'}
,{id:'37', name:'童话' ,sname:'光良'}
,{id:'38', name:'寓言' ,sname:'张韶涵'}
,{id:'39', name:'宁夏' ,sname:'梁静茹'}
,{id:'40', name:'断点' ,sname:'张敬轩'}
,{id:'41', name:'快乐崇拜' ,sname:'潘玮柏'}
,{id:'42', name:'一首简单的歌' ,sname:'王力宏'}
,{id:'43', name:'孤单北半球' ,sname:'欧得洋'}
,{id:'44', name:'十年' ,sname:'陈奕迅'}
,{id:'45', name:'男人海洋' ,sname:'周传雄'}
,{id:'46', name:'挥着翅膀的女孩' ,sname:'容祖儿'}
,{id:'47', name:'我们的爱' ,sname:'F.I.R'}
,{id:'48', name:'第一次爱的人' ,sname:'王心凌'}
];
</script>
</body>
</html>
21.html标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>html标签</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<p>{{text}}</p>
<p v-html="text"></p>
</div>
<script>
/* 百度富文本编辑器 http://fex.baidu.com/ueditor/*/
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
text:"<b>这里显示一些内容</b>"
}
})
</script>
</body>
</html>
22,Set方法的使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>set方法的使用</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1>{{user.age}}岁</h1>
<!-- v-if 不会显示标签 -->
<!-- v-show 会加上 display:none -->
<h1 v-if="user.sex">{{user.sex}}性</h1>
<button type="button" @click="user.age++">增加年龄</button>
<button @click="addSex">添加性别为男性</button>
</div>
<script>
//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
//key一般使用数据的id
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
user:{
age:1
}
},
methods:{
addSex(){
//vm.sex = "男";
/* 追加的对象 对象名 值 */
Vue.set(vm.user,'sex','男');
//vue不允许动态添加根级别的响应式数据
//Vue.set(vm,'money',100);
}
}
})
console.log(vm);
</script>
</body>
</html>
23,性能优化
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>性能优化</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<p>{{text}}</p>
<p v-html="text"></p>
<!-- v-pre跳过编译 -->
<div v-pre v-show="false">
<h1>{{text}}</h1>
<h1>{{text}}</h1>
<h1>{{text}}</h1>
</div>
{{text}}
{{text}}
{{text}}
</div>
<script>
/* 百度富文本编辑器 http://fex.baidu.com/ueditor/*/
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
text:"<b>这里显示一些内容</b>"
}
})
</script>
</body>
</html>
24,自定义指令 - 全局
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>自定义指令</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1 v-my-title="title"></h1>
<h2 v-my-title>这个也想居中</h2>
</div>
<script>
/* 百度富文本编辑器 http://fex.baidu.com/ueditor/*/
Vue.config.productionTip = false;
//全局自定义指令
Vue.directive('my-title',function(el, binding){
//文字颜色
el.style.color = "red";
//文本居中
el.style.textAlign = "center";
if(binding.value.length > 0){//如果有内容才添加内容
//内容
//el.innerText = "新华社:"+binding.value;
//添加内容
el.innerHTML = "新华社:"+binding.value + "<hr>";
}
});
const vm = new Vue({
el:'#box',
data:{
title:"《人民的名义》总监制李学政:王立科曾想让该剧停播"
}
})
</script>
</body>
</html
25,自定义指令 - 局部
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>局部 - 自定义指令</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1 v-my-title="title"></h1>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
title:"国庆节快乐"
},
directives:{//directives不要忘记加s
'my-title':{
bind(el, binding){
//让文字从右往左显示
//split("") 字符串转数组
//reverse() 数组倒叙排序
//join("") 数组转字符串
el.innerHTML = binding.value.split("").reverse().join("");
}
}
}
})
</script>
</body>
</html>
26,Vue的生命周期(一)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue的生命周期(一)</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1 :style="{opacity}">渐变效果</h1>
{{change()}}
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
opacity:1
},
methods:{
change(){
console.log("我执行了");
setInterval(() =>{
this.opacity -= 0.1;
if(this.opacity <= 0){
this.opacity = 1;
}
},1000);
}
}
})
</script>
</body>
</html>
27,Vue的生命周期(二)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue的生命周期(二)</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1 :style="{opacity}">渐变效果</h1>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#box',
data:{
opacity:1
},
methods:{
},
mounted(){//页面上所有的DOM元素渲染完成之后调用
console.log("我执行了");
setInterval(() =>{
/* this.opacity -= 0.1;
if(this.opacity <= 0){
this.opacity = 1;
} */
this.opacity <= 0 ? this.opacity=1 : this.opacity -= 0.1;
},100);
}
})
</script>
</body>
</html>
28,组件的基本使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>组件的基本使用</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<ntitle></ntitle>
<ntitle></ntitle>
<ntitle></ntitle>
<ntitle></ntitle>
</div>
<script>
Vue.config.productionTip = false;
//通过组件的形式调用,创建标题
//1、创建组件
const ntitle = Vue.extend({
template:`
<div>
<h1>{{title}}</h1>
<h3>编辑:{{name}}</h3>
</div>
`,
data(){
return {
title:'科学家研究表明,不吃饭会饿。',
name:'张三'
}
}
})
const vm = new Vue({
el:'#box',
components:{//组件的注册
ntitle
}
})
</script>
</body>
</html>