系列文章目录
文章目录
前言
毕业时,因为前端很丑折磨了好一段时间。现在有时间,学习一下前端的Vue组件开发。下面是我记录的知识,学习来源是哔站的黑马老师,大家不懂可以点对点去学习。
第一天
1. Vue的初步创建
在这里我直接省去了 Vue 的优点,笔者认为既然大家要选择学习 Vue,那么其优点和应用场景应该有所了解,此处我直接开门见山,将程序跑起来。如果你是新手,我用的 Vscode 开发,所以需要大家安装这个运行环境。还需要安装 node.js,Vue的网页拓展,在 Vscode 内部安装一些插件如下所示。第一天准备搭建运行环境,毕竟万事开头难,没意义的工作却也是最重要的一部分。

下面展示完整代码,直接可以跑起来。
<!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>四川兔兔</title>
</head>
<body>
<div class="box2">
box2 -- {{ count }}
</div>
<div class="box">
box -- {{ msg }}
</div>
-----------------------------------------------------
<!-- Vue所管理的范围 -->
<div id="app">
<!-- 这里将来会编写一些用于渲染的代码逻辑 -->
<h1>{{ msg }}</h1>
<a href="#">{{ count }}</a>
</div>
<!-- 引入的是开发版本包 - 包含完整的注释和警告 -->
<script src="../js/vue.js"></script>
<script>
// 一旦引入 VueJS核心包,在全局环境,就有了 Vue 构造函数
const app = new Vue({
// 通过 el 配置选择器,指定 Vue 管理的是哪个盒子
el: '#app',
// 通过 data 提供数据
data: {
msg: 'Hello 朋友们',
count: 666
}
})
</script>
</body>
</html>
这是一个 html 文件,body就是装入网页主体内容,div 就是一个个盒模型。我们先从script配置开始看,需要引入 vue.js
这个文件,我们初学者就暂时不用压缩版本,文件的获取可以在官网,选择开发版本。

将这个文件放在相应的位置,我给出我的目录,第一个 script 去找我们下载文件的位置,方便进行链接。

下面这串代码代码是第二个 script 的内容,非常核心。先定义一个 Vue 的对象,el 指定了作用那个盒子,此处是 app 那个盒子,由于上面两个盒子并没有对应的Vue对象,应用的数据无法展示,直接显示文本内容。data 直接定义了数据对象。
- 准备容器 (Vue所管理的范围)
- 引包 (开发版本包 / 生产版本包) 官网
- 创建实例
- 添加配置项 => 完成渲染
<script>
// 一旦引入 VueJS核心包,在全局环境,就有了 Vue 构造函数
const app = new Vue({
// 通过 el 配置选择器,指定 Vue 管理的是哪个盒子
el: '#app',
// 通过 data 提供数据
data: {
msg: 'Hello 道友们',
count: 666
}
})
</script>

2.差值表达式
差值表达式用于提取 Vue 对象的数据,可以进行一些简单的操作,是获取后端数据之后,用于渲染内容的手段。
- 使用
{{ }}
进行data
域中数据的选择。 - 可以对数据进行一些列操作,比如字符串的拼接,加减乘除,三目运算等等。
- 不能嵌套 if 等代码,毕竟数据嘛不能进行冗长的操作。不能使用没有定义的类型,不能在标签属性中使用,比如
<p title="{{msg}}">我是P标签</p>
3. 响应式特征
data中的数据, 最终会被添加到实例上,这个操作看视频。
① 访问数据: “实例.属性名”
② 修改数据: “实例.属性名”= “值”
4.Vue中常用指令汇总
常用指令用于提高程序员 DOM 的效率,减少页面延迟和卡顿。Vue的指令按照用途不同,可分为六大类:
- 内容渲染(v-html,v-text)
- 条件渲染(v-show,v-if,v-else,v-else-if)
- 事件绑定(v-on)
- 属性绑定(v-bind)
- 双向绑定(v-model)
- 列表渲染(v-for)
4.1 内容渲染
v-text 的使用语法:<p v-text="userName">hello</p>
,意思是将 userName值渲染到 p 标签中.使用该语法会覆盖 p 标签原有的内容。
v-html 使用语法:<p v-html="intro">hello</p>
,意思是将 intro 值渲染到 p 标签中,使用该语法,会覆盖 p 标签原有内容,能够将HTML标签的样式呈现出来。
代码样例:
<div id="app">
<h2>个人信息</h2>
<p v-text="userName">姓名:</p>
<p v-html="intro">简介:</p>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
userName:'四川兔兔',
intro:'<h2>这是一个<strong>非常优秀</strong>的boy<h2>'
}
})
</script>
从下面图片我们可以看出来,Vue的常用指令 v-
相当于属性,而且使用之后,原来标签的内容就已经被覆盖了,姓名:,介绍:,并没有展示出来。

