Vue3
Vue是一款用于构建用户界面的渐进式的JavaScript框架。
Vue由2部分组成:Vue核心包,Vue插件包
Vue核心包包含:声明式渲染,组件系统。
Vue插件包:VueRouter(客户端路由),Vuex/Pinia(状态管理),Webpack/Vite(构建工具)
Vue的开发形式分为2种:基于核心包的局部开发,整站开发。
基于核心包的局部开发:只使用Vue核心包的局部开发。
整站开发:使用整个Vue生态进行开发。
框架:一套完整的项目解决方案,用于快速构建项目。
框架的优点:提升前端开发效率。
框架的缺点:需要记忆框架的使用规则。
1.Vue快速入门
(1)准备工作
1.引入Vue模块
在html文件中
<body>
..........
.........
<script type=‘module’>
import {createApp} from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
</script>
</body>
2.创建Vue程序的应用示例,控制视图的元素
在html文件中
<body>
..........
.........
<script type=‘module’>
import {createApp} from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({ });
</script>
</body>
3.准备元素(div),被Vue控制。
<body>
..........
.........
<script type=‘module’>
import {createApp} from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({ }).mount('#app'); // 只针对与id为app的元素进行挂载
</script>
</body>
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue入门</title>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
<h1>{{ count }}</h1>
</div>
<h1>{{ count }}</h1>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
createApp({
data() {
return {
message: 'Hello Vue!',
count:100
}
}
}).mount('#app'); // 只针对与id为app的元素进行挂载
</script>
</body>
</html>
运行结果:
2.Vue常用指令
在html标签上,不同指令实现不同功能。
1.v-for
用于列表渲染,遍历容器中的元素/对象。
使用方法:
<tr v-for="(item, index) in itemList" :key="item.id">{{item}}</tr>
遍历itemList数组
遍历出来的元素是item
元素的索引是index
:key为遍历出来的元素添加唯一标识
[ ]是数组
{ }是对象
示例
<table>
<!-- 表头 -->
<thead>
<!-- 定义一行 -->
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>头像</th>
<th>职位</th>
<th>入职日期</th>
<th>最后操作时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(e, index) in empList" :key="e.id">
<!-- index表示索引从0开始 序号表示从1开始 -->
<td>{{index+1}}</td>
<td>{{e.name}}</td>
<td>{{e.gender==1?'男':'女'}}</td>
<!-- 插值表达式,不能出现在标签内部 -->
<td><img class='avatar'src="{{e.image}}" :alt='{{e.name}}'></td>
<td>{{e.position}}</td> //需要条件判断
<td>{{e.entryDate}}</td>
<td>{{e.lastOpTime}}</td>
<td>
<button type="button">修改</button>
<button type="button">删除</button>
</td>
</tr>
</tbody>
</table>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
createApp({
data() {
return {
searchFrome:{//封装用户输入的查询条件。
name:'',
gender:'',
position:''
},
empList: [ //定义数组
{"id":1, //定义一个对象
"name":"张三",
"gender": '1',
"avatar": 'img/y2.png',
"position": '1',
"entryDate": '2020-01-01',
"lastOpTime": '2025-01-01'
},
{"id":2,
"name":"李四",
"gender": '2',
"avatar": 'img/y2.png',
"position": '2',
"entryDate": '2020-01-01',
"lastOpTime": '2025-01-01'
},
{"id":3,
"name":"王五",
"gender": '1',
"avatar": 'img/y2.png',
"position": '3',
"entryDate": '2020-01-01',
"lastOpTime": '2025-01-01'
}
]
}
},
// data后面添加方法
methods:{
search:function(){
// 将搜索条件输出到控制台
console.log(this.searchFrome);
},
clear:function(){
// 清空搜索条件
this.searchFrome={name:'',gender:'',position:''};
}
}
}).mount('#all'); // 只针对与id为all的元素进行挂载
</script>
头像一栏显示不正确。原因:插值表达式,不能出现在标签内部。需要使用v-bind进行修饰。
职位一栏不能正确显示,性别一栏(只有男或者女)可以使用三元运算符,但是职业有5种,无法使用三元运算符,应使用v-if/v-else-if/v-else或者v-show进行处理。
2.v-bind
动态为标签属性绑定值(插值表达式,不能在标签内使用)
使用方法:
v-bind:属性="变量" :属性="变量"
<td><img class="avatar" v-bind:src="e.image" :alt="e.name"></td>
可保证图片的正确显示。
<!-- 表格主体内容 -->
<tbody>
<tr v-for="(e, index) in empList" :key="e.id">
<td>{{index + 1}}</td>
<td>{{e.name}}</td>
<td>{{e.gender == 1?'男' : '女'}}</td>
<!-- 插值表达式是不能出现在标签内部 -->
<td><img class="avatar" v-bind:src="e.image" :alt="e.name"></td>
<td>{{e.entrydate}}</td>
<td>{{e.updatetime}}</td>
<td class="action-buttons">
<button type="button">编辑</button>
<button type="button">删除</button>
</td>
</tr>
</tbody>
</table>
3.v-if/v-else-if/v-else
用来控制元素的显示与隐藏。
基于条件判断,来控制创建或移除元素节点(条件渲染)
使用场景:网页运行时进行处理,要么显示要么不显示。
示例:
<body>
<div id="container">
<!-- 表格展示区 -->
<table>
<!-- 表头 -->
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>头像</th>
<th>职位</th>
<th>入职日期</th>
<th>最后操作时间</th>
<th>操作</th>
</tr>
</thead>
<!-- 表格主体内容 -->
<tbody>
<tr v-for="(e, index) in empList" :key="e.id">
<td>{{index + 1}}</td>
<td>{{e.name}}</td>
<td>{{e.gender == 1?'男' : '女'}}</td>
<!-- 插值表达式是不能出现在标签内部 -->
<td><img class="avatar" v-bind:src="e.image" :alt="e.name"></td>
<!-- v-if: 控制元素的显示与隐藏 -->
<td>
<span v-if="e.job == 1">班主任</span>
<span v-else-if="e.job == 2">讲师</span>
<span v-else-if="e.job == 3">学工主管</span>
<span v-else-if="e.job == 4">教研主管</span>
<span v-else-if="e.job == 5">咨询师</span>
<span v-else>其他</span>
</td>
<td>{{e.entrydate}}</td>
<td>{{e.updatetime}}</td>
<td class="action-buttons">
<button type="button">编辑</button>
<button type="button">删除</button>
</td>
</tr>
</tbody>
</table>
v-else-if必须在v-if之后,可有多个v-else-if。
v-else必须在v-if/v-else-if之后。
4.v-show
用来控制元素的显示与隐藏。与v-if/v-else-if/v-else有所区别。
v-if/v-else-if/v-else和v-show的区别:
v-if网页运行时处理,不满足条件,直接不渲染此元素。
v-show通过css样式,渲染v-show的所有元素,满足条件显示,不满足条件隐藏。
基于css样式的display来控制显示与隐藏。
使用场景:频繁切换显示与隐藏两种状态;如:下拉框。
示例:
<body>
<div id="container">
<!-- 表格展示区 -->
<table>
<!-- 表头 -->
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>头像</th>
<th>职位</th>
<th>入职日期</th>
<th>最后操作时间</th>
<th>操作</th>
</tr>
</thead>
<!-- 表格主体内容 -->
<tbody>
<tr v-for="(e, index) in empList" :key="e.id">
<td>{{index + 1}}</td>
<td>{{e.name}}</td>
<td>{{e.gender == 1?'男' : '女'}}</td>
<!-- 插值表达式是不能出现在标签内部 -->
<td><img class="avatar" v-bind:src="e.image" :alt="e.name"></td>
<!-- v-show: 控制元素的显示与隐藏 -->
<td>
<span v-show="e.job == 1">班主任</span>
<span v-show="e.job == 2">讲师</span>
<span v-show="e.job == 3">学工主管</span>
<span v-show="e.job == 4">教研主管</span>
<span v-show="e.job == 5">咨询师</span>
</td>
<td>{{e.entrydate}}</td>
<td>{{e.updatetime}}</td>
<td class="action-buttons">
<button type="button">编辑</button>
<button type="button">删除</button>
</td>
</tr>
</tbody>
</table>
</div>
</body>
5.v-model
v-model用于获取表单项数据。
v-on用于事件绑定。
通常v-model和v-on配合起来使用。
v-model中绑定的变量必须在data中定义
v-model使用方法:
<body>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
createApp({
data() {
return {
searchFrome:{//封装用户输入的查询条件。
name:'',
gender:'',
position:''
}
}
}).mount('#all'); // 只针对与id为all的元素进行挂载
</script>
</body>
name<-->姓名
gender<-->性别
position<-->职位
具体代码:
<body>
<div id="all">
<!-- 显示采集到的数据 -->
<!-- {{searchFrome}} -->
<form class="search-from" action="/search" method="post">
<label for="name">姓名:</label>
<input type="text" name="name" id="name" v-model="searchFrome.name" placeholder="请输入姓名">
<label for="gender">性别:</label>
<select name="gender" id="genser" v-model="searchFrome.gender">
<option value=""></option>
<option value="1">男</option>
<option value="2">女</option>
</select>
<label for="position">职位:</label>
<select name="position" id="position" v-model="searchFrome.position">
<option value=""></option>
<option value="1">班主任</option>
<option value="2">讲师</option>
<option value="3">学工主管</option>
<option value="4">教研主管</option>
<option value="5">咨询师</option>
</select>
<button type="button" v-on:click="search">查询</button>
<button type="button" @click="clear">清空</button>
</form>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
createApp({
data() {
return {
searchFrome:{//封装用户输入的查询条件。
name:'',
gender:'',
position:''
}
}
}
}).mount('#all'); // 只针对与id为all的元素进行挂载
</script>
</body>
在标签中使用:
<input type="text" name="name" id="name" v-model="searchFrome.name" placeholder="请输入姓名">
将姓名文本栏中输入数据导入data中的searchFrome.name
在标签中使用:
<select name="gender" id="genser" v-model="searchFrome.gender">
将性别文本栏中输入数据导入data中的searchFrome.gender
在标签中使用:
<select name="position" id="position" v-model="searchFrome.position">
将职业文本栏中输入数据导入data中的searchFrome.position
效果如下:
6.v-on
使用方法:
v-on:click="函数名" 或@click="函数名"
为html标签绑定事件(添加事件监听)。
通常与v-model配合使用。
<button type="button" v-on:click="search">查询</button>
<button type="button" @click="clear">清空</button>
将查询与清空按钮绑定事件监听。
整体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>员工管理</title>
<style>
#all{
width: 80%;
margin: 0 auto;
}
.navbar{
background-color: rgb(170, 170, 170);
display: flex;/*弹性布局*/
justify-content: space-between;/*左右对齐*/
align-items: center;/*垂直居中*/
padding: 5px;
}
.navbar h1{
margin: 0;/*去掉h1标签的默认间距*/
font-weight: bold;/*加粗*/
color: white;/*白色文字*/
font-family: "楷体";
}
.navbar a{
color: white;
font-weight: bold;/*加粗*/
text-decoration: none;/*取消下划线*/
align-items: center;/*垂直居中*/
}
.search-from{
display: flex;
flex-wrap: nowrap;/*换行*/
align-items: center;/*垂直居中*/
gap: 10px;/*间距*/
margin-top: 10px;
margin-bottom: 10px;
}
.search-from input,select{
padding: 5px;
width: 220px;
}
table{
width: 100%;
border-collapse: collapse;
}
th,td{
border: 1px solid rgb(0, 0, 0);/*边框*/
padding: 5px;
text-align: center;
}
.footer{
background-color: #b5b3b3;
color: white;
text-align: center;
padding: 10px 0;
margin-top: 30px;
}
</style>
</head>
<body>
<div id="all">
<div class="navbar">
<h1>tlias 智能学习辅助系统</h1>
<a href="">退出登录</a>
</div>
<!-- 显示采集到的数据 -->
<!-- {{searchFrome}} -->
<form class="search-from" action="/search" method="post">
<label for="name">姓名:</label>
<input type="text" name="name" id="name" v-model="searchFrome.name" placeholder="请输入姓名">
<label for="gender">性别:</label>
<select name="gender" id="genser" v-model="searchFrome.gender">
<option value=""></option>
<option value="1">男</option>
<option value="2">女</option>
</select>
<label for="position">职位:</label>
<select name="position" id="position" v-model="searchFrome.position">
<option value=""></option>
<option value="1">班主任</option>
<option value="2">讲师</option>
<option value="3">学工主管</option>
<option value="4">教研主管</option>
<option value="5">咨询师</option>
</select>
<button type="button" v-on:click="search">查询</button>
<button type="button" @click="clear">清空</button>
</form>
<table>
<!-- 表头 -->
<thead>
<!-- 定义一行 -->
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>头像</th>
<th>职位</th>
<th>入职日期</th>
<th>最后操作时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(e, index) in empList" :key="e.id">
<!-- index表示索引从0开始 序号表示从1开始 -->
<td>{{index+1}}</td>
<td>{{e.name}}</td>
<td>{{e.gender==1?'男':'女'}}</td>
<!-- 插值表达式,不能出现在标签内部 -->
<td><img class='avatar' v-bind:src="e.avatar" :alt='e.name'></td>
<!-- <td>{{e.position}}</td> //需要条件判断 -->
<td>
<span v-if="e.position==1">班主任</span>
<span v-else-if="e.position==2">讲师</span>
<span v-else-if="e.position==3">学工主管</span>
<span v-else-if="e.position==4">教研主管</span>
<span v-else-if="e.position==5">咨询师</span>
<span v-else>其他</span>
</td>
<td>{{e.entryDate}}</td>
<td>{{e.lastOpTime}}</td>
<td>
<button type="button">修改</button>
<button type="button">删除</button>
</td>
</tr>
</tbody>
</table>
<footer class="footer">
<p>cyy有限公司</p>
<p>版权,时间2025.5.9</p>
</footer>
</div>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
createApp({
data() {
return {
searchFrome:{//封装用户输入的查询条件。
name:'',
gender:'',
position:''
},
empList: [ //定义数组
{"id":1, //定义一个对象
"name":"张三",
"gender": '1',
"avatar": 'img/y2.png',
"position": '1',
"entryDate": '2020-01-01',
"lastOpTime": '2025-01-01'
},
{"id":2,
"name":"李四",
"gender": '2',
"avatar": 'img/y2.png',
"position": '2',
"entryDate": '2020-01-01',
"lastOpTime": '2025-01-01'
},
{"id":3,
"name":"王五",
"gender": '1',
"avatar": 'img/y2.png',
"position": '3',
"entryDate": '2020-01-01',
"lastOpTime": '2025-01-01'
}
]
}
},
// data后面添加方法
methods:{
search:function(){
// 将搜索条件输出到控制台
console.log(this.searchFrome);
},
clear:function(){
// 清空搜索条件
this.searchFrome={name:'',gender:'',position:''};
}
}
}).mount('#all'); // 只针对与id为all的元素进行挂载
</script>
</body>
</html>