这是一个vue笔记, 来自网络, 做了一些修改和说明, 增加了效果. 为了方便查看学习.
注意:
1 v-if放在这有点问题, 修改了代码.
2 图片用网图, 有些图片浏览器可以正常打开,这里加载不出来.
3 这里2.6.14, 这里可以下载https://unpkg.com/vue@2.6.14/dist/vue.js
4 原始笔记来自网络, 如有侵权联系作者删除.
什么是Vue
Vue是一套生产工具
, 你只要会用即可, 不需要知道原理!
目前绝大多数WEB项目, 都采用Vue框架实现!
Vue最低兼容 IE10, 2009年出品的 IE9不支持.
Vue是一个 比 jQuery 封装的更加彻底的框架, 把讨厌的
DOM操作统统封装了起来, 书写代码时, 完全看不到DOM相关代码!
官方网站: https://cn.vuejs.org/
目前Vue分两个版本:
- Vue2.x: 目前普及率最高, 大多数项目都采用的是 Vue2.x 制作
- Vue3.x: 刚出1年左右, 目前还未广泛普及. — 非学习重点, 最后一天会讲解新特性
脚本的下载地址: https://cn.vuejs.org/v2/guide/installation.html
前情回顾
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="box">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<script>
// 原生DOM写法: 找到 span 标签, 在其中添加文本: Hello World!
let span = document.querySelector("#box>span")
span.innerHTML = "Hello World!"
// 每次操作一个元素, 都必须: 先查找 -> 修改
let span1 = document.querySelector("#box>span:nth-child(2)")
span1.innerHTML = "111111111"
let span2 = document.querySelector("#box>span:nth-child(3)")
span2.innerHTML = "222222222"
let span3 = document.querySelector("#box>span:nth-child(4)")
span3.innerHTML = "333333333"
// jQuery思想: 利用语法上, 对查找操作的写法做简化
// $('选择器')
// 这套思路中: 选择器依然需要用户手写! 需要用户消耗大量时间去观察 页面DOM元素应该如何选, 他们的关系如何!
</script>
</body>
</html>
效果:
插值语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- DOM的痛点:
查询代码复杂 + 选择器书写繁琐 且 需要理清DOM元素之间的关系 -->
<div id="app">
<!--
{{}}: 叫做 插值语法, Vue规定的格式, 类似于模板字符串的${} -->
<h2>{{title}}</h2>
<div>
<div>
<div>msg: {{msg}}</div>
<div>{{word}}</div>
<div>{{name}}</div>
<div>{{skill}}</div>
</div>
</div>
</div>
<!-- vue.js 是开发版, 代码有错误 会在后台出现提示 -->
<!-- vue.min.js 是生产版, 没有错误提示, 体积小, 适合上线时使用 -->
<!-- script src="./vendor/vue.js"></script -- >
<script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
<script>
// new Vue(): 创建Vue实例对象, Vue来自于 上方引入的脚本
new Vue({
// 对象类型中, 是vue相关配置项 -- 都是固定的名称
// el: element元素; 值是选择器; 代表当前vue要管理哪个元素
el: "#app",
// data: 数据. 用途:凡是显示在页面上的数据 都放在此属性中
// Vue底层会自动搜索 el 指定元素中, 标签内容是{{}} 的. 就认为是Vue应该处理的变量, 进行对应的替换操作
data: {
title: "Hello Vue!",
msg: "这是第一个vue代码",
word: "Nice To meet you!",
name: "亮亮",
skill: "什么都没讲",
},
})
</script>
</body>
</html>
效果:
{{title}}
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root">
<div>{{msg}}</div>
</div>
<script src="./vendor/vue.js"></script>
<!-- 只要按照官方指定的格式书写代码, 剩余的事情底层会解决--DOM的查询操作 和 赋值操作等.. -->
<script>
//....
new Vue({
el: "#root",
data: {
msg: "我可以的!",
},
})
</script>
</body>
</html>
插值语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<!-- {{}}: 插值语法, 相当于 模板字符串的 ${}, 其中书写的代码都是JS代码 -->
<div>{{9*9}}</div>
<div>{{age >=18 ? '成年' : '未成年'}}</div>
<div>{{new Date().getTime()}}</div>
<div>总价: {{count * price}}</div>
<div>数组的下标取值: {{ names[0] }}</div>
<div>对象: {{teacher.name}}</div>
</div>
<script src="./vendor/vue.js"></script>
<script>
// 用 vue 管理 id='app' 的元素(element)
new Vue({
el: "#app",
data: {
age: 18,
price: 44,
count: 5,
names: ["lily", "john", "mike"],
teacher: { name: "亮亮", age: 35 },
},
})
</script>
</body>
</html>
事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<div>{{msg}}</div>
<!-- 原生语法: onclick -->
<!-- 为了与原生区分, 使用 @ 代替 on -->
<button @click="show1">点我1</button>
<!-- 旧写法, 已淘汰. v-on:click -->
<button v-on:click="show1">点我2</button>
</div>
<script src="./vendor/vue.js"></script>
<script>
//语法糖介绍:
let a = {
// 最完整写法
desc: function desc() {},
//可以省略 function 关键词, 因为太长了
desc1() {},
}
console.log(a)
// 声明vue 管理 id='app' 的元素, 增加data. msg: 666
var vm = new Vue({
el: "#app",
data: {
msg: 666,
},
// methods(方法): 官方规定, 此属性中写 函数, 可以全局到处使用
methods: {
// 相当于: show1: function(){}
show1() {
alert(1111)
// 为 msg 变量 +1
// this的指向: 普通函数的this指向运行时所在对象
// 此处: 要查看真正生成的 vue 对象结构, msg就是存储在vue对象中的. 所以采用 this.msg 来读取
this.msg++
// vue的精髓设计: 修改数据的时候, 会同步更新绑定的DOM元素
// 具体更新原理: 属于常考面试题 -- 亮亮会讲!
},
},
})
console.log(vm) //查看vue对象的样子
</script>
</body>
</html>
事件练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<div>{{count}}</div>
<button @click="doAdd">+1</button>
<button @click="doMinus">-1</button>
<!-- v-on: 在vue3 中已淘汰!, 目前的Vue2也不用 -->
<button v-on:click="doCheng2">*2</button>
<button @click="doChu4">/4</button>
</div>
<script src="./vendor/vue.js"></script>
<script>
//
new Vue({
// el: 管理的元素, 值为选择器
el: "#app",
// data: 存放数据
data: { count: 10 },
// methods: 存放函数
methods: {
doChu4() {
this.count /= 4
},
doCheng2() {
// this.count = this.count * 2
this.count *= 2
},
doMinus() {
this.count--
},
// doAdd: function(){}
doAdd() {
// this.count++ //自增
this.count = this.count + 1
//如果是jq完成此操作 应该分3步
//1.查找到 count 所在的元素: $div
//2.为count+1: new_count = $div.text() +1
//3.把新的count设置到元素中: $div.text(new_count)
},
},
})
</script>
</body>
</html>
事件参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<p>选择你最喜欢的英雄: <b>{{hero}}</b></p>
<button @click="doChoose">托儿索</button>
<button @click="doChoose">儿童劫</button>
<button @click="doChoose">小学僧</button>
<button @click="doChoose">人头狗</button>
</div>
<script src="./vendor/vue.js"></script>
<script>
// 创建 vue 对象, 管理 id='app' 元素, hero默认值: '待定'
new Vue({
el: "#app",
data: { hero: "待定" },
methods: {
// 参数名随意: 这叫形参, 习惯上是 e 或 event
doChoose(event) {
// 事件触发时, 默认带有参数: 事件本身的相关内容
console.log(event)
// target 就是触发当前事件的 DOM 元素
let name = event.target.innerHTML
this.hero = name // 把按钮上的名称 赋值给 hero 变量
},
},
})
</script>
</body>
</html>
选择你最喜欢的英雄: {{hero}}
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<p>选择你最喜欢的队伍: <b>{{team}}</b></p>
<button data-desc="晋级" @click="doChoose">RNG</button>
<button data-desc="晋级" @click="doChoose">EDG</button>
<button data-desc="已淘汰" @click="doChoose">LNG</button>
<button data-desc="已淘汰" @click="doChoose">FPX</button>
</div>
<script src="./vendor/vue.js"></script>
<script>
new Vue({
el: "#app",
data: { team: "" },
methods: {
// 事件点击时, 会自动把事件相关内容 作为参数传递给方法
doChoose(e) {
console.log(e)
let desc = e.target.dataset.desc
let name = e.target.innerHTML
this.team = `${name}-${desc}`
},
},
})
</script>
</body>
</html>
选择你最喜欢的队伍: {{team}}
自定义参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<p>数量: {{count}}</p>
<!-- 注意: 默认写法 @click="changeCount" 此时事件本身会作为参数传递进入 -->
<!-- 如果 自定义的传参, 官方提供了关键词: $event, 用来代表事件参数 -->
<!-- Vue本身就对DOM进行了封装, 提倡的是 代码本身 0 DOM -->
<!-- 所以传参的方式更加推荐, 不推荐使用DOM属性! -->
<button data-delta="+1" @click="changeCount(+1, $event)">数量加1</button>
<button data-delta="-1" @click="changeCount(-1, $event)">数量减1</button>
</div>
<script src="./vendor/vue.min.js"></script>
<script>
new Vue({
el: "#app",
// 此处是数字类型
data: { count: 10 },
methods: {
// delta: 值是 -1 或 +1
changeCount(delta, e) {
console.log(e)
this.count = this.count + delta
},
},
})
</script>
</body>
</html>
数量: {{count}}
属性的绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<!-- {{}} 主要是双标签的内容 使用 -->
<p>{{imgs[0]}}</p>
<!-- 属性用特殊写法: -->
<!-- 旧写法, 基本不用 -->
<img v-bind:src="imgs[0]" />
<!-- 新写法: :属性名="JS代码" -->
<img :src="imgs[current]" />
<button @click="goNext">下一张</button>
</div>
<script src="./vendor/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
imgs: ["./img/1.jpg", "./img/2.jpg", "./img/3.jpg", "./img/4.jpg"],
current: 0, //当前序号
},
methods: {
goNext() {
this.current++
// 取余: 4 %4 == 0, 超过最大序号 自然回到0
// this.current %= 4
// 用图片的个数作为 取余, 可以更加灵活.
// 这样图片数组有变化, 此处的余数自然就会变化
this.current %= this.imgs.length
},
},
})
</script>
</body>
</html>
{{imgs[0]}}
隐藏与显示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<!-- css 隐藏元素: 通过 display -->
<p style="display: none">这是一段消息</p>
<!-- show: 显示,呈现 -->
<p v-show="show">这是一段消息</p>
<button @click="doShow">显示</button>
<button @click="doHide">隐藏</button>
</div>
<script src="./vendor/vue.js"></script>
<script>
new Vue({
el: "#app",
// show: 代表是否要显示
data: { show: true },
methods: {
doShow() {
this.show = true
},
doHide() {
this.show = false
},
},
})
</script>
</body>
</html>
这是一段消息
if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- 根据条件 加载DOM元素 -->
<div id="app">
<p>亮哥的分数:{{score}}</p>
<!-- :属性名='js代码' -->
<button @click="changeScore(-1)" :disabled="score==1">-1</button>
<button @click="changeScore(+1)" :disabled="score==5">+1</button>
<!-- 根据分数显示不同的结果 -->
<!-- v-if: 条件为真, 加载元素; 条件为假, 删除元素 -->
<!-- 面试常问: v-show 和 v-if 都能实现元素的隐藏和显示, 差别在? -->
<!-- v-show利用css的display:none实现隐藏. -->
<!-- v-if 利用删除或添加DOM元素实现隐藏/显示. -->
<!-- v-show性能高,推荐; v-if要删DOM,性能低,不推荐 -->
<p v-if="score==5">大吉大利,今晚吃鸡</p>
<p v-if="score==4">吃糠咽菜,反思人生</p>
<p v-if="score<4">领导找谈话, 准备回家种地...</p>
</div>
<script src="./vendor/vue.js"></script>
<script>
new Vue({
el: "#app",
data: { score: 3 },
methods: {
changeScore(delta) {
this.score += delta
},
},
})
</script>
</body>
</html>
亮哥的分数:{{score}}
大吉大利,今晚吃鸡
吃糠咽菜,反思人生
领导找谈话, 准备回家种地…
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- if...else... -->
<div id="app">
<p>王某人的面试分数: {{score}}</p>
<!-- v-show: true显示 false隐藏 -->
<button @click="changeScore(-10)" v-show="score>0">-10</button>
<button @click="changeScore(+10)" v-show="score<100">+10</button>
<!-- if ... else ...: 满足条件显示xxx 否则显示xxx -->
<p v-if="score>=60">及格</p>
<p v-else>不及格</p>
</div>
<script src="./vendor/vue.js"></script>
<script>
new Vue({
el: "#app",
data: { score: 60 },
methods: {
changeScore(delta) {
this.score += delta
},
},
})
</script>
</body>
</html>
效果:
王某人的面试分数: {{score111}}
{{evaluate}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- if...elseif...elseif...else... -->
<div id="app">
<p>小亮的考试分数: {{score}}</p>
<button @click="changeScore(-10)" :disabled="score==0">-10</button>
<button @click="changeScore(+10)" :disabled="score==100">+10</button>
<!-- 不同的条件 加载不同的DOM元素 -->
<p v-if="score==100">Perfect!</p>
<p v-else-if="score>=90">优秀</p>
<p v-else-if="score>=80">良好</p>
<p v-else-if="score>=60">及格</p>
<p v-else>不及格</p>
</div>
<script src="./vendor/vue.js"></script>
<script>
new Vue({
el: "#app",
data: { score: 60 },
methods: {
changeScore(delta) {
this.score += delta
},
},
})
</script>
</body>
</html>
小亮的考试分数: {{score12}}
{{dg}}
for循环
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<!-- 回顾遍历数组: for (let item of names) { } -->
<!-- 写在哪个元素上, 就可以遍历生成此元素 -->
<!-- of 写成in 效果相同 -->
<li v-for="item of names">{{item}}</li>
<!-- 练习: -->
<div v-for="abc of names">{{abc}}</div>
<p v-for="x in names">{{x}}</p>
<h4></h4>
</ul>
</div>
<script src="./vendor/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
names: ["亮亮", "小亮", "暗暗", "啥都不讲亮"],
},
})
</script>
</body>
</html>
- {{item}}
{{x}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<!-- 可以写 (item,index) 就代表 元素 和 序号 -->
<li v-for="(item,index) in names">
<b>{{index}}</b>
<span>.{{item}}</span>
</li>
<!-- 遍历对象: in 和 of 效果一致; 挑你喜欢的 -->
<li v-for="(item,index) of emp">
<b>{{index}}</b>
<span>{{item}}</span>
</li>
</ul>
</div>
<script src="./vendor/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
names: ["亮亮", "铭铭", "亚楠", "小新", "贾"],
emp: { name: "亮亮", age: 44, phone: "18799887788" },
},
})
</script>
</body>
</html>
- {{index}} .{{item}}
- {{index}} {{item}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- 遍历数字 -->
<div id="app">
<!-- 底层会把4 转为 [1,2,3,4] 然后遍历 -->
<span v-for="item in 4">{{item}}</span>
</div>
<script src="./vendor/vue.js"></script>
<script>
new Vue({
el: "#app",
})
</script>
</body>
</html>
今日内容回顾
Vue框架: 作者进行了完善的封装. 让用户 不需要 操作DOM元素 就可以操作界面
- 不需要查找元素
- 在数据变化时, 会自动更新到DOM中
- vue的初始化
- 引入vue官方提供的脚本.
- 创建实例对象
new Vue({
el:"选择器", // vue会管理 选择器指定的元素
data: {}, //data中的数据 才可以在页面上使用
methods:{}, //这里的函数 才可绑定到页面上使用
}) - 插值语法:
{{}}
- 在html中书写, 主要出现在 双标签的内容区域,
{{ JS代码... }}
- 在html中书写, 主要出现在 双标签的内容区域,
- 事件:
- 旧写法, 由于复杂基本上不用:
<el v-on:事件名="">
- 新写法, 简单易用:
<el @事件名=""/>
- 默认参数:
<el @click="函数" />
注意函数不加()结尾 - 默认会把 事件本身作为参数传入到函数中
- 自定义参数:
<el @click="函数(参数, 参数..., $event)"
- 使用关键词
$event
来代表事件参数
- 旧写法, 由于复杂基本上不用:
- 属性:
- 旧写法:
<el v-bind:属性名="值" />
- 新写法:
<el :属性名="JS代码范围"
- 旧写法:
- 隐藏和显示:
v-show
: 值是true则显示, 值是false 则隐藏
本质是利用 css 的
display:none
实现隐藏 v-if
,v-else
,v-else-if
:- 条件真则添加DOM元素, 添加假则移除DOM元素
- 面试必考: v-show(
css方式, 效率高
) 和 v-if(DOM的添加/移除, 效率低
) 的差异
- for循环
of
和in
关键词 效果一样, 没任何区别, 挑喜欢的<el v-for="item of 数组/对象"
- 带有序号:
<el v-for="(item,index) in 数组/对象"
作业
作业1:
需要用data 保存: 商品名, 单价, 数量, 然后显示到页面上
点击按钮可以变更数量, 最小值1, 减按钮不可用
最大值 20, 隐藏 +按钮
总价格应该 是单价x数量 计算得到
作业2:
有数组如下:
teachers:[
{name:"亮亮", age:34, phone:'18787878789'},
{name:"亚楠", age:18, phone:'18787875555'},
{name:"小新", age:32, phone:'18787434897'},
{name:"铭铭", age:35, phone:'18783447897'},
{name:"贾", age:37, phone:'18787545697'},
]
把数组显示到页面上, 用表格显示
- 提示:
删除
按钮触发的事件应该带有当前项的序号作为参数, 利用 数组的splice
方法可以删除数组元素–具体参考亮亮
讲解的数组知识点
作业3(难):
数组如下: 使用今日项目包中的图片库
- 页面上默认显示第一张图片
- 图片下方有4个按钮, 代表不同的页数: 用循环, 根据图片数量自动生成
- 被点击的按钮, 应该处于
不可用
状态 - 点击按钮之后可以把图片切换成 按钮对应的图
提示: 数组中只保存了图片名, 但是图片路径应该是:
./img/图片名
:src="JS代码"
JS代码可以用模板字符串
方式, 把图片名拼接到 图片路径里
images:['1.jpg', '2.jpg', '3.jpg', '4.jpg']
作业4
页面上有 登录注册按钮:
当点击登录之后:记录为登录成功状态
, 则改为显示:
点击退出之后, 记录为未登录状态
, 则改为显示: