基础
- 静态资源:
- HTML:用于搭建基础网页,展示页面的内容
- CSS:用于美化页面,布局页面
- JavaScript:控制页面的元素,让页面有一些动态的效果
Html5
详细参见:思维脑图
基础标签
1、标题标签: h1 到 h6
2、段落标签:p
3、字体加粗:b 字体倾斜:em
4、换行:br(非成对出现的)
5、分割线: hr
6、表示一块内容:div (没有特殊的效果)
在html5中支持自定义标签,自定义的标签和div标签的用法是一样的
7、行内块元素:span
8、图像标签:img
src属性:指定图片地址
alt: 指定图片未加载出来时的提示
9、超连接标签:a
10、音频播放器:audio
11、视频播放器:video
12、无序列表:ul
13、有序列表:ol
14、表格:table
表单标签
表单:form
input:输入框
type属性:
text:文本
password:密码
submit:提交按钮(点击之会主动提交表单)
button:普通按钮(点击之后没有特殊效果)
checkbox:多选框
radio:单选框
file:文件上传
hidden:影藏的表单域(预设一个要传递的参数和值,但是不会在页面上显示)
reset:情况表单内容
name:表单的参数名
value:表单的值
placeholder:表单的提示内容
label标签:将表单前的提示内容和表单进行关联;当点击label标签内容时,会自动将焦点聚焦于关联的表单上
textarea标签:文本输入框
CSS3
基本使用
1、通过link标签引入外部的css文件
<link rel="stylesheet" href="css/a.css">
2、在head中通过style标签定义样式
<style>
div{
color:blue;
}
</style>
3、在标签中通过style属性定义样式
如:<div style="color:red;">hello css</div>
选择器
1. 基础选择器
1. id选择器:选择具体的id属性值的元素.建议在一个html页面中id值唯一
* 语法:#id属性值{}
2. 元素选择器:选择具有相同标签名称的元素
* 语法: 标签名称{}
* 注意:id选择器优先级高于元素选择器
3. 类选择器:选择具有相同的class属性值的元素。
* 语法:.class属性值{}
* 注意:类选择器选择器优先级高于元素选择器
2. 扩展选择器:
1. 选择所有元素:
* 语法: *{}
2. 并集选择器:
* 选择器1,选择器2{}
3. 子选择器:筛选选择器1元素下的选择器2元素
* 语法: 选择器1 选择器2{}
4. 父选择器:筛选选择器2的父元素选择器1
* 语法: 选择器1 > 选择器2{}
5. 属性选择器:选择元素名称,属性名=属性值的元素
* 语法: 元素名称[属性名="属性值"]{}
6. 伪类选择器:选择一些元素具有的状态
* 语法: 元素:状态{}
* 如: <a>
* 状态:
* link:初始化的状态
* visited:被访问过的状态
* active:正在访问状态
* hover:鼠标悬浮状态
背景
/* 设置背景颜色 */
/*background: yellow;*/
/* 设置图片作为背景 */
background-image: url('./images/bj.png');
/* 设置背景是否平铺
background-repeat:
no-repeat; 不进行平铺
repeat-y; y轴平铺
repeat-x; x轴平铺 */
background-repeat: no-repeat;
/* 设置背景的定位 */
background-position:50px 100px;
/* 固定背景位置 */
background-attachment:fixed;
/* 设置背景大小 */
background-size:200px 100px ;
文本样式
color: #FF0000; 字体颜色
font-size: 36px; 大小
font-weight: bold; 是否加粗
font-style: italic; 是否倾斜
font-family: '微软雅黑'; 字体样式
line-height 行高
font: 字体是否加粗 字体大小/行高 字体样式
text-indent: 36px; 设置文字首行缩进
text-align:设置文件对齐位置
盒子模型(控制布局)
* margin:外边距
* padding:内边距
* 默认情况下内边距会影响整个盒子的大小
* box-sizing: border-box; 设置盒子的属性,让width和height就是最终盒子的大小
为什么要进行浮动:页面横向布局
* float:浮动
* left
* right
浮动塌陷的问题:父级元素在没有设置高度的情况下,子元素浮动会造成浮动塌陷(父元素后面的元素会显示到浮动的元素下面)
解决方案1、:给父元素设置:overflow: hidden;
定位
相对定位 relative:相对于原来在文档流的位置进行偏移
绝对定位 absolute: 根据已经进行定位的父级元素进行偏移
(通常在使用绝对定位时,会将父级元素设置为相对定位,简称子绝父相)
固定位置定位 fixed
显示(display)
display属性:可以控制元素的显示和隐藏
display: none隐藏元素
display:block(默认,元素可见)
display:block/inline-block 主要用于行内标签(如a span还有特殊img)宽高设置不生效
JavaScript(JS)
基本语法
引入
1、第一种:行间事件: 直接在元素上 通过给元素添加事件绑定,来执行js代码
<button type="button" onclick="alert(123456)">按钮1</button>
2、第二种:通过script标签引入外部的js文件
<script type="text/javascript" src="js/main.js"></script>
3、第三种:直接页面的script标签中编写js代码
<script>
function musen(){
alert('musen123')
}
</script>
注释
1. 单行注释://注释内容
2. 多行注释:/*注释内容*/
变量
var:定义的变量可以跨代码块访问(全局变量)。
let:定义块级作用局的变量(代码块内的局部变量)
const: 定义常量,初始化必须赋值,值不可修改,只能在块级作用域访问
{} :包起来的代码,就是代码块
数据类型
1. 原始数据类型(基本数据类型):
1. number:数字。 整数/小数/NaN(not a number 一个不是数字的数字类型)
2. string:字符串。 字符串 "abc" "a" 'abc'
3. boolean: true和false
4. null:一个对象为空的占位符
5. undefined:未定义。如果一个变量没有给初始化值,则会被默认赋值为undefined
2. 引用数据类型:对象
对象
对象的定义:1、{} ,2、new Object()
对象的属性和方法:
属性名:属性值
方法名:函数
对象中的this:代表的是对象本身
var objA = {
name:'木森',
age:18,
func1:function(){
console.log('objA的func1方法')
},
func2:function(){
console.log('打印对象中的this')
console.log(this.name)
}
}
函数
function 方法名称(形式参数列表){
方法体
}
1、函数的定义:
function printUserInfo(name,age){
console.log('我的名字:'+name+'我的年纪:'+age)
}
2、函数的返回值
function addNumber(a,b){
// 返回a+b的结果
return a+b
}
// 扩展:函数中的this:代表的是window对象(窗口)
function work01(){
console.log(this)
}
var 方法名 = function(形式参数列表){
方法体
}
// es6中箭头函数
// 箭头函数和普通函数中this的区别
// 普通函数里的this代表的所在作用域的对象,即对象中普通函数里的this指对象本身
// 箭头函数里的this代表的所在作用域的外层作用域的对象,即对象中箭头函数里的this指当前对象外层作用域的对象
var objA ={
// 箭头函数
func: ()=>{
console.log('这个是func方法')
},
func3:(a,b)=>{
return a+b
},
// 箭头函数只有一个参数时,括号可以省略
func4:a=>{
console.log(a)
// 这个this代表的window对象
console.log(this)
},
func2:function (){
console.log('这个是func2方法')
// this代表objA
console.log(this)
}
}
流程控制语句
1、if-else语句
if(10>20){
console.log('10>5成立!')
}else{
console.log('10>5不成立!')
}
2、if- else if -else
var number = 55
if (number>=80){
console.log('成绩很优秀')
}else if( number>=60){
console.log(number)
console.log('成绩及格')
}else{
console.log('成绩不及格')
}
3、while循环
// break 和continue关键字和python中的作用时一样的
var count = 1
while(count<=10){
console.log(count)
count++
// 当count等于5时,强制退出循环
if (count==8){
// break
// continue
}
console.log(`--------------`)
}
4、for循环
(1)for条件循环 :for(循环开始之前执行的代码,是否执行循环体的条件,循环体执行完执行执行的代码)
for (var i=1;i<=10;i++){
console.log(i)
}
(2)for 遍历循环
// 注意点:for循环遍历数组时,遍历出来的时数组的索引
var arryA = [11,22,33,44]
for循环遍历数组
for(i in arryA){
console.log(i,arryA[i])
}
// 注意点:for循环遍历对象时,遍历出来的是对象的属性名
var objA = {
name:'木森',
age:18,
func1:function(){
console.log('objA的func1方法')
},
func2:function(){
console.log('打印对象中的this')
console.log(this.name)
}
}
// for循环遍历对象
for (i in objA){
console.log(i,objA[i])
}
数组遍历、过滤和查找
// forEach遍历数组
arryA.forEach(function (item,i,arry){
// item 是遍历出来的值
// i 是对应的索引
//arry 是数组本身
console.log(item,i,arry)
})
// filter:遍历数组,进行过滤
var res = arryA.filter(function(item,i){
return item>50
})
console.log(res)
// find方法:查找第一个符合条件的值
var res = arryA.find(function(item,i){
return item ==33
})
console.log(res)
JS操作页面
// window.onloan 是窗口的一个事件,这个事件会等到页面元素加载完毕之后才会执行
window.onload = function(){
document.querySelector('#box1').innerText='python001'
}
VUE2
浏览器安装vue devtools可用于调试vue程序
基础语法
基本使用
- 引入vue
- 声明控制的DOM区域
- 创建vue实例
- el:指向视图view
- data:指向数据model
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div>{{name}}</div>
<div>{{age}}</div>
<div>{{gender}}</div>
<button type="button" @click="add()">+</button>
<button type="button" @click="sub()">-</button>
</div>
<script type="text/javascript">
/*
{{}}:插值表达式
*/
var vue = new Vue({
// el 是vue绑定的页面元素
el: "#app",
// data: 是绑定到页面中的数据
data:{
name:'musen',
age:18,
gender:'男'
},
methods:{
// vue方法中的this代表的vue这个对象
add:function(){
this.age++
},
sub:function(){
this.age--
}
},
})
</script>
</body>
</html>
vue指令
v-text、v-html(文本插值)
<标签名 v-text="vue中data的key"></标签名>
<标签名 v-html="vue中data的key"></标签名>
说明:文本插值v-html通过data的key获取value显示标签的文本中
插值表达式{{}}不解析html标签,不能使用在属性中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="box">
<span>{{user}}</span>
<span v-text="user"></span>
<div v-html="info"></div>
<div v-pre>{{info}}</div>
</div>
<script type="text/javascript">
/*
常见指令:
v-text:往标签中插入文本值
v-html:往标签中插入html元素
v-pre:在标签中显示原始文本内容
*/
var vue = new Vue({
el: '#box',
data: {
user: '小柠檬',
info: '<h1>python</h1>',
status:false
}
})
</script>
</body>
</html>
v-bind(属性绑定)
单向数据绑定,脚本改变,视图改变
<标签名 v-bind:属性名="data中key"></标签名>
简写:常用
<标签名 :属性名="data中key"></标签名>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style type="text/css">
.hide {
width: 100px;
height: 200px;
background: red;
}
.hide2 {
width: 100px;
height: 200px;
background: blue;
}
</style>
</head>
<body>
<div id="box">
<!-- <div class="hide">1</div> -->
<!-- <hr> -->
<!-- <div v-bind:class="cls">2</div>
<hr>
<div v-bind:class="[cls]">3</div>
<hr>
<div :class="{hide:status}">4 </div>
-->
<a :href='addr'>淘宝</a>
<a :href="addr2" :musen='musen' >百度</a>
</div>
<script type="text/javascript">
/**
* v-bind 可以简写为 :
* v-bind:属性值 = 绑定的数据
*/
var vue = new Vue({
el: '#box',
data: {
cls: 'hide',
status: true,
addr:'http://www.taobao.com',
addr2:'http://www.baidu.com',
musen:'1234'
}
})
</script>
</body>
</html>
v-model(双向绑定)
仅用于input、select、textarea标签
双向数据绑定,脚本改变,视图改变,视图改变,脚本也改变
<标签名 v-model="vue中data的key"></标签名>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="info">
<div>{{info}}</div>
</div>
<script type="text/javascript">
var vue = new Vue({
el:'#app',
data:{
info: 'python'
}
})
</script>
</body>
</html>
v-on(事件绑定)
<标签名 v-on:事件名="执行函数"></标签名>
简写:重点记忆
<标签名 @事件名="执行函数"></标签名>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<table border="" cellspacing="" cellpadding="">
<tr>
<th>ID</th>
<th>接口名</th>
<th>测试人员</th>
<th>项目名</th>
<th>项目ID</th>
<th>描述信息</th>
<th>创建时间</th>
<th>用例数</th>
<th>操作</th>
</tr>
<tr :key='item.id' v-for="item in lists">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.tester}}</td>
<td>{{item.project}}</td>
<td>{{item.project_id}}</td>
<td>{{item.desc}}</td>
<td>{{item.create_time}}</td>
<td>{{item.testcases}}</td>
<td><button @click="del(item.id)">删除</button></td>
</tr>
</table>
<hr>
</div>
<script type="text/javascript">
/*
给绑定的事件传递参数
*/
var vue = new Vue({
el: '#app',
data: {
lists: [{
"id": 1,
"name": "登录接口_自动化测试平台项目",
"tester": "可优",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "登录接口",
"create_time": "2019-11-06 14:50:30",
"testcases": 9,
},
{
"id": 2,
"name": "注册接口_自动化测试平台项目",
"tester": "可可",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "自动化测试平台项目, 注册接口",
"create_time": "2019-11-06 14:51:00",
"testcases": 0,
},
{
"id": 3,
"name": "创建项目接口_自动化测试平台项目",
"tester": "可优",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "这是自动化测试平台创建项目接口",
"create_time": "2019-11-06 14:51:45",
"testcases": 1,
},
{
"id": 4,
"name": "注册接口_前程贷P2P金融项目",
"tester": "小可可",
"project": "前程贷P2P金融项目",
"project_id": 2,
"desc": "",
"create_time": "2019-11-06 14:52:22",
"testcases": 0,
},
{
"id": 5,
"name": "登录接口_前程贷P2P金融项目",
"tester": "柠檬小姐姐",
"project": "前程贷P2P金融项目",
"project_id": 2,
"desc": "",
"create_time": "2019-11-06 14:52:40",
"testcases": 0,
},
{
"id": 6,
"name": "查看项目列表接口_前程贷P2P金融项目",
"tester": "柠檬小姐姐",
"project": "前程贷P2P金融项目",
"project_id": 2,
"desc": "",
"create_time": "2019-11-06 17:22:50",
"testcases": 1,
}
],
},
methods:{
del:function(id){
// 删除数据的方法
console.log('删除一行数据',id)
// 从lists中删除对应的数据
// 通过过滤的方式删除数组中的数据
// this.lists= this.lists.filter(function(item,index){
// return item.id !=id
// })
// 查找要删除的数据索引值
let index = this.lists.findIndex(function(item){
return item.id==id
})
// 根据数组的索引去删除数组中对应的数据
this.lists.splice(index,1)
}
}
})
</script>
</body>
</html>
v-if、v-show(条件渲染)
// v-if 如果满足某个条件,那么就显示文本,不满足就无
<标签名 v-if="判断条件">文本</标签名>
<标签名 v-else-if="判断条件">文本</标签名>
....
<标签名 v-else>文本</标签名>
// v-show 如果满足某个条件,那么就显示文本,不满足就隐藏 display:none
<标签名 v-show="判断条件">文本</标签名>
v-if 示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div>
<span v-text="user"></span>
<span v-text="score"></span>
<span v-if="score>80">优秀</span>
<span v-else-if="score>60">良好</span>
<span v-else=>不及格</span>
</div>
</div>
<script type="text/javascript">
/*
0-60 不及格
60--80 良好
80-100 优秀
vue中的条件判断语句:根据不同的条件显示不同的内容
v-if
v-else-if
v-else:
*/
var vue = new Vue({
el:"#app",
data:{
stus:[
{name:'木森',score:100},
{name:'盼盼达',score:78},
{name:'好好先生',score:89},
{name:'枫',score:99},
],
score:88,
user:'musen'
}
})
</script>
</body>
</html>
v-show 示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>条件渲染</title>
</head>
<body>
<div id="div">
<!--v-show指令-->
<div v-show="flag">div4</div>
<!--
v-if v-show 他们俩虽然都是控制元素是否显示,但是底层的原理不一样
v-if 如果条件为false,页面中根本没有这个元素
v-show如果条件为false,页面中有这个元素只不过它的display属性值为none
-->
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: "#div",
data: {
num: 2,
flag: false
}
});
</script>
</html>
v-for(循环)
<标签名 v-for="变量名 in 容器或者对象名">{{变量名}}</标签名>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<table border="" cellspacing="" cellpadding="">
<tr>
<th>姓名</th>
<th>成绩</th>
<th>等级</th>
</tr>
<!-- // key 需要指定一个数据中唯一的值 -->
<tr v-for='item in stus' :key='item.score'>
<td>{{item.name}}</td>
<td>{{item.score}}</td>
<td v-if="item.score>80">优秀</td>
<td v-else-if="item.score>60">良好</td>
<td v-else>不及格</td>
</tr>
</table>
</div>
<script type="text/javascript">
/*
0-60 不及格
60--80 良好
80-100 优秀
v-for:循环语句
*/
var vue = new Vue({
el: "#app",
data: {
stus: [{
name: '木森',
score: 100
},
{
name: '盼盼达',
score: 78
},
{
name: '好好先生',
score: 89
},
{
name: '枫',
score: 99
},
],
score: 88,
user: 'musen'
}
})
</script>
</body>
</html>
高级特征
修饰符
事件修饰符
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div @click="work3">
<div @click="work2()">
<button type="button" @click.stop="work1()">按钮1</button>
<a href="http://www.baidu.com" @click.prevent.stop="handleA()">百度</a>
</div>
</div>
</div>
<script type="text/javascript">
/*
事件冒泡:子元素触发某个事件之后,会依次将这个事件传递给父元素
vue事件修饰符:
stop: 阻止事件冒泡
prevent:阻止元素默认的事件行为
*/
var vm = new Vue({
el: '#app',
data: {},
methods: {
work1: function() {
console.log('work1-----')
},
work2: function() {
console.log('work2-----')
},
work3: function() {
console.log('---work30000')
},
handleA:function(){
console.log('点击了a标签')
}
}
})
</script>
</body>
</html>
按键修饰符
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<form action="">
账号:<input type="text" v-model.lazy="loginForm.user"> <br>
密码:<input type="password" v-model="loginForm.pwd" @keyup.enter="login_btn()"><br>
<button type="button" @click="login_btn()">点击登录</button>
</form>
</div>
<script type="text/javascript">
/*
事件冒泡:子元素触发某个事件之后,会依次将这个事件传递给父元素
vue事件修饰符:
stop: 阻止事件冒泡
prevent:阻止元素默认的事件行为
按键修饰符
keyup.enter:回车键
表单修饰符:
trim:去除输入首尾的空白
*/
Vue.config.keyCodes.a = 65
var vm = new Vue({
el: '#app',
data: {
loginForm:{
user:'',
pwd:''
}
},
methods: {
login_btn:function(){
alert('点击了登录')
}
}
})
</script>
</body>
</html>
表单修饰符
/// 在 "change" 事件后同步更新而不是 "input",比如回车或者失去焦点
<input v-model.lazy="msg" />
// 输入自动转换为数字
<input v-model.number="age" />
// 默认自动去除用户输入内容中两端的空格
<input v-model.trim="msg" />
计算属性(computed)
计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3>产品名:{{name}}</h3>
<h3>单价:{{price}}</h3>
<h3>
数量:
<button type="button" @click="sub()">-</button>
<span>{{num}}</span>
<button type="button" v-on:click="add()">+</button>
</h3>
<hr>
<!-- <h2>合计金额:{{sum_func()}}</h2> -->
<h2>合计金额:{{sum}}</h2>
</div>
<script type="text/javascript">
/**
*计算属性:通过computed进行定义
作用:
*
*
*/
var vue = new Vue({
el: '#app',
data: {
name: '小柠檬',
price: 8,
num: 0,
},
methods: {
add: function() {
this.num++
},
// 定义方法时:将function省略,和上面定义的add方法没有区别
sub() {
this.num--
},
// sum_func(){
// return this.price * this.num
// }
},
// 定义计算属性,
computed: {
sum: function() {
return this.price * this.num
}
},
})
</script>
</body>
</html>
侦听器(watch)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="box">
数量:
<button type="button" @click="sub()">-</button>
<input type="text" :value="number">
<button type="button" v-on:click="add()">+</button>
<hr>
<input type="text" v-model.lazy="name">
</div>
<script type="text/javascript">
/**
* 侦听器 监测数据的值是否发生变化
*/
var vue = new Vue({
el: '#box',
data: {
number:0,
name :'musen'
},
methods:{
add:function(){
this.number++
},
// 定义方法时:将function省略,和上面定义的add方法没有区别
sub(){
this.number--
}
},
// 侦听器
watch:{
number:function(value){
console.log('监测到number的值发生了变化',value)
if (value<0){
alert('数量不能少于0')
this.number=0
}
},
name:function(value){
console.log('监测到name的值发生了变化',value)
}
}
})
</script>;
</body>
</html>
过滤器(filters)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3>产品名:{{name}}</h3>
<h3>单价:{{price | dubboFloat}}</h3>
<h3>
数量:
<button type="button" @click="sub()">-</button>
<span>{{num}}</span>
<button type="button" v-on:click="add()">+</button>
</h3>
<hr>
<!-- <h2>合计金额:{{sum_func()}}</h2> -->
<h2>合计金额:{{sum | dubboFloat}}</h2>
<h2>{{info| upper}}</h2>
</div>
<script type="text/javascript">
var vue = new Vue({
el: '#app',
data: {
name: '小柠檬',
price: 8,
num: 0,
info:'python'
},
methods: {
add: function() {
this.num++
},
// 定义方法时:将function省略,和上面定义的add方法没有区别
sub() {
this.num--
}
},
// 定义计算属性,
computed: {
sum: function() {
return this.price * this.num
}
},
// 定义过滤器
/*
主要用来对页面显示的数据,做一些格式化的处理
*/
filters:{
dubboFloat:function(value){
// 格式化数值,显示两位小数
return value.toFixed(2)
},
upper:function(value){
// 将字符串中的小写字符转换为答谢
return value.toUpperCase()
}
}
})
</script>
</body>
</html>
vue生命周期
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div>{{message}}</div>
<button @click="update01">按钮</button>
<button type="button" @click="btn">销毁</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: '木森'
},
methods:{
update01:function(){
this.message='mmmmm'
},
btn:function(){
//销毁vue实例对象
this.$destroy()
}
},
beforeCreate: function() {
console.group('------beforeCreate--vue创建前状态------');
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //undefined
console.log("%c%s", "color:red", "message: " + this.message)
},
created: function() {
console.group('------created--vue创建完毕状态------');
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeMount: function() {
console.group('------beforeMount,data数据挂载前状态------');
console.log("%c%s", "color:red", "el : " + (this.$el)); //已被初始化
console.log(this.$el.innerHTML);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
mounted: function() {
console.group('------mounted data数据挂载结束状态------');
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化
console.log(this.$el.innerHTML);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeUpdate: function() {
console.group('beforeUpdate data数据更新前状态==============');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el.innerHTML);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
updated: function() {
console.group('updated data数据更新完成状态==============');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el.innerHTML);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
beforeDestroy: function() {
console.group('beforeDestroy vue对象销毁前状态==============');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el.innerHTML);
console.log("%c%s", "color:red", "data : "+ this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
destroyed: function() {
console.group('destroyed vue对象销毁完成状态==============');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el.innerHTML);
console.log("%c%s", "color:red", "data : "+ this.$data);
console.log("%c%s", "color:red", "message: " + this.message)
}
})
</script>
</body>
</html>
组件化开发
组件注册和使用
全局注册
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.title {
background: #0000FF;
height: 80px;
margin-bottom: 5px;
}
.content {
background: #FAEBD7;
height: 1000px;
}
.footer {
margin-top: 10px;
background: #9ACD32;
height: 100px;
}
.left {
width: 15%;
background: #00FFFF;
height: 100%;
float: left;
margin-right: 0.5%;
}
.right {
width: 84%;
background: #FF0000;
height: 100%;
float: left;
}
</style>
</head>
<body>
<div id="app">
<!-- 顶部菜单栏 -->
<div class="title">
<header-con></header-con>
<!-- <HeaderCon></HeaderCon> -->
</div>
<!-- 中间的主题内容 -->
<div class="content">
<!-- 左边的菜单 -->
<div class="left">
<left-con></left-con>
</div>
<!-- 右边的内容 -->
<div class="right">
<right-con></right-con>
</div>
</div>
</div>
<script type="text/javascript">
/*
1、定义组件:
全局组件:使用Vue.component定义组件
2、在页面中使用组件 <组件名></组件名>
3、组件名的命名注意点:
如果定义组件的时候,组件名使用的是大驼峰的命名风格,在页面中引用组件的时候 ,
要使用中划线命名风格(xx-xx)
4、定义的全局组件 可以再其他的组件中直接引用
注意点:在组件的版本中引用其他组件可以使用大驼峰命名法
建议:组件命名尽量使用中划线命名风格 xxx-xxx
*/
// 全局的组件定义:
// Vue.component('header-con', {
// template: `
// <div><h1>这个是页面头部组件</h1></div>
// `
// })
Vue.component('HeaderCon', {
template: `
<div><h1>这个是页面头部组件9999</h1></div>
`
})
Vue.component('left-con', {
template: `
<div> <h1>这个是页面左边内容的组件</h1>
<my-button></my-button></div>
`
})
Vue.component('right-con', {
template: `
<div>
<h1>这个是页面左边内容的组件</h1>
<my-button></my-button>
<MusenButton></MusenButton>
</div>
`
})
Vue.component('my-button',{
template:`
<button>mybutton</button>
`
})
Vue.component('MusenButton',{
template:`
<button>musen</button>
`
})
var vm = new Vue({
el: '#app',
data: {
},
})
</script>
</body>
</html>
局部注册
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<header-con></header-con>
<left-con></left-con>
</div>
<script type="text/javascript">
/*
*/
var vm = new Vue({
el: '#app',
data: {
},
// 定义局部组件:只能在父组件(页面)中使用,不能在其他的组件中引用
components: {
// 组件名要使用引号包起来,不然会报语法错误-
'header-con': {
template: `
<button>按钮1</button>
`
},
'left-con': {
template: `
<div>
<span>python666</span>
</div>
`
}
}
})
</script>
</body>
</html>
组件名格式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<header-con></header-con>
<left-con></left-con>
</div>
<script type="text/javascript">
/*
1、组件中的数据 同样放在data字段中,
注意点:组件中的data是一个方法(函数),数据为函数return返回出来的内容
注意点:组件的模板内容,必须有一个根节点(最外层只有一个标签)
2、组件中的方法:定义在methods中
*/
var vm = new Vue({
el: '#app',
data: {
name: '木森',
age: 99
},
// 定义局部组件:只能在父组件(页面)中使用,不能在其他的组件中引用
components: {
// 组件名要使用引号包起来,不然会报语法错误-
'header-con': {
template: `
<button @click='handleClick'>按钮1</button>
`,
methods: {
handleClick: function() {
console.log('----handleClick-----')
}
},
},
'left-con': {
template: `
<div>
<h2>名字{{name}}</h2>
<h2>名字{{age}}</h2>
<h2>计算属性sum:{{sum}}</h2>
<span>python666</span>
</div>
`,
// 组件中的数据 同样放在data字段中,
// 注意点:组件中的data是一个方法(函数),数据为函数return返回出来的内容
data: function() {
return {
name: 'musen',
age: 18
}
},
computed: {
sum: function() {
return this.name + this.age
}
},
watch: {
age: function(val) {
console.log(val)
}
}
}
}
})
</script>
</body>
</html>
父组件往子组件中传数据
父组件在引用子组件时,通过属性绑定的形式(即:自子组件自定义的属性名)传递参数
子组件中通过props定义接收数据的参数名(子组件的属性名)
注意:子组件传值注意-加冒号和不加冒号区别
- 父组件向子组件传值,如果不加:冒号,传过去的不是数值,而是一个字符串
- 父组件向子组件传值,加上:冒号,传过去的就是一个数值,不是字符串,因为加了:冒号以后引号""里面的内容就是一个js表达式
- 只有传递字符串常量时,不采用v-bind形式,其余情况均采用v-bind形式传递。
- 如果不加冒号,子组件在接收到值之后,监听做不到改变监听值内的属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<data-views :lists="cases1"></data-views>
<data-views :lists="cases2"></data-views>
</div>
<script type="text/javascript">
/*
场景:父组件中引用子组件的时候,给子组件传递数据
实现步骤:
1、在子组件中通过props来定义接收数据的参数名(子组件的属性名)
2、父组件在引用子组件时,通过属性绑定的形式传递参数
*/
Vue.component('data-views', {
// 指定父组件中引用该组件时,传递数据的参数名
props:['lists'],
template: `
<table border="" cellspacing="" cellpadding="">
<tr>
<th>ID</th>
<th>接口名</th>
<th>测试人员</th>
<th>项目名</th>
<th>项目ID</th>
<th>描述信息</th>
<th>创建时间</th>
<th>用例数</th>
</tr>
<tr :key='item.id' v-for="item in lists">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.tester}}</td>
<td>{{item.project}}</td>
<td>{{item.project_id}}</td>
<td>{{item.desc}}</td>
<td>{{item.create_time}}</td>
<td>{{item.testcases}}</td>
</tr>
</table>
`
})
var vm = new Vue({
el: '#app',
data: {
cases1:[{
"id": 1,
"name": "登录接口_自动化测试平台项目",
"tester": "可优",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "登录接口",
"create_time": "2019-11-06 14:50:30",
"testcases": 9,
},
{
"id": 2,
"name": "注册接口_自动化测试平台项目",
"tester": "可可",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "自动化测试平台项目, 注册接口",
"create_time": "2019-11-06 14:51:00",
"testcases": 0,
}],
cases2:[
{
"id": 3,
"name": "创建项目接口_自动化测试平台项目",
"tester": "可优",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "这是自动化测试平台创建项目接口",
"create_time": "2019-11-06 14:51:45",
"testcases": 1,
},
{
"id": 4,
"name": "注册接口_前程贷P2P金融项目",
"tester": "小可可",
"project": "前程贷P2P金融项目",
"project_id": 2,
"desc": "",
"create_time": "2019-11-06 14:52:22",
"testcases": 0,
},
{
"id": 5,
"name": "登录接口_前程贷P2P金融项目",
"tester": "柠檬小姐姐",
"project": "前程贷P2P金融项目",
"project_id": 2,
"desc": "",
"create_time": "2019-11-06 14:52:40",
"testcases": 0,
},
{
"id": 6,
"name": "查看项目列表接口_前程贷P2P金融项目",
"tester": "柠檬小姐姐",
"project": "前程贷P2P金融项目",
"project_id": 2,
"desc": "",
"create_time": "2019-11-06 17:22:50",
"testcases": 1,
}
]
}
})
</script>
</body>
</html>
子组件往父组件中传数据
-
在子组件中通过$emit来触发一个自定义的事件,并把数据传递过去
$emit('自定义的事件名',传递的数据)
-
父组件在引用子组件时,通过事件监听机制,来监听子组件自定义的事件,并指定方法去处理这个事件
@自定义的事件名 = 处理事件的方法($event)
-
在处理事件的方法中接收数据,并处理
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<data-views :lists="cases1" @run='recvData($event)'></data-views>
<hr>
<div>
<h3>执行的用例信息:{{info}}</h3>
</div>
</div>
<script type="text/javascript">
/*
场景:一般子组件在操作某个数据之后,要将数据传递给父组件,就要用到子组件给父组件传递数据,
实现步骤:
1、在子组件中通过$emit来触发一个自定义的事件,并把数据传递过去
$emit('自定义的事件名',传递的数据)
2、父组件在引用子组件时,通过事件监听机制,来监听子组件自定义的事件,并指定方法去处理这个事件
@自定义的事件名 = 处理事件的方法($event)
3、在处理事件的方法中接收数据,并处理
*/
Vue.component('data-views', {
// 指定父组件中引用该组件时,传递数据的参数名
props:['lists'],
template: `
<table border="" cellspacing="" cellpadding="">
<tr>
<th>ID</th>
<th>接口名</th>
<th>测试人员</th>
<th>项目名</th>
<th>项目ID</th>
<th>描述信息</th>
<th>创建时间</th>
<th>用例数</th>
<th>操作</th>
</tr>
<tr :key='item.id' v-for="item in lists">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.tester}}</td>
<td>{{item.project}}</td>
<td>{{item.project_id}}</td>
<td>{{item.desc}}</td>
<td>{{item.create_time}}</td>
<td>{{item.testcases}}</td>
<th><button @click="$emit('run',item)">执行</button></th>
</tr>
</table>
`
})
var vm = new Vue({
el: '#app',
data: {
cases1:[{
"id": 1,
"name": "登录接口_自动化测试平台项目",
"tester": "可优",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "登录接口",
"create_time": "2019-11-06 14:50:30",
"testcases": 9,
},
{
"id": 2,
"name": "注册接口_自动化测试平台项目",
"tester": "可可",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "自动化测试平台项目, 注册接口",
"create_time": "2019-11-06 14:51:00",
"testcases": 0,
}],
info:''
},
methods:{
// 父组件中监听到子组件触发的事件之后,接收数据的方法
recvData:function(value){
console.log(value)
this.info = value
}
}
})
</script>
</body>
</html>
插槽
一些情况下我们会希望能和 HTML 元素一样向组件中传递内容
父组件在引用子组件时,传递的内容可以使用template标签包裹(通过#slot名
的格式指定传递给目标插槽)
子组件使用 <slot> 作为一个占位符(通过value属性给各个插槽分配唯一的 ID,以确定每一处要渲染的内容),父组件传递进来的内容就会渲染在这里
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<data-views :lists="cases1" @run='recvData($event)'>
<template slot="title">
<span>项目名:柠檬班</span>
<span>版本:V1.0</span>
<span>时间:2021-04-02</span>
</template>
<template slot='body'>
<h4>python+vue真好用</h4>
</template>
</data-views>
<hr>
<div>
<h3>执行的用例信息:{{info}}</h3>
</div>
</div>
<script type="text/javascript">
/*
插槽:定义组件时,给父组件预留填充内容(html)的插口(空白)
*/
Vue.component('data-views', {
// 指定父组件中引用该组件时,传递数据的参数名
props: ['lists'],
template: `
<div>
<slot name='title'></slot>
<h1>-------------子组件---------------</h1>
<slot name='body'></slot>
<table border="" cellspacing="" cellpadding="">
<tr>
<th>ID</th>
<th>接口名</th>
<th>测试人员</th>
<th>项目名</th>
<th>项目ID</th>
<th>描述信息</th>
<th>创建时间</th>
<th>用例数</th>
<th>操作</th>
</tr>
<tr :key='item.id' v-for="item in lists">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.tester}}</td>
<td>{{item.project}}</td>
<td>{{item.project_id}}</td>
<td>{{item.desc}}</td>
<td>{{item.create_time}}</td>
<td>{{item.testcases}}</td>
<th><button @click="$emit('run',item)">执行</button></th>
</tr>
</table>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
cases1: [{
"id": 1,
"name": "登录接口_自动化测试平台项目",
"tester": "可优",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "登录接口",
"create_time": "2019-11-06 14:50:30",
"testcases": 9,
},
{
"id": 2,
"name": "注册接口_自动化测试平台项目",
"tester": "可可",
"project": "自动化测试平台项目",
"project_id": 1,
"desc": "自动化测试平台项目, 注册接口",
"create_time": "2019-11-06 14:51:00",
"testcases": 0,
}
],
info: ''
},
methods: {
// 父组件中监听到子组件触发的事件之后,接收数据的方法
recvData: function(value) {
console.log(value)
this.info = value
}
}
})
</script>
</body>
</html>
单文件组件
<script>
export default {
data() {
return {
greeting: 'Hello World!'
}
}
}
</script>
<template>
<p class="greeting">{{ greeting }}</p>
</template>
<style>
.greeting {
color: red;
font-weight: bold;
}
</style>
elementUI
前后端交互axios
前端发送请求.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script type="text/javascript">
// 使用axios发送一个get请求
// const pro = axios.get('http://127.0.0.1:5000/api/projects11')
// // 此处的res并不是接口的响应 它是一个Promise对象(异步事件的对象)
// console.log(pro)
// ----------------获取接口返回的数据(请求成功)-------------------
// pro.then(function(response){
// // 这个回调函数的中的response才是接口返回的响应对象
// console.log('接口的响应数据:',response)
// // 获取响应体
// console.log(response.data)
// //获取响应的状态码
// console.log((response.status))
// })
// console.log('999999999999999999')
// ----------------获取接口返回的数据(请求失败:返回的状态码是4,5系列的)-------------------
// pro.catch(function(error) {
// // 获取请求失败的响应对象
// console.log(error.response)
// let response = error.response
// console.log(response.data)
// console.log(response.headers)
// })
// 自定义HTTP状态码错误的范围
const pro = axios.get('http://127.0.0.1:5000/api/projects11', {
validateStatus: function(status) {
// 指定HTTP状态码错误的范围
// return status < 500;
return true
}
})
pro.then(function(response) {
// 这个回调函数的中的response才是接口返回的响应对象
console.log('接口的响应数据:', response)
// 获取响应体
console.log(response.data)
//获取响应的状态码
console.log((response.status))
})
</script>
</body>
</html>
axios创建请求对象.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script type="text/javascript">
// 使用axios创建请求对象
const request = axios.create({
// 指定请求HTTP响应码错误范围
validateStatus: function(status) {
return true
},
// 指定基本的url地址
baseURL: "http://127.0.0.1:5000",
// 添加固定的请求头
headers: {
'X-Custom-Header': 'foobar'
},
})
//使用请求对象
request.get('/api/projects').then(function(response) {
console.log(response.status)
})
request.get('/api/projects11').then(function(response) {
console.log(response.status)
})
</script>
</body>
</html>
axios发生get请求的参数传递.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script type="text/javascript">
// 使用axios创建请求对象
const request = axios.create({
// 指定请求HTTP响应码错误范围
validateStatus: function(status) {
return true
},
// 指定基本的url地址
baseURL: "http://127.0.0.1:5000",
// 添加固定的请求头
headers: {
'X-Custom-Header': 'foobar'
},
})
//get方法传递查询字符串参数
// 方式一 :通过params传递 get('url',{params:{key:value,key:value}})
//
// request.get('/api/interface',{
// params:{id:1001}
// }).then(function(response) {
// console.log(response.status)
// console.log(response.data)
// })
// 方式二:直接在url后面拼接 url?key=value&key=value
//
// request.get('/api/interface?id=1001').then(function(response) {
// console.log(response.status)
// console.log(response.data)
// })
</script>
</body>
</html>
json和表单参数的处理.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script type="text/javascript">
// 使用axios创建请求对象
const request = axios.create({
// 指定请求HTTP响应码错误范围
validateStatus: function(status) {
return true
},
// 指定基本的url地址
baseURL: "http://127.0.0.1:5000",
// 添加固定的请求头
headers: {
'X-Custom-Header': 'foobar'
},
})
// 发送post请求
// json格式的参数传递: content-Type:application/json
// request.post('/api/user/login',{user:'python01',pwd:'lemonban'}).then(function(response){
// console.log(response.data)
// console.log(response.status)
// })
// 表单参数传递:content-Type:application/x-www-form-urlencoded format
// 创建表单参数对象
// const formData = new URLSearchParams();
// formData.append('user', 'python01')
// formData.append('pwd', 'lemonban')
// request.post('/api/user/login', formData).then(function(response) {
// console.log(response.data)
// console.log(response.status)
// })
</script>
</body>
</html>
请求拦截器和响应拦截器.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script type="text/javascript">
// 使用axios创建请求对象
const request = axios.create({
// 指定请求HTTP响应码错误范围
validateStatus: function(status) {
return true
},
// 指定基本的url地址
baseURL: "http://127.0.0.1:5000",
// 添加固定的请求头
})
// 添加请求拦截器:每次请求接口都会自动调用
request.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
// 接口需要鉴权:token
console.log('请求拦截器:',config)
return config;
});
// 添加响应拦截器:每次请求完之后,A返回响应数据之前会调用。
request.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response.data;
}, function (error) {
// 对响应错误做点什么
return error.response;
});
//使用请求对象
request.get('/api/projects').then(function(data) {
console.log(data)
})
</script>
</body>
</html>
async和await的使用.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script type="text/javascript">
// 使用axios创建请求对象
const request = axios.create({
// 指定请求HTTP响应码错误范围
validateStatus: function(status) {
return true
},
// 指定基本的url地址
baseURL: "http://127.0.0.1:5000",
// 添加固定的请求头
})
// 添加请求拦截器:每次请求接口都会自动调用
request.interceptors.request.use(function(config) {
// 在发送请求之前做些什么
// 接口需要鉴权:token
console.log('请求拦截器:', config)
return config;
});
// 添加响应拦截器:每次请求完之后,A返回响应数据之前会调用。
request.interceptors.response.use(function(response) {
// 对响应数据做点什么
return response;
}, function(error) {
// 对响应错误做点什么
return error.response;
});
// 使用请求对象
// 注意点:await 和只能在通过async定义的函数中使用
async function getProjec() {
const response = await request.get('/api/projects')
console.log(response)
}
getProjec()
</script>
</body>
</html>
登录案例.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- axios 用来发送网络请求 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 引入elementUI -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<div class="box" style="width: 600px;height: 400px; margin:100px auto;text-align: center;">
<el-card class="box-card">
<h1> 用户登录</h1>
<el-form ref="formLogin" :model="formLogin" label-width="80px">
<el-form-item label="账号">
<el-input v-model="formLogin.user"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="formLogin.pwd" type='password'></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loginHandle">点击登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
<hr>
<button type="button" @click="getProject()">获取所有项目</button>
<div class="box2">
<el-table
:data="projects"
style="width: 100%">
<el-table-column
prop="id"
label="ID"
width="60">
</el-table-column>
<el-table-column
prop="create_time"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="项目名"
width="180">
</el-table-column>
<el-table-column
prop="testcases"
label="用例数">
</el-table-column>
</el-table>
</div>
</div>
<script type="text/javascript">
const request = axios.create({
// 指定请求HTTP响应码错误范围
validateStatus: function(status) {
return true
},
// 指定基本的url地址
baseURL: 'http://api.keyou.site:8000',
})
// 添加请求拦截器:每次请求接口都会自动调用
request.interceptors.request.use(function(config) {
// 在发送请求之前,判断是否有token
if (window.sessionStorage.getItem('token')) {
config.headers.Authorization = 'JWT ' + window.sessionStorage.getItem('token')
}
console.log('请求头', config.headers)
return config;
})
var vm = new Vue({
el: '#app',
data: {
formLogin: {
username: 'musen123',
password: '1234567'
},
projects: [],
},
methods: {
// 点击登录之后,处理登录的方法
loginHandle: async function() {
// 请求登录接口
console.log('请求登录接口')
const response = await request.post('/user/login/', this.formLogin)
console.log(response)
// 判断登录请求是否成功
if(response.status ===200){
alert('登录成功')
window.sessionStorage.setItem('token', response.data.token)
}else{
alert('登录失败')
}
},
getProject: async function() {
// 请求项目列表
console.log('请求项目列表接口')
const response = await request.get('/projects/')
console.log(JSON.stringify(response.data))
this.projects = response.data.results
}
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<!-- axios 用来发送网络请求 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<button type="button" onclick="login()"> 登录</button><!--
<button type="button" οnclick="getProject()"> 获取项目</button> -->
</head>
<body>
<script type="text/javascript">
const request = axios.create({
// 指定请求HTTP响应码错误范围
validateStatus: function(status) {
return true
},
// 指定基本的url地址
baseURL: 'http://api.keyou.site:8000',
})
// 添加请求拦截器:每次请求接口都会自动调用
request.interceptors.request.use(function(config) {
// 在发送请求之前,判断是否有token
if (window.sessionStorage.getItem('token')) {
config.headers.Authorization = 'JWT ' + window.sessionStorage.getItem('token')
}
return config;
})
async function login() {
console.log('请求登录接口')
const response = await request.post('/user/login/', {
username: 'musen123',
password: '1234567'
})
console.log(response)
// 判断登录请求是否成功
if (response.status === 200) {
alert('登录成功')
window.sessionStorage.setItem('token', response.data.token)
} else {
alert('登录失败')
}
}
async function getProject() {
console.log('请求项目列表接口')
const response = await request.get('/projects/')
console.log(JSON.stringify(response.data))
}
// // 调用登录函数
login()
// // 调用获取项目的函数
// getProject()
</script>
</body>
</html>
路由vue-router
vue-route基本使用
1、初始化路由对象和定义路由对象
2、将路由对象绑定到vue实例中去
3、在根组件中定义路由视图的展示位置
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js" type="text/javascript"></script>
<!-- 引入vue -->
</head>
<body>
<div id="app">
<!-- <router-link to="/home">主页</router-link> -->
<!-- <router-link to="/login">登录</router-link> -->
<!-- 路由视图 -->
<router-view></router-view>
</div>
<script type="text/javascript">
/*
第一步:定义展示页面内容的组件
第二步:定义路由规则
第三步:初始化路由对象
第四步:将路由对象绑定到vue实例中去
第五步:在根组件中定义路由视图的展示位置
注意点:如果在html页面中使用vuerouter 在使用script引入的时候 一定要放在vue下面
路由配置:
path:指定路由路径
name:给路由命名
redirect:指定路由重定向的路径
component:指定该路由渲染的组件
*/
// 首页
const home = {
template: `<h1>这个是项目首页</h1>
`
}
// 登录页面
const login = {
template: `
<h1>这个是项目登录页面</h1>
`
}
// 创建一个路由对象
const router = new VueRouter({
//通过路由routes指定路由规则
routes: [{
path: '/',
// 设置路由重定向
redirect: '/login'
},
{
path: '/login',
component: login,
// 给路由设置名字
name:'login'
},
{
path:'/home',
component:home
}
]
})
var vm = new Vue({
el: '#app',
// 将路由对象绑定到vue实例中
router
});
</script>
</body>
</html>
编程式路由和声明式路由
-
声明式路由
<router-link :to="{ name: 'user', params: { username: 'erina' }}"> User </router-link>
-
编程式路由
router.push({ name: 'user', params: { username: 'erina' } })
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js" type="text/javascript"></script>
<!-- 引入vue -->
</head>
<body>
<div id="app">
<div class="box">
<!-- 这个路由访问的方式,叫做声明式路由 -->
<router-link to="/home"><button type="button">用户页面</button></router-link>
<router-link to="/login"><button type="button">登录页面</button> </router-link>
<router-link to="/user/1"><button type="button">用户</button> </router-link>
<router-link to="/user/2"><button type="button">用户</button> </router-link>
<input type="text" v-model="number">
<button type="button" @click="handle">提交数据</button>
</div>
<router-view></router-view>
</div>
<script type="text/javascript">
// 首页
const home = {
template: `<h1>这个是项目首页</h1>
`
}
const cases = {
template: `<h1>case页面</h1>
`
}
// 登录页面
const login = {
template: `
<h1>这个是项目登录页面</h1>
`
}
const user = {
template: `
<h1>这个是项目user页面---{{ $route.params.id }}</h1>
`
}
// 创建一个路由对象
const router = new VueRouter({
//通过路由route指定路由规则
routes: [{
path: '/login',
// 给路由设置名字
name: 'login',
component: login
},
{
path: '/home',
component: home
},
{
path: '/case',
component: cases
},
{ // 路由地址上匹配的参数,在路由对应的组件中可以使用 $route.params.参数名 获取
path: '/user/:id',
component: user,
name: 'user'
},
]
})
var vm = new Vue({
el: '#app',
data: {
number: 0
},
methods: {
handle: function() {
if (this.number > 5) {
// 编程式路由
//跳转到另外一个页面
this.$router.push({
name: 'user',
params: {
id: this.number
}
})
}
}
},
// 将路由对象绑定到vue实例中
router
});
</script>
</body>
</html>
登录进入首页案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- axios 用来发送网络请求 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 引入vue-router用来管理路由 -->
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js" type="text/javascript"></script>
<!-- 引入elementUI -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<div></div>
<script type="text/javascript">
const request = axios.create({
// 指定请求HTTP响应码错误范围
validateStatus: function(status) {
return true
},
// 指定基本的url地址
baseURL: 'http://api.keyou.site:8000',
})
// 添加请求拦截器:每次请求接口都会自动调用
request.interceptors.request.use(function(config) {
// 在发送请求之前,判断是否有token
if (window.sessionStorage.getItem('token')) {
config.headers.Authorization = 'JWT ' + window.sessionStorage.getItem('token')
}
console.log('请求头', config.headers)
return config;
})
// 定义组件
const login = {
template: `
<div class="login_box" style="width: 600px;height: 400px; margin: 50px auto;text-align: center;">
<el-card class="box-card">
<h1>用 户 登 录</h1>
<el-form ref="form" :model="formLogin" label-width="80px">
<el-form-item label="账号">
<el-input v-model="formLogin.username"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="formLogin.password" type='password'></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loginHandle">点击登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
`,
data() {
return {
formLogin: {
username: '',
password: ''
}
}
},
methods: {
// 点击登录之后,处理登录的方法
loginHandle: async function() {
// 请求登录接口
console.log('请求登录接口')
const response = await request.post('/user/login/', this.formLogin)
console.log(response)
// 判断登录请求是否成功
if (response.status === 200) {
alert('登录成功')
window.sessionStorage.setItem('token', response.data.token)
this.$router.push('/home')
} else {
alert('登录失败')
}
}
}
}
// const home = {
// template: `<div>
// <el-menu
// @select = 'handle'
// class="el-menu-demo"
// mode="horizontal"
// background-color="#545c64"
// text-color="#fff"
// active-text-color="#ffd04b">
// <el-menu-item index="/cases">用例列表</el-menu-item>
// <el-menu-item index="/interface">接口列表</el-menu-item>
// <el-menu-item index="/projects">项目列表</el-menu-item>
// </el-menu>
// <router-view></router-view>
// </div>`,
// methods:{
// handle(index,indexPath){
// console.log(index),
// this.$router.push(index)
// }
// }
// }
const home = {
template: `<div>
<el-menu
:router = 'rou'
background-color='#555500'
class="el-menu-demo"
mode="horizontal"
default-active='/cases'
text-color="#fff"
active-text-color="#00aaff">
<el-menu-item :index="{name:'case'}">用例列表</el-menu-item>
<el-menu-item :index="apiListRouter">接口列表1</el-menu-item>
<el-menu-item index="/interface">接口列表2</el-menu-item>
<el-menu-item index="/projects">项目列表</el-menu-item>
</el-menu>
<router-view></router-view>
</div>`,
data(){
return{
rou : true,
apiListRouter: {name:'interface'}
}
}
}
const project = {
template: `<div>project </div>`
}
const cases = {
template: `<div> cases</div>`
}
const interface = {
template: `<div>interface</div>`
}
// 定义路由规则
const router = new VueRouter({
routes: [{
path: '/',
redirect: '/home'
},
{
path: '/login',
component: login
},
{
path: '/home',
component: home,
redirect:'/cases',
children: [{
path: '/projects',
component: project
},
{
path: '/cases',
component: cases
},
{
path: '/interface',
name: 'interface',
component: interface
}
]
},
]
})
// 添加路由导航守卫
// 用例对访问的路由进行权限控制
// 除了login这个路由其他的路由都要进行了登录之后才能访问
router.beforeEach((to, from, next) => {
// console.log(to)
// console.log(from)
// console.log(next)
// 判断访问的是否是登录页面
if (to.path === '/login') {
return next()
// 判断当前sessionStorage中是否有token(判断是否登录过)
} else if (window.sessionStorage.getItem('token')) {
return next()
} else {
return next('/login')
}
})
// 初始vue对象
var vm = new Vue({
el: '#app',
router: router,
data: {
},
methods: {
}
})
</script>
</body>
</html>
vue-cli
- 安装vue/cli脚手架
- 基于脚手架创建vue项目
VUE3
setUp使用
computed使用
- 多对一,多个数据影响一个
- 缓存特性,避免每次获取值时都要重新计算
- 如果属性值是函数,默认使用get方法,函数的返回值就是属性的属性值。还有一个set方法,当数据变化时就会调用set方法
import { ref, reactive, computed } from 'vue'
const loginBtnState = computed(() => {
const { mobile, loginCode } = phoneForm
if (mobile.length !== 11 || loginCode.length <= 0) return true
else return false
})
const loginCodeBtnState = computed(() => {
if (
codeTip.value === '验证码' &&
phoneForm.mobile.length === 11 &&
/^1[3456789]\d{9}$/.test(phoneForm.mobile)
) { return false } else return true
})
const model = computed({
get() {
return props.modelValue
},
set(val: any) {
emit('updateModel', val)
}
})
# useInit.ts
import { computed } from 'vue'
import { TableOptions } from '../index.types'
export const useInit = (props: Partial<Record<string, any>>) => {
const tableOption = computed(() => {
return props.options?.filter((option: TableOptions) => !option.action)
})
const actionOption = computed(() => {
return props.options?.find((option: TableOptions) => option.action)
})
const paginationJustify = computed(() => ({
justifyContent: props.paginationJustify
}))
return {
tableOption,
actionOption,
paginationJustify
}
}
watch使用
- 一对多,一个数据发生变化,执行相应操作会影响多个数据
- 允许执行异步操作 ( 访问一个 API )
// 监听当前项目名
watch(
() => currentProject.value,
newVal => {
cache.session.set('project_name', newVal)
}
)
// 监听项目搜索框内容
watch(
() => input.value,
newVal => {
listProject({name: newVal}).then(response => {
items.value = response.rows;
});
}
)
定义接收属性props
const props = defineProps({
projectName: {
type: String,
default: '请选择项目'
},
})
定义上报事件emit
const emits = defineEmits(['update:modelValue', 'on-success', 'on-discard']);
父子组件传参
父组件传数据给子组件
- 父组件在引用子组件时,通过属性绑定的形式(即:自子组件自定义的属性名)传递参数
<Form
:model-value="formData"
:options="formOptions"
label-width="120px" />
- 子组件在props中声明需要接收的变量名,用props.变量名获取和设置新值(在template部分使用时:可直接使用变量名)
# Form/index.vue
const props = defineProps({
modelValue: {
type: Object as PropType<UnwrapNestedRefs<Record<string, any>>>,
default: () => ({})
},
options: {
type: Array as PropType<FormOptions[]>,
required: true
}
});
子组件传数据给父组件
-
在子组件中使用emit自定义事件,并通过组件绑定的事件,上报自定义事件,把数据传递过去
const emit = defineEmits(['toIndexCancel', 'checkDetail']); const handelCancel = (appointmentId: number) => { emit('toIndexCancel', appointmentId); }; const handleClickCheckDetail = (appointmentId: number) => { // 查询当前项 const content = currentList.value.find(item => item.appointmentId === appointmentId); emit('checkDetail', content); };
-
父组件在引用子组件时,监听子组件自定义的事件,并指定方法去处理这个事件
@自定义的事件名 = 处理事件的方法
<detail ref="detailRef" :select-date="currentDate" v-model="dialogVisible" @checkDetail="handleClickCheckDetail" @toIndexCancel="cancel" />
注意:template中使用自定义事件名,可以用“-字母小写"代替"字母大写”,比如
@update:model-value="emit('update:modelValue', false)"
-
在处理事件的方法中接收数据,并处理
const handleClickCheckDetail = (item: WorkCalendarItem) => { dialogVisible.value = false; handleClickContent(item); }; /** * 删除预约记录后刷新 */ const cancel = () => { dialogVisible.value = false; queryData(); };