我们刚开始学习JS代码时,我们只需要掌握JS中对应知识点就好,随着对JS代码的熟悉程度,我们就要思考如何写出更优雅,更简洁的代码。
接下来我分享10种常用JS代码功能,通过常规写法和优雅写法的对比,来体现其优雅和简洁性。代码中用了ES6新特性,如果你对ES6不了解,可以先收藏好。在后期的VUE中,基本都在和ES6打交道。
常规写法
利用concat方法来合并数组
const apples = ["红苹果", "绿苹果"];
const fruits = ["西瓜", "草莓", "葡萄"].concat(apples);
console.log(fruits); // ['西瓜', '草莓', '葡萄', '红苹果', '绿苹果']
优雅写法
利用ES6中的...扩展运算符来合并数组
const apples = ["红苹果", "绿苹果"];
const fruits = ["西瓜", "草莓", "葡萄", ...apples];
console.log(fruits);//['西瓜', '草莓', '葡萄', '红苹果', '绿苹果']
常规写法
利用数组下标一个一个从数组中取数据
const num = [1, 2];
const num1 = num[0];
const num2 = num[1];
console.log(num1, num2); //1 2
优雅写法
利用ES6的解构赋值来取值
const num = [1, 2];
const [num1, num2] = num;
console.log(num1, num2);
常规写法
对象.属性名 的方式获取属性值
const user = {
name: "张三",
age: 30,
};
const name = user.name;
const age = user.age;
console.log(name, age);//"张三" 30
优雅写法
利用ES6的解构赋值来实现
const user = {
name: "张三",
age: 30,
};
const { name, age } = user;
console.log(name, age); // 张三 30
常规写法
利用for循环来遍历数组,从而取值
const fruits = ["西瓜", "草莓", "葡萄", "苹果"];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
优雅写法
利用ES6的for ... of来遍历数组取值
const fruits = ["西瓜", "草莓", "葡萄", "苹果"];
for (fruit of fruits) {
console.log(fruit);
}
常规写法
forEach中回调函数为普通函数
const fruits = ["西瓜", "草莓", "葡萄", "苹果"];
fruits.forEach(function (fruit) {
console.log(fruit); //西瓜 草莓 葡萄 苹果
});
优雅写法
forEach中回调函数为箭头函数,如果箭头函数中只有一句代码,则可以省略{ }
const fruits = ["西瓜", "草莓", "葡萄", "苹果"];
fruits.forEach((fruit) => console.log(fruit)); //西瓜 草莓 葡萄 苹果
常规写法
数组中保存着每一条水果的信息,我们通过输入水果名,到数组中查找到对应的信息。
利用常规的for循环遍历来查找。
const fruits = [
{ name: "苹果", order: 1 },
{ name: "李子", order: 4 },
{ name: "香蕉", order: 2 },
];
function getApples(arr, value) {
for (let index = 0; index < arr.length; index++) {
if (arr[index].name === value) {
return arr[index];
}
}
}
const result = getApples(fruits, "苹果");
console.log(result); // { name: "苹果", order: 1 }
优雅写法
利用数组的find方法来实现搜索
const fruits = [
{ name: "苹果", order: 1 },
{ name: "李子", order: 4 },
{ name: "香蕉", order: 2 },
];
function getApples(arr, value) {
return arr.find((obj) => obj.name === value);
}
const result = getApples(fruits, "李子");
console.log(result);
常规写法
利用parseInt来实现
const num = parseInt("10");
console.log(num,typeof num); // 10 "number"
优雅写法
利用+ 号来实现,不过只针对纯数字的字符串有效
const num = +"10";
console.log(num,typeof num); //=> 10 "number"
console.log(+"10" === 10); // true;
常规写法
通过if判断,如果为null,则初始化值为“普通用户”
//获取用户角色
function getUserRole(role) {
let userRole;
if (role) {
userRole = role;
} else {
userRole = "普通用户";
}
return userRole;
}
console.log(getUserRole()); //普通用户
console.log(getUserRole("管理员")); //管理员
优雅写法
通过 || 或短路运算符来实现
function getUserRole(role) {
return role || "普通用户"; // 默认值定义的常见方法
}
console.log(getUserRole()); // "普通用户"
console.log(getUserRole("管理员")); // "管理员";
常规写法
const name = "张三";
const age = 23;
const message = "大家好,我叫" + name + "今年" + age + "岁了!";
console.log(message); //大家好,我叫张三,今年23岁了!
优雅写法
const name = "张三";
const age = 23;
const message = `大家好,我叫${name},今年${age}岁了!`;
console.log(message); // Hi DevPoint!
常规写法
利用for循环来遍历
const employee = { name: "张三", age: 30 };
const salary = { grade: "A" };
const summary = salary; //用来做合并后对象
for (const key in employee) {
summary[key] = employee[key];
}
console.log(summary); // {grade: 'A', name: '张三', age: 30}
优雅写法
利用es6的扩展运算符和解构赋值来实现
const employee = { name: "张三", age: 30 };
const salary = { grade: "A" };
const summary = { ...employee, ...salary };
console.log(summary); // { name: '张三', age: 30, grade: 'A' }
最后我想告诉大家一个好消息,为了帮助关注我的同学,我们创建了《30天挑战学习计划》,全程免费,不涉及任何费用和利益,具体内容为以下4部分
1、HTML5+CSS3核心知识
2、30个HTML5+CSS3案例
3、2个PC+移动+响应式综合项目实战
4、网站全面上云部署与发布
接下来我来详细介绍下这个课程体系!
为帮助到一部分同学不走弯路,真正达到一线互联网大厂前端项目研发要求,首次实力宠粉,打造了《30天挑战学习计划》,内容如下:
HTML/HTML5,CSS/CSS3,JavaScript,真实企业项目开发,云服务器部署上线,从入门到精通
共4大完整的项目开发 !一行一行代码带领实践开发,实际企业开发怎么做我们就是怎么做。从学习一开始就进入工作状态,省得浪费时间。
从学习一开始就同步使用 Git 进行项目代码的版本的管理,Markdown 记录学习笔记,包括真实大厂项目的开发标准和设计规范,命名规范,项目代码规范,SEO优化规范
从蓝湖UI设计稿 到 PC端,移动端,多端响应式开发项目开发
这些内容在《30天挑战学习计划》中每一个细节都有讲到,包含视频+图文教程+项目资料素材等。只为实力宠粉,真正一次掌握企业项目开发必备技能,不走弯路 !
过程中【不涉及】任何费用和利益,非诚勿扰 。
如果你没有添加助理老师微信,可以添加下方微信,说明要参加30天挑战学习计划,来自头条号!老师会邀请你进入学习,并给你发放相关资料
30 天挑战学习计划 Web 前端从入门到实战 | arry老师的博客-艾编程
种包管理器到ESLint,从CommonJS到AMD,再从ES6模块到Babel和Webpack,好多工具啊!
好累……
是的,今天我觉得很疲劳。我不禁想,我本应该继续我的销售职业,不应该抄近路做前端开发。但我意识到,前端开发是给勇敢者准备的,而勇敢者绝不会放弃,他们才是人生赢家。
所以我决定做人生赢家,我要写点东西给前端开发和工具链疲劳的受害者们看。我要写一下我是怎样将初学者级别的代码变成令人赞叹的产品级代码的,以及这个过程中我用到的工具。
现在开始吧!
我们在做的东西
其实没什么令人激动的东西。我们做了个Web应用,从某个API读取一些随机的用户,然后显示在前端上。它没有路由的能力。本文的最终目标是让你熟悉前端的工具链。
我们的AngularJS代码中没有使用样板代码,所以我们不会被CLI的那些黑科技搞得晕头转向。注意我用的是AngularJS,不是Angular。使用AngularJS的原因是我找不到任何关于AngularJS工具链和打包的文章。
首先在根目录下建一个index文件。
<html>
<head>
<title>Random User!</title>
<link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre.min.css">
</head>
<body>
<div class="container">
<h1 class="text-center">Random User!</h1>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.0/angular.min.js"></script>
</body>
</html>
中规中矩的老式代码。这段代码从CDN上加载AngularJS文件和一个最小化的CSS框架,然后开始一点点编写JavaScript代码并添加到index中。
但随着应用程序的增长,我们有必要跟踪所有的依赖(这里的依赖就是Angular)。
使用包管理器
许多人使用包管理器跟踪项目所需的依赖的版本。包管理器的最大卖点就是,它会访问依赖的GitHub主页,下载到你的文件夹里,并且跟踪下载的版本。这样可以保证,移动代码位置或者下载其他版本的依赖不会造成代码无法工作。
代码管理器有过duojs、jspm、bower、npm,现在还有Yarn。现在去装一个yarn,我们稍后会用到。
向应用程序里添加依赖时,yarn会下载所需的文件,并保存到node_modules文件夹中。之后,需要用到依赖时,可以在index文件里引入:
装好这个后,我们再往根目录下添加app.js、userController.js和userFactory.js文件,然后全都链接到index文件里。
/**
* /app.js
*/
var app = angular.module("RandomApp", []);
// /userFactory.js
app.factory("UserF", function($http) {
var UserF = {};
UserF.getUsers = function(){
return $http({
method: 'GET',
url: 'https://www.reqres.in/api/users',
})
};
return UserF;
});
// /userController.js
app.controller("userController", function($scope, UserF){
$scope.users = [];
UserF.getUsers()
.then(function(res) {
$scope.users = res.data.data;
})
});
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Random User!</title>
<link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre.min.css">
</head>
<body>
<div class="container" ng-app="RandomApp">
<h1 class="text-center">Random User!</h1>
<div ng-controller="userController">
<div ng-repeat="user in users">
<div class="card">
<div class="card-image">
<img ng-src="{{user.avatar}}" class="img-responsive">
</div>
<div class="card-header">
<div class="card-title h5">{{user.first_name}} {{user.last_name}}</div>
</div>
</div>
</div>
</div>
</div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="app.js"></script>
<script src="userController.js"></script>
<script src="userFactory.js"></script>
</body>
</html>
index越来越大了。他遇到了他自己的问题。他的手心开始出汗,膝盖发软,胳膊也越来越沉重……
这种方式的问题
所有的script标签必须按照固定的顺序。app.js生成app,然后附加到全局的window对象上。这个app变量会被其他脚本文件用到。这种情况通常被称为“全局命名空间污染”。
如果你还在用这种方式,就趁早改了吧。它的问题是,不管我们什么时候打开哪个文件,都无法得知app变量的值究竟是什么。
这段代码的另一个语义上的问题是,它使用了匿名函数。匿名函数是JavaScript的天使,也是魔鬼。
永远不要忘记给匿名函数起名字。这样以后调试代码会变得容易很多。
那么,要是有个JS警察负责找出这些问题,岂不是很好?
ESLint
ESLint是个清理器。就像个严格的结对编程的伙伴一样。清理器会在你运行应用程序之前就帮你调试代码,并且强迫你和你的团队遵循整洁代码的实践。谁说这样的老师不存在的?
配置ESLint
我们使用Airbnb的样式配置,在我们编写代码时进行检查,并指出不当的地方。上面的命令会将配置安装到node_modules目录下,但我们得告诉ESLint怎么用这个配置。建立一个名为.eslintrc.json的文件,内容如下:
// .eslintrc.json
{
"extends": [
"airbnb/legacy"
],
"env": {
"browser": true
}
}
extends列表告诉ESLint在它自己的默认规则之上使用Airbnb的规则。env变量告诉ESLint不要抱怨没有初始化的window变量等。要清理所有文件,可以使用通配符 * 。
现在运行下ESLint看看有什么结果。
这些都是Airbnb样式指南定义的规则。我留给你自己去改正这些文件。一开始就有个清理器是最理想的。当然,你可以关闭某个特定的规则。
比如,如果你喜欢不用分号,或者使用双引号而不是单引号,你可以关闭相应的规则。ESLint很灵活,允许你这么做。
模块
现在来讨论下模块。在创建大规模应用时,我们要求代码有良好的结构,以便于以后的扩展。
我们把代码放到不同的模块中,以实现代码分割的目的。JavaScript直到ES6才支持模块。但模块化的概念早在ES6之前就出现了。
CommonJS
在ES6之前,人们使用CommonJS标准。你可以写一段代码,然后告诉环境导出这段代码。之后就能使用像RequireJS之类的库导入模块了。
// util.js
module.export = {
noop: function(){},
validateUrl: function(s){
return s.matches(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/)
}
};
// postController.js
var validateUrl = require('./util').validateUrl;
var handleSubmit = function handleSubmit(e) {
if(!validateUrl(e.target.value)) {
return;
}
submitUrl(e.target.value);
}
如果你玩过Node,你会觉得这段代码看起来很眼熟。不过这个标准有个缺陷——它是同步的。
也就是说,只有在validateUrl被require了之后,postController的第3行的handleSubmit才会被执行。在这之前代码会暂停。
这种体系在Node.js中没什么问题。Node可以在服务器启动之前加载所有依赖,比如配置日志文件、连接云端的数据库、配置秘钥等。但在前端,这种方法并不是太理想。
异步模块定义(Asynchronous Module Definition,AMD)
顾名思义,这种方式会异步加载模块,比CommonJS的方式好一些。下面是使用AMD的代码(我加了几个函数)。看着眼熟吗?
define(['validateSpam', 'blockUser', function(validateSpam, blockUser){
return {
noop: function(){},
validateUrl: function(s) {
return s.matches(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/)
},
validateSpammyComment: function validateSpammyComment(comment, userID) {
if(validateSpam(comment)) {
blockUser(userID);
return false;
}
return true;
}
}])
第1行看起来就像AngularJS中的依赖注入一样。
ES6模块
TC39委员会看到开发者们使用外部库之后,他们深切感受到JavaScript需要支持模块。因此他们在ES6中引入了模块功能。现在使用ES6吧!
function noop(){};
function validateUrl(s) {
return s.matches(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/)
}
export {
noop,
validateUrl
}
import { validateUrl } from './util';
var handleSubmit = function handleSubmit(e) {
if(!validateUrl(e.target.value)) {
return;
}
submitUrl(e.target.value);
}
不需要再调用外部库。import和export都是原生支持的。但依然有些版本的浏览器并不能完全支持ES6的所有功能。
但这种浏览器之间的不一致并不能阻止程序员编写下一代的JavaScript。像babel等工具可以扫描所有JavaScript,并将它们转译成能兼容所有浏览器的代码。因此,你的代码甚至可以支持IE之类的老浏览器。
Babel和ES6
好了,现在我们把旧的JavaScript转换成新的JavaScript。先做一点改动,以便添加模块功能。现在我们先不管清理器……让它去抱怨吧。
// /userFactory.js
let angular = window.angular;
let app = angular.module('RandomApp');
/**
* A User factory which gets the user list
* @param $http
*/
let userFactory = $http => {
let UserF = {};
UserF.getUsers = () => $http({
method: 'GET',
url: 'https://www.reqres.in/api/users'
});
return UserF;
};
app.factory('UserF', userFactory);
// /userController.js
let angular = window.angular;
let app = angular.module('RandomApp');
/**
* Controls the user
* @param $scope
* @param UserF
*/
let userController = ($scope, UserF) => {
$scope.users = [];
UserF.getUsers().then(res => $scope.users = res.data.data);
};
userController.$inject = ['$scope', 'UserFactory'];
app.controller('userController', userController);
这段代码的问题
这段代码无法工作。因为ES6的let关键字创建的变量是代码块上下文内的变量,而在同一个上下文内无法重复定义代码块级别的变量。
别忘了:我们还在全局上下文里呢。现在来改正这个问题。
我希望重构代码的原因是,我想引入babel,这样可以亲眼看看babel的魔法。现在可以在终端里安装babel:yarn add babel-cli babel-preset-env
这行命令会安装babel-cli和babel-preset-env。
babel插件和预设
JavaScript代码会通过一系列转换器,而我们可以选择需要什么转换器。你可以让它把箭头函数转换成匿名函数,转换扩展运算符(spread),转换for...of循环,等等。这些转换器叫做插件。
你可以选择任何你想要的插件。成组的插件叫做预设。babel-preset-env会给babel一个灵活的目标。
它并不是指定某个特定版本的JavaScript,而是告诉babel自动跟踪最新的n个版本浏览器。
现在来设置babel配置文件:.babelrc,把它放到根目录下。
{
"presets": [
["env", {
"targets": {
"browsers": "last 2 versions"
}
}]
]
}
现在从终端运行如下命令,babel就能正常工作。输入以下命令:
node_modules/.bin/babel *.js
很方便对吧?babel会在转换之前预览以下。
现在喘口气,考虑下我们学过的东西。我们将一个JavaScript文件分解成了许多个文件。我们添加了清理器,防止写出不合规范的代码。
我们使用未来的JavaScript语法,并将其转换成特定版本的浏览器能理解的东西。我们污染了全局命名空间,但暂时还能接受,我们稍后会解决这个问题。
如果有个工具能自动完成这一切就好了。我们给它所有代码,自动运行清理器找出所有错误,然后转译成浏览器兼容的代码。没错,确实有这么个工具。现在把这些东西都自动化吧。
用Webpack进行构建
首先,把所有JS文件都移动到一个目录下。我们使用标准的命名方式,将文件夹命名为build。同时,我们重构下JavaScript文件,这样所有文件都能被构建到同一个文件下。
// /build/userController.js
/**
* Controls the user
* @param $scope
* @param UserF
*/
let userController = ($scope, UserF) => {
$scope.users = [];
UserF.getUsers().then(res => $scope.users = res.data.data);
};
userController.$inject = ['$scope', 'userFactory'];
export default userController;
// /build/userFactory.js
/**
* A User factory which gets the user list
* @param $http
*/
let userFactory = $http => {
let UserF = {};
UserF.getUsers = () => $http({
method: 'GET',
url: 'https://www.reqres.in/api/users'
});
return UserF;
};
userFactory.$inject = ['$http'];
export default userFactory;
/// /build/app.js
import angular from 'angular';
import userController from './userController';
import userFactory from './userFactory';
angular.module('RandomApp', [])
.factory('userFactory', userFactory)
.controller('userController', userController);
现在创建webpack.config.js文件:
var path = require('path');
module.exports = {
mode: 'development', // tells webpack that this is a development build. the 'production' switch will minify the code among other things
devtool: 'cheap-eval-source-map', // generate source maps for better debugging and dont take much time.
context: __dirname, // since this runs in a node environment, webpack will need the current directory name
entry: './build/app.js', // take this file and add to the bundled file whatever this file imports
output: {
path: path.join(__dirname, 'dist'), // output this in a dist folder
filename: 'bundle.js' // and name it bundle.js
},
// read medium post to know what's module and devServer because I dont have much room for comments
module: {
rules: [{
enforce: 'pre',
loader: 'eslint-loader',
test: /\.js$/
}, {
loader: 'babel-loader',
test: /\.js$/
}]
},
devServer: {
publicPath: '/dist/',
filename: 'bundle.js',
historyApiFallback: true,
overlay: true
}
};
如果现在运行webpack,就会看到所有文件都被打包成一个文件,放到dist目录下:
webpack配置揭秘
祝贺你,给自己点奖励吧。现在我们把所有文件都打包到一起,它几乎可以用于生产环境了。
现在来讨论下这个配置。我会逐一介绍每个配置项的意思。更详细的资料可以参考手册(https://webpack.js.org/)。
大多数配置项我都给出了注释。这里说说没加注释的那些。
Webpack加载器(module对象)
这个可以想像成一条流水线上的一串代码加载单元。最后一个加载器(这里是babel-loader)会最先被Webpack用来加载代码。
我们要求webpack遍历所有代码,然后用babel-loader将代码转译成ES5。
加载器对象还需要一个test设置项。它用这个设置项来匹配所有它应该负责的文件(本例中用一段正则表达式匹配了所有扩展名为.js的文件)。
转译之后,就执行下一个加载器(这里是eslint-loader)。最后,把所有改变从内存中写到文件中,然后输出到output对象指定的文件里。
但这并不是我们的配置文件的行为。我们在ESLint加载器上加了个enforce: pre,因为我们希望先运行清理器。
这是因为输出的结果只有一个文件,而且如果使用最小化和混淆功能的话,这个文件通常会变成人类无法阅读的格式(生产环境中经常会如此)。
清理器看这个文件就会疯了。这不是我们想要的,所以我们希望webpack先运行清理器,再进行转译。
除此之外,你还可以使用好几个加载器,可以加载样式表文件、SVG图像,以及字体。有个我总会用到的加载器就是html-loader。
HTML加载器
在Angular下,我们通常会在directive/component中包含模板文件,因此可以在Webpack中使用html-loader进行加载。
templateUrl: './users/partial/user.tpl.html' // 把这种写法改成:templateUrl: require('./users/partial/user.tpl.html')
Webpack由一个超大规模的社区支持,他们写了很多优秀的加载器,以及很完善的文档。不管你有什么需求,很可能已经有现成的加载器了。
Webpack开发服务器(devServer)
Webpack开发服务器是个独立于Webpack的模块。它会启动自己的服务器,然后监视任何文件的改动。如果文件发生变化,Webpack开发服务器就会重新打包并自动刷新页面。
如果发生错误,它会在屏幕上显示一个覆盖层(通过overlay配置项设置),并直接在浏览器中显示错误信息。而且它速度非常快,因为一切都在内存中完成,不会访问硬盘。
当然,为了运行webpack开发服务器,你首先得有一个基础的构建好的文件(即,至少要运行webpack一次以生成构建好的文件)。
一旦生成之后,就可以运行该命令。该命令会启动服务器并提供静态文件,打开浏览器(默认是8080端口),并持续监视任何变动。
搞定了!
不过这并不是结局。还有许多你能做的事情。在工作中,我们使用Flow在编码时进行静态类型检查。
静态类型检查器可以检查代码,并在发生错误时发出警告,比如调用函数时提供了错误类型的参数等。Flow也可以集成到Webpack中。
我们还使用Prettier实现编码时的自动格式化。它能让代码更可读。
傻瓜都能写计算机能看懂的代码。
好的程序员写人类能看懂的代码。
—— Martin Fowler。
我要把这句话贴在我的桌子上。祝贺你!你成功了!
如果你读完了这篇超长的文章,我要跟你击掌向你道喜,你是人生赢家。JavaScript对我而言并不容易。
我很希望我在第一个项目中编写UI时能懂得这些东西。但我估计这就是前端开发对我的意义。持续学习,持续进步。
原文:https://medium.freecodecamp.org/the-brain-fatigued-javascripters-guide-to-modern-frontend-tooling-in-2018-9818a04e9ec5
作者:Amin Mohamed Ajani,Javascript开发人员,曾为FireFox开发工具贡献代码。用户界面工程师,擅长iQuanti,reactjs,nodejs和TheIsmaili。
译者:弯月,责编:胡巍巍
“征稿啦”
CSDN 公众号秉持着「与千万技术人共成长」理念,不仅以「极客头条」、「畅言」栏目在第一时间以技术人的独特视角描述技术人关心的行业焦点事件,更有「技术头条」专栏,深度解读行业内的热门技术与场景应用,让所有的开发者紧跟技术潮流,保持警醒的技术嗅觉,对行业趋势、技术有更为全面的认知。
如果你有优质的文章,或是行业热点事件、技术趋势的真知灼见,或是深度的应用实践、场景方案等的新见解,欢迎联系 CSDN 投稿,联系方式:微信(guorui_1118,请备注投稿+姓名+公司职位),邮箱(guorui@csdn.net)。
HTML是用来开发网页的,它是开发网页的语言
全称HyperText Mark-up Language,超文本标记语言
标记就是标签
<标签名称></标签名称> 比如 <html></html> <h1></h1>等,标签大多数都是成对出现的。
超文本 两层含义:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>网页标题</title>
</head>
<body>
网页显示内容
</body>
</html>
第一行<!DOCTYPE html>是文档声明
用来指定页面所使用的html的版本, 这里声明的是一个html5的文档
<html>...</html>标签是开发人员在告诉浏览器
整个网页是从<html>这里开始的,到</html>结束
也就是html文档的开始和结束标签
<head>...</head>标签用于定义文档的头部
是负责对网页进行设置标题、编码格式以及引入css和js文件的
<body>...</body>标签是编写网页上显示的内容
网页文件的后缀是.html, 一个html文件就是一个网页,html文件用编辑器打开显示的是文本,可以用文本的方式编辑它,如果用浏览器打开,浏览器会按照标签描述内容将文件渲染成网页
VS Code全拼是 Visual Studio Code 是由微软研发的一款免费、开源的跨平台代码编辑器
目前是前端(网页)开发使用最多的一款软件开发工具
下载网址: https://code.visualstudio.com/Download
选择对应的安装包进行下载:
安装一切默认
1 标签不区分大小写,但是推荐使用小写
2 根据标签的书写形式,标签分为双标签(闭合标签)和单标签(空标签) 2.1 双标签是指由开始标签和结束标签组成的一对标签,这种标签允许嵌套和承载内容,比如: div标签 2.2 单标签是一个标签组成,没有标签内容, 比如: img标签
标签的使用形式
列表标签
网页效果
表格标签
<table>标签:表示一个表格
<tr>标签:表示表格中的一行
<td>标签:表示表格中的列
<th>标签:表示表格中的表头
属性设置
border: 1px solid black:设置边框和颜色
border-collapse: collapse:设置边框合并
网页效果
表单标签
表单用于搜集不同类型的用户输入的数据,然后可以把用户数据提交到web服务器
<form>标签 表示表单标签,定义整体的表单区域
一个表单中有很多信息组成,比如 姓名,爱好,地址等,这些内容有很多其他标签来承载
这些标签称为表单元素标签
网页效果
表单用于搜集不同类型的用户输入的数据,然后可以把用户数据提交到web服务器
两种方式的区别:
表单元素属性设置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--
姓名 type="text" 定义单行文本输入框
密码 type="password" 定义密码输入框
性别 type="radio" 定义单选框
爱好 type="checkbox" 定义复选框
照片 type="file" 定义上传文件
个人描述 <textarea></textarea> 定义多行文本输入框
地址 <select></select> 定义下拉列表
提交 type="submit" 定义提交按钮
重置 type="reset" 定义重置按钮
按钮 type="button" 定义一个普通按钮
-->
<form action="http://192.168.1.106:8080" method="POST">
<label>姓名:</label>
<input type="text" name="username" >
<br>
<label>密码:</label>
<input type="password" name="password">
<br>
<label>性别:</label>
<input type="radio" name="sex" value="1">男
<input type="radio" name="sex" value="0">女
<br>
<label>爱好:</label>
<input type="checkbox" name="like" value="睡觉">睡觉
<input type="checkbox" name="like" value="吃饭">吃饭
<input type="checkbox" name="like" value="打豆豆">打豆豆
<br>
<label>照片:</label>
<input type="file" name="pic">
<br>
<label>个人描述:</label>
<textarea name="desc"></textarea>
<br>
<label>地址:</label>
<select name="addr">
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">广州</option>
<option value="4">深圳</option>
</select>
<br>
<input type="submit" value="提交">
<input type="reset" value="重置">
<input type="button" value="按钮">
</form>
</body>
</html>
点击提交:
可以看到服务器收到了请求报文。
*请认真填写需求信息,我们会在24小时内与您取得联系。