4.2 条件渲染
v-show
- 作用:控制元素的隐藏。
- 语法:v-show = “表达式” 表达式值为 true 显示, false 隐藏。
- 原理:切换 display:none 控制显示隐藏。
- 使用场景:需要频繁切换的场景,比如把鼠标移动到某个图标时出现介绍字样。
其实相关盒模型仍然占有空间,需要渲染,只是隐藏。然而 v-if
条件渲染,不满足条件,连盒模型都不会出现。
v-if
- 作用: 控制元素显示隐藏(条件渲染)
- 语法: v-if= “表达式” 表达式值 true显示, false 隐藏
- 原理: 基于条件判断,是否创建 或 移除元素节点
- 场景: 要么显示,要么隐藏,不频繁切换的场景
代码
<!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>条件渲染</title>
</head>
<body>
<div id="app">
<div v-show="flag">我是v-show控制的盒子</div>
<div v-if="flag">我是v-if控制的盒子</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
flag: false
}
})
</script>
</body>
</html>
作为指令传参,直接"data的内容"
。flag等于false,表示不会渲染内容,但是我们检查渲染代码发现:v-show
,他是存在的,仅仅是display:none不显示,然而 v-if
代码都没有,说明盒模型都没有,完全不渲染。

v-else、v-else-if 用于多重条件判断,必须紧跟 v-if 后面。通过下面实例,我们可以知道,v-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>条件渲染</title>
</head>
<body>
<div id="app">
<p v-if="gender==1">性别:♂ 男</p>
<p v-else="gender==2">性别:♀ 女</p>
<hr>
<p v-if="score>=90">成绩评定A:奖励电脑一台</p>
<p v-else-if="score>=80">成绩评定B:奖励周末郊游</p>
<p v-else-if="score>=70">成绩评定C:奖励零食礼包</p>
<p v-else-if="score>=60">没有奖励</p>
<p v-else>成绩评定D:惩罚一周不能玩手机</p>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
gender: 2,
score: 95
}
})
</script>
</body>
</html>
这里大家可以换一下data中的数据,看看不同的结果。
4.3 事件绑定
实现用户界面交互.使用Vue时,如需为DOM注册事件,及其的简单,语法如下:
- <button v-on:事件名=“内联语句”>按钮
- <button v-on:事件名=“处理函数”>按钮
- <button v-on:事件名=“处理函数(实参)”>按钮
v-on:
简写为 @
内联语句:实现按钮的加减。
<div id="app">
<button @click="count--">-</button>
<span>{{ count }}</span>
<button v-on:click="count++">+</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
count: 100
}
})
</script>
事件处理函数,此处在Vue对象中增加一个元素,methods: 可以在里面写入一些方法,这个思想和Java的面向对象开发很相似。函数的语法:
函数名(形参){主体内容}
两种调用方式,如果没有形参@click="函数名"
有形参@click="函数名(形参1,形参2)"
因为我们把Vue创建的对象赋值给 app,因此访问数据元素 isShow 可以使用app.isShow,但是为了提高代码的可维护性,我们通常使用 this.isShow.
<!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>事件处理函数</title>
</head>
<body>
<div id="app">
<button @click="fn">切换显示隐藏</button>
<h1 v-show="isShow">黑马程序员</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isShow: true
},
methods:{
fn(){
this.isShow=!this.isShow;
console.log("点击切换");
}
}
})
</script>
</body>
</html>
里面点击实现切换的 fn 函数通过 isShow 取反来实现的。
实现效果:

4.4 v-bind
- 作用: 动态设置html的标签属性 比如:src、url、title
- 语法: v-bind: 属性名=“表达式”
- v-bind: 可以简写成 => :
比如,我们通常渲染一组图片,它的 src
属性值,是一个图片地址。这些地址在数据 data 中以数组形式存储。
则可以这样设置属性值:通常简写,直接省去 v-bind
<img v-bind:src="url" />
<img :src="url" />
(v-bind可以省略)
代码:图片需要大家自己创建一个image文件,往里面导入自己的图片
<!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">
<button v-show="index>0" @click="index--">上一页</button>
<div>
<img :src="list[index]" alt="">
</div>
<button v-show="index < list.length-1" @click="index++">下一页</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
index:0,
list:[
'../image/奋斗.jpeg',
'../image/好奇.jpg',
'../image/佛系.jpg',
'../image/谨慎.jpeg',
'../image/牛马.jpeg'
]
}
})
</script>
</body>
</html>
两个button按钮分别实现上一页和下一页功能,里面的 v-show 上面提到过,我们频繁切换,到了0页和最后一页要隐藏,不能再增减了。@click 事件绑定,人机交互,实现切换页面。img标签负责图片渲染,渲染的元素有后端提供,为了方便,我们在前端直接写死,使用数组形式,因为后端数据一般也是数组。为了实现数组索引的滑动,在 app 对象中定义一个 index,初始值为零,特别强调数组的定义 数组名: [成员1,成员2],data里面所有元素的定义都是 元素名:具体内容
。说得这么详细这是我的看法,编程是一个细心的过程,逗号错了都运行不起来,多多留意细节,懂了和能够实现是两码事情。
结果图:

