1、bootstrop框架
1、 bootstrop框架是一个用于制作页面界面的框架,运用bootstrop框架中的布局属性,可以对页面进行合理快捷的布局,布局分为了以下几种:响应式布局、断点、布局容器、网格布局。
2、运用bootstrop框架的步骤:首先需要在html代码中引入“bootstrap.css” 和“bootstrap.bundl.js”文件,才能使用bootstrop中自带的属性样式,其次在标签的class属性中添加对应的样式属性值就可以引用对应的样式了。
3、运用bootstrop表单验证实现表单信息验证功能,代码如下:
<!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</title>
<link rel="stylesheet" href="css/bootstrap.css">
<script src="js/bootstrap.bundle.js"></script>
</head>
<body class="d-flex justify-content-center">
<form class="card p-3" style="width: 400px" onsubmit="return false" novalidate>
<div class="vstack gap-3">
<div class="row">
<label class="col-3 col-form-label">姓名</label>
<div class="col">
<input name="name" type="text" class="form-control">
<div class="invalid-feedback">
error
</div>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label">年龄</label>
<div class="col">
<input name="age" type="number" class="form-control">
<div class="invalid-feedback">
error
</div>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label">简介</label>
<div class="col">
<textarea maxlength="200" name="desc" rows="4" class="form-control"></textarea>
<div class="invalid-feedback">
error
</div>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label">班级</label>
<div class="col">
<select name="clazz" class="form-select">
<option value="" selected disabled>请选择</option>
<option value="一班">一班</option>
<option value="二班">二班</option>
<option value="三班">三班</option>
</select>
<div class="invalid-feedback">
error
</div>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label">爱好</label>
<div class="col d-flex flex-column justify-content-center">
<div>
<div class="form-check form-check-inline">
<input id="qin" type="checkbox" name="hobbies" value="qin" class="form-check-input">
<label for="qin" class="form-check-label">琴</label>
</div>
<div class="form-check form-check-inline">
<input id="qi" type="checkbox" name="hobbies" value="qi" class="form-check-input">
<label for="qi" class="form-check-label">棋</label>
</div>
<div class="form-check form-check-inline">
<input id="shu" type="checkbox" name="hobbies" value="shu" class="form-check-input">
<label for="shu" class="form-check-label">书</label>
</div>
<div class="form-check form-check-inline">
<input id="hua" type="checkbox" name="hobbies" value="hua" class="form-check-input">
<label for="hua" class="form-check-label">画</label>
</div>
</div>
<div>
<!-- type="hidden" 隐藏域 -->
<input id="hobbies" type="hidden" class="form-control">
<div class="invalid-feedback">
error
</div>
</div>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label">是否入党</label>
<div class="col d-flex align-items-center">
<div class="form-switch">
<input id="rd" type="checkbox" name="rd" class="form-check-input">
<!-- <label for="rd" class="form-check-label">入党</label>-->
</div>
</div>
</div>
<div class="row">
<div class="col-3"></div>
<div class="col">
<button class="btn btn-primary w-100">提交</button>
</div>
</div>
</div>
</form>
</body>
<script>
// html 自带的自动表单验证
// bootstrap 自动表单验证 was-validated
// bootstrap 手动表单验证 is-valid is-invalid
const btn = document.querySelector('button');
const form = document.querySelector('form');
const nameEl = document.querySelector('input[name=name]');
const ageEl = document.querySelector('input[name=age]');
const descEl = document.querySelector('textarea[name=desc]');
const clazzEl = document.querySelector('select[name=clazz]');
const hobbiesEl = document.querySelector('#hobbies');
const nameTip = document.querySelector('input[name=name]+.invalid-feedback');
const ageTip = document.querySelector('input[name=age]+.invalid-feedback');
const descTip = document.querySelector('textarea[name=desc]+.invalid-feedback');
const clazzTip = document.querySelector('select[name=clazz]+.invalid-feedback');
const hobbiesTip = document.querySelector('#hobbies+.invalid-feedback');
function reset() {
nameEl.classList.remove('is-valid', 'is-invalid')
ageEl.classList.remove('is-valid', 'is-invalid')
descEl.classList.remove('is-valid', 'is-invalid')
clazzEl.classList.remove('is-valid', 'is-invalid')
hobbiesEl.classList.remove('is-valid', 'is-invalid')
}
btn.addEventListener('click', () => {
reset()
let fd = new FormData(form)
// 读取数据
let name = fd.get('name')
let age = fd.get('age')
let desc = fd.get('desc')
let clazz = fd.get('clazz')
let hobbies = fd.getAll('hobbies')
let rd = fd.get('rd')
// 姓名是否有效
let nameValid = checkName(name)
// 赋值错误提示
nameTip.textContent = nameValid
// 赋值元素验证样式
nameEl.classList.add(nameValid === '' ? 'is-valid' : 'is-invalid')
let ageValid = checkAge(age)
ageTip.textContent = ageValid
ageEl.classList.add(ageValid === '' ? 'is-valid' : 'is-invalid')
let descValid = checkDesc(desc);
descTip.textContent = descValid
descEl.classList.add(descValid === '' ? 'is-valid' : 'is-invalid')
let clazzValid = checkClazz(clazz);
clazzTip.textContent = clazzValid
clazzEl.classList.add(clazzValid === '' ? 'is-valid' : 'is-invalid')
let hobbiesValid = checkHobbies(hobbies);
hobbiesTip.textContent = hobbiesValid
hobbiesEl.classList.add(hobbiesValid === '' ? 'is-valid' : 'is-invalid')
})
// 验证姓名
// 返回 字符串 若为空字符串则验证通过 否则字符串为错误提示
function checkName(name) {
name = name.trim()
if (name === '') return '请输入姓名'
if (name.length < 2 || name.length > 50) return '姓名长度需要在2~50字之间'
let regex = /^((?!共产党).)*$/
if (!regex.test(name)) return '姓名不能包含“共产党”'
return ''
}
function checkAge(age) {
if (age.trim() === '') return '请输入年龄'
age = Number(age)
if (age < 0 || age > 200) return '请输入0~200的年龄'
return ''
}
function checkDesc(desc) {
desc = desc.trim()
if (desc === '') return ''
let regex = /^((?!张三|奇迹).)*$/
if (!regex.test(desc)) return '简介不能包含"张三"和"奇迹"'
if (desc.length > 200) return '简介长度不能大于200'
return ''
}
function checkClazz(clazz) {
if (clazz === null) return '请选择班级'
return ''
}
function checkHobbies(hobbies) {
if (hobbies.length > 3) return '爱好不能超过3个'
return ''
}
</script>
</html>
此代码可以实现对表单中的信息进行验证,如果输入的信息格式内容不符合要求,就会显示错误提示。效果如下:
2、React
1、React是一个js核心库,它具备的特点是:(1)声明式:也就是js中的数据决定页面最终渲染的结果;声明式不是响应式,但往往都是同时出现共同作用页面;响应式:数据变化页面会立即更新.(2)组件化: 一个包含所有外观和行为的,独立可运行的模块,称为组件;组件化的思想可以将复杂页面,化繁为简的进行设计; 组件可提高代码复用性;一次学习,跨平台编写;使用 `react` 可以开发 桌面web页面,移动端页面,移动app,桌面app等。
2、react的使用步骤:首先需要引入react核心库和react-dom库,同时为了更方便的书写react通常会使用jsx语法,就需要引入babel文件,最后就可以编写react代码了。
3、react最常用的写法是组件化,将页面中会重复引用的外观和行为进行封装,变成一个可以独立运行的模块,可以直接在页面中引用,提高代码的复用性,如果需要修改组件中的某个内容,修改一次就可以将页面多个地方进行统一修改。
4、react的应用,实现多表单控制,使用 react 制作一个用于录入用户信息的表单组件,表单项有以下内容: 姓名、性别、 年龄,表单组件包含一个重置按钮,点击后重置。页面结构如下:
// 请制作一个父组件 App
<App>
// 父组件中包含两个表单组件
<Form />
<Form />
// 在父组件中点击该按钮
// 读取两个表单组件中的值
<button>读取两个表单的数据</button>
// 父组件中能够重置所有表单
<button>重置所有表单</button>
</App>
class MyForm extends React.Component {
state = {
name:'',
sex: '其他',
age:''
}
onClick1() {
console.log(this.state.name)
console.log(this.state.sex);
console.log(this.state.age);
}
onNameInput(ev){
this.setState({name: ev.target.value})
}
onSexChange(ev) {
this.setState({sex: ev.target.value})
}
onAgeChange(ev){
this.setState({age: Number(ev.target.value)})
}
onClick2() {
this.clear()
}
clear(){
this.setState(
{
name:'',
sex: '其他',
age:''
}
)
}
render() {
return (
<div>
<div className="card p-3 rounded-0" style={{width: '400px'}}>
<div className="vstack gap-3">
<div className="row">
<label className="col-3 col-form-label">姓名</label>
<div className="col">
<input onInput={this.onNameInput.bind(this)}
value={this.state.name}
name="name" type="text" className="form-control"/>
</div>
</div>
<div className="row">
<label className="col-3 col-form-label">性别</label>
<div className="col d-flex align-items-center">
<div className="form-check form-check-inline">
<input onChange={this.onSexChange.bind(this)}
id="male"
checked={this.state.sex === '男'}
className="form-check-input" type="radio"
value="男"/>
<label htmlFor="male" className="form-check-label">男</label>
</div>
<div className="form-check form-check-inline">
<input onChange={this.onSexChange.bind(this)}
id="female"
checked={this.state.sex === '女'}
className="form-check-input" type="radio"
value="女"/>
<label htmlFor="female" className="form-check-label">女</label>
</div>
<div className="form-check form-check-inline">
<input onChange={this.onSexChange.bind(this)}
id="other"
checked={this.state.sex === '其他'}
className="form-check-input" type="radio"
value="其他"/>
<label htmlFor="other" className="form-check-label">其他</label>
</div>
</div>
</div>
<div className="row">
<label className="col-3 col-form-label">年龄</label>
<div className="col">
<input onInput={this.onAgeChange.bind(this)}
value={this.state.age}
name="age" type="text" className="form-control"/>
</div>
</div>
<div className="row">
<div className="col">
<button onClick={this.onClick1.bind(this)} className="btn btn-primary w-100 ">提交
</button>
</div>
<div className="col">
<button onClick={this.onClick2.bind(this)} className="btn btn-warning w-100">重置
</button>
</div>
</div>
</div>
</div>
</div>
)
}
}
以上代码将如下表单样式封装成一个组件,在主组件或者其他页面中就可以直接调用如下样式:
调用方法:
3、应用
在最后几天,将这阶段学习的bootstrop和react知识结合在一起制作了一个bbs论坛项目,实现了简单的页面跳转功能,在项目的完成和不断完善过程中,我对本阶段学习的内容有了更加深刻学习和理解,方法使用的也更加熟练,让我有了很大的收获。
其中遇到的最不好解决的问题就是对于项目中引用图片和不同页面跳转时的路径的写法不准确,在组件中使用绝对路径会更加准确,但是将项目用不同软件打开时,绝对路径的写法也会不同,一般情况下,绝对路径是相对于电脑盘符的路径,在本项目中的绝对路径是相对于服务器的绝对路径。在其他情况下,使用相对路径会比较合适。
在项目完成后做的不好的地方有:
(1)密码不应该明文显示,应该用‘***’代替将其隐藏;
(2)受控组件select不应该添加selected,这里要添加value属性。