4.5 v-for
实打实的列表渲染。下面是列表渲染的结构,
v-for="(数组单个成员,索引) in 数组 " :key="单个成员.id"
通常我们直接使用item,index就可以了。这个 :key 一定要加上,这是每个盒模型的唯一标识符,不建议使用数组下标 index,因为数组下标也是动态改变的。不加 :key,删除对应列表项时,程序把最后一个列表项删除,然后把其余的列表项重新复制到剩余列表项中,没有达到删除指定列表项的目的,显然不合理。
//遍历对象
<div v-for="(item, index) in object" :key='item.id' >{{value}}</div>
item:对象中的值
key:对象中的键
index:遍历索引从0开始
//遍历数字
<p v-for="item in 10">{{item}}</p>
item从1 开始
小栗子:简易人员信息表
<!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>删除数据列表</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(item,index) in bookList" :key="item.id">
<span>姓名:{{item.name}}</span>
<span>年龄:{{item.age}}</span>
<button @click="delt(item.id)">删除</button>
</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
index: 0,
bookList: [
{id:1,name:'二狗',age:18},
{id:2,name:'彬酱',age:19},
{id:3,name:'浪总',age:20},
{id:4,name:'呆呆',age:21},
{id:5,name:'兔兔',age:22}
]
},
methods:{
delt(id){
console.log('删除',id)
this.bookList=this.bookList.filter(item => item.id!=id)
}
}
})
</script>
</body>
</html>
key的值是id,学生就是学号,实现列表渲染。ur 是无序标签,li 表格标签,列表渲染的 v-for 放在 li 中。代码需要注意的地方:
- 数组的成员使用{}表示,里面的数字型直接写,字符型打上双引号。
- 删除操作使用数组的 filter()方法,得到一个新数组,注意逻辑,删除某个id,即我想得到不是这个 id 的成员,所以取非,然后覆盖原数组。里面的 item => item.id !=id 就是数组的每一项进行循环检查,把符合要求的项复制到新的数组中。
4.6 v-model 双向绑定。
所谓双向绑定,即修改页面数据,同步变量值,这样可以实现前后端交互,在前端的变量渲染同步,然后可将变量传递给后端,保存到数据库中。
- 数据改变后,呈现的页面结果会更新
- 页面结果更新后,数据也会随之而变
作用: 给 表单元素(input、radio、select)使用,双向绑定数据,可以快速 获取 或 设置 表单元素内容
语法: v-model=“变量”,添加在表单的对应位置。
代码:
<!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">
账户:<input type="text" v-model="count"> <br><br>
密码:<input type="password" v-model = "password1"> <br> <br>
<button @click="login">登录</button> <button @clcik="reset">重置</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
userName:"四川兔兔",
count:"123456",
password1:"123456"
},
methods:{
login(){
console.log("我登录啦")
},
reset(){
console.log("我要重置密码")
}
}
})
</script>
</body>
</html>
这串代码实现了简单的登录页面,在密码和账户两个表单使用v-model,实现双向绑定。点击登录或者重置密码会打印相应的字,这里函数具体实现和页面跳转学要在开发中来实现,此处略过。修改密码和账户,变量会发生相应变化。

4.7 综合小案列:兔兔备忘录
代码:
<!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">
<link rel="stylesheet" href="./css/index.css">
<title>兔兔备忘录</title>
</head>
<body>
<!-- 主体部分 -->
<section id="app">
<header class="header">
<h1>兔兔备忘录</h1>
<input v-model="context" placeholder="请输入任务" class="new-todo"/>
<button class="add" @click="add">添加任务</button>
</header>
<!-- 列表区域 -->
<section class="main">
<ul class="todo-list">
<li class="todo" v-for="(item,index) in list" :key="item.id">
<div class="view">
<span class="index">{{index+1}}. </span><label>{{item.context}}</label>
<button @click="del(item.id)" class="destroy"></button>
</div>
</li>
</ul>
</section>
<!-- 统计和清除 -->
<footer class="footer" v-show="list.length > 0">
<!-- 统计 -->
<span class="todo-count">合计:<strong>{{list.length}}</strong></span>
<!-- 清空 -->
<button class="clear-completed" @click="clear">清空任务</button>
</footer>
</section>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
context:'',
list:[{id:1,context:"今天完成一天的编程任务"},
{id:2,context:"完成跑步锻炼"},
{id:3,context:"早睡早起身体棒"}
]
},
methods:{
add(){
if(this.context.trim()===''){
alert("请输入任务名称")
return
}
this.list.unshift({
id:+new Date(),
context:this.context
})
this.context = ''
},
del(id){
this.list=this.list.filter(item => item.id !== id)
},
clear(){
this.list = []
}
}
})
</script>
</body>
</html>
这里的 id 使用时间戳,具有唯一性。添加在数组中,我们可以list.unshift( 内容 ) 这种数组自己创建的,不用复制。清空直接让数组为空数组即可,删除前面讲过,filter创建新数组,记得赋值。