目录
&=Stable Diffusion 美图活动一期=&
InsCode是一个集成了在线IDE、在线AI编程、在线算力租赁、在线项目部署以及在线SD 模型使用的综合代码开发平台。不论你是初级软件工程师,还是AI大模型爱好者,InsCode都能帮助你快速编写代码,运行项目。甚至在这里你还可以一键购买算力,训练大模型,开发自己的AI应用程序。
一、介绍
1.1 是什么
LayUI是一个基于JavaScript的前端开发框架,旨在简化Web界面的设计和开发。它使用了简洁友好的API,并提供了丰富的组件和样式,使开发者可以快速构建美观、响应式的网页界面。
下面是LayUI的一些特点和组成部分的详细介绍:
-- 1. **简洁易用的API**:LayUI提供了简单、直观的API,使开发者可以使用少量的代码来实现复杂的界面效果。开发者只需简单地引入LayUI的库文件,即可开始使用LayUI。
-- 2. **模块化开发**:LayUI使用了模块化的设计理念,将各个组件拆分成独立的模块,开发者可以根据需求选择性地引入和使用这些模块。这样可以提高代码的重用性和维护性。
-- 3. **丰富的组件**:LayUI提供了一系列丰富的界面组件,例如表单、表格、弹窗、导航、菜单等,这些组件可以满足常见的前端需求,并且可以自由组合在一起,构建符合实际需求的界面。
-- 4. **响应式设计**:LayUI支持响应式布局,可以根据不同屏幕尺寸自适应地调整界面布局。这使得开发的网页界面在不同的设备上都能够有良好的显示效果,提升用户体验。
-- 5. **丰富的主题和样式**:LayUI提供了多种主题和样式,开发者可以根据实际需求选择合适的主题,轻松地改变网页的风格和外观。
-- 6. **开放的扩展性**:LayUI提供了一套开放的扩展机制,开发者可以根据需要进行二次开发,定制满足自己需求的组件或样式。
总的来说,LayUI是一个简单、易用、灵活的前端开发框架,它可以帮助开发者快速搭建优雅、高效的网页界面。无论是初学者还是有经验的开发者,都可以通过LayUI来简化开发流程,实现出色的前端效果。
1.2 谁开发
LayUI是由中国的一家开发团队领航网络开发的。该团队创建于2012年,专注于前端开发和UI设计。他们致力于为开发者提供简洁、易用的前端开发框架和工具。
背景上,2012年是前端开发领域快速发展的时期,移动互联网和Web应用程序的兴起对前端开发提出了更高的要求。在这个背景下,领航网络团队创建了LayUI,旨在简化前端开发流程,提高开发效率,并提供优雅且丰富的界面组件。
LayUI的出现填补了市场上一些前端开发框架的空缺,为开发者提供了一个简单、易用、强大的开发框架。由于其简洁易用、模块化开发和丰富的组件库等特点,LayUI很快获得了开发者的认可和广泛的应用。
随着时间的推移,LayUI不断演进和更新,不断适应前端开发的新趋势和需求。至今,LayUI已经成为国内外前端开发者常用的框架之一,为各种规模的项目提供了强大的支持。领航网络团队通过持续的技术研发和反馈收集,不断优化和更新LayUI,使其成为一个成熟、稳定且功能丰富的前端开发框架。
1.3 作用
LayUI是一个功能丰富的前端开发框架,它具有多种作用和优点。以下是LayUI的详细描述:
- -- 1. **简化界面开发**:LayUI提供了丰富的组件、样式和布局,使界面开发变得简单和直观。通过引入LayUI,并使用其简洁易用的API,开发者可以通过少量的代码实现复杂的界面效果。这极大地简化了界面的开发流程,降低了开发的复杂性和难度。
- -- 2. **提高开发效率**:LayUI的设计目标之一是提高开发效率。它采用了模块化的开发方式,将各个组件和功能拆分成独立的模块。开发者可以根据自己的需求选择性地引入和使用这些模块,避免了加载不必要的组件和功能,提高了页面加载速度。此外,LayUI的简单易用的API和丰富的组件库,使开发者能够快速开发出功能完备、美观的网页界面。
- -- 3. **响应式布局支持**:LayUI提供了响应式布局的支持,使页面能够自动适应不同的屏幕尺寸和设备。开发者可以使用LayUI提供的响应式的布局组件和工具,根据不同的设备,自动调整页面的布局和显示效果。这使得开发的网页在不同终端上都能够有良好的显示效果,提供更好的用户体验。
- -- 4. **提供丰富的组件和样式**:LayUI提供了一系列常用的界面组件,如表单、表格、弹窗、导航、菜单等等。这些组件都经过精心设计和优化,具有良好的交互体验和视觉效果。此外,LayUI还提供了多种样式和主题供选择,开发者可以根据实际需求,自由搭配和定制界面风格。
- -- 5. **可定制性**:LayUI提供了开放的扩展机制,允许开发者根据自己的需求进行二次开发和定制。开发者可以根据具体项目的需求,在LayUI的基础上进行扩展和定制,实现个性化的界面和功能。这使得LayUI具有更强的灵活性和可扩展性,能够适应各种不同的项目需求。
总而言之,LayUI作为一个简单、易用、强大的前端开发框架,可以极大地简化界面开发,提高开发效率,并提供丰富的组件、样式和扩展性,满足不同项目的需求。它适用于各种Web应用程序和网站的开发,为开发者提供了一种快速、便捷和灵活的前端开发解决方案。
二、使用
2.1 功能介绍
其中官方网站已经下线,可以访问该网站地址进行使用: 在线示例 - Layui
2.1.1 功能对比
下面是LayUI、EasyUI和Bootstrap的优点体现的更具体描述:
LayUI的优点体现:
- - 简单易用:LayUI的API设计简单、直观,易于上手和使用,尤其适合前端开发的初学者。
- - 响应式布局支持:LayUI提供了响应式布局的支持,能够根据不同设备的屏幕尺寸自适应布局,使页面在不同设备上都能良好展示。
- - 丰富的组件:LayUI提供了丰富的组件库,包括表单、表格、导航等常用界面组件,使开发者能够快速构建功能完备、美观的网页界面。
- - 可定制性:LayUI提供了开放的扩展机制,允许开发者根据自己的需求进行定制和扩展,能满足不同项目的个性化需求。
EasyUI的优点体现:
- - 组件丰富:EasyUI拥有丰富的可视化组件库,包括表格、树型控件、弹窗等常用组件,易于使用和定制。
- - 强大的数据处理能力:EasyUI内置了数据网格和表单控件,支持数据的增删改查以及各种数据操作,方便开发者处理复杂的数据交互和操作需要。
- - 可扩展性:EasyUI支持自定义扩展和插件,使开发者能够根据项目的特定需求进行准确的扩展和定制。
Bootstrap的优点体现:
- - 响应式布局支持:Bootstrap是一个流行的响应式框架,能够根据不同设备的尺寸自适应布局,确保页面在不同设备上呈现出良好的显示效果。
- - 组件丰富:Bootstrap提供了大量的组件和样式,如网格系统、按钮、导航、表单等,使开发者能够快速搭建现代化、美观的网页界面。
- - 社区支持和生态圈:Bootstrap拥有庞大的用户社区和活跃的生态圈,有大量的开源模板和插件可供使用,易于扩展和集成到项目中。
总而言之,LayUI、EasyUI和Bootstrap都有自己的优点和特点。LayUI注重简洁易用和定制性,EasyUI注重数据处理和组件库,Bootstrap注重响应式布局和社区支持。根据具体的项目需求和个人喜好,选择合适的框架能够提高开发效率,快速构建出功能完备、美观的前端界面。
2.2.2 主要功能
LayUI具有以下主要功能和特点:
- 1. **界面元素**:LayUI提供了丰富的界面元素,如按钮、表单、表格、导航、面包屑、进度条等,可以快速构建各种样式美观的界面。
- 2. **布局系统**:LayUI采用了响应式布局方式,可以根据设备的不同自适应地调整页面布局,以确保在各种屏幕尺寸下都有良好的显示效果。
- 3. **数据表格**:LayUI提供了强大且易于使用的数据表格组件,支持表头固定、排序、分页、数据加载等功能,并提供了丰富的自定义配置选项。
- 4. **表单验证**:LayUI内置了表单验证模块,可以轻松实现对表单数据的验证,包括必填字段、长度限制、格式验证等,提高了表单的可靠性和用户友好性。
- 5. **弹层组件**:LayUI提供了弹层组件,包括提示框、确认框、加载框、普通弹层等,在页面中展示消息、警告、询问等交互式弹窗。
- 6. **菜单导航**:LayUI提供了便捷的菜单导航组件,可以构建水平导航、垂直导航,支持多级菜单和动态加载数据。
- 7. **工具函数**:LayUI内置了一些常用的工具函数,如日期处理、字符编码转换、模板引擎等,方便开发者快速处理常见的数据操作。
- 8. **模块化开发**:LayUI采用了模块化的开发方式,组件之间相互独立,可以按需引入和使用,避免了冗余代码,提高了代码的可维护性和可扩展性。
- 9. **皮肤定制**:LayUI支持自定义皮肤,开发者可以根据项目需求轻松切换或定制界面的样式,满足不同风格的设计需求。
总的来说,LayUI提供了丰富的界面元素和交互组件,同时支持响应式布局和模块化开发,使得开发者能够快速构建美观、功能完备的前端界面,并提供良好的用户体验。
2.2 使用流程
LayUI的使用流程可以分为以下几个步骤:
-- 1. **引入LayUI库**:在你的HTML文件中,引入LayUI库的相关文件,包括`layui.js`和`layui.css`。你可以从LayUI官方网站下载最新版本的LayUI库,然后将这些文件复制到你的项目中。
<link rel="stylesheet" href="path/to/layui.css"> <script src="path/to/layui.js"></script>
-- 2. **初始化LayUI**:在你的JavaScript代码中,使用`layui.use()`方法来初始化LayUI并加载需要使用的模块。
<script> layui.use(['element', 'form'], function(){ var element = layui.element; var form = layui.form; // 在这里编写你的代码 }); </script>
上面的代码中,我们通过`layui.use()`方法引入了`element`和`form`两个模块。你可以根据你的需求引入其他需要使用的模块。
-- 3. **使用LayUI组件**:在`layui.use()`方法的回调函数中,你可以使用LayUI提供的各种组件来构建你的界面和功能。
<script> layui.use(['element', 'form'], function(){ var element = layui.element; var form = layui.form; // 菜单导航 element.init(); // 初始化菜单 element.on('nav(menu)', function(elem){ // 处理菜单点击事件 console.log(elem); // 输出点击的菜单信息 }); // 表单验证 form.on('submit(formDemo)', function(data){ // 表单提交的逻辑代码 return false; // 阻止表单提交 }); }); </script>
在上面的示例中,我们使用`element.init()`初始化菜单导航,并监听菜单的点击事件。另外,我们使用`form.on('submit')`监听表单的提交事件,并编写了相应的逻辑代码。
-- 4. **编写HTML结构**:根据你的需求,编写相应的HTML结构,可以使用LayUI提供的HTML标签和CSS类来构建界面。
<ul class="layui-nav" lay-filter="menu"> <li class="layui-nav-item"><a href="">首页</a></li> <li class="layui-nav-item"><a href="">产品</a></li> <li class="layui-nav-item"><a href="">关于</a></li> </ul> <form class="layui-form" action=""> <!-- 表单元素 --> <div class="layui-form-item"> <label class="layui-form-label">用户名</label> <div class="layui-input-inline"> <input type="text" name="username" lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input"> </div> </div> <!-- 提交按钮 --> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button> </div> </div> </form>
上面的代码展示了一个简单的菜单导航和一个表单,使用了LayUI的相应标签和CSS类。
通过以上流程和示例,你可以开始使用LayUI来构建你的界面和实现功能。可以根据具体的需求引入相应的模块,使用LayUI提供的组件和样式来开发各种界面元素和交互功能。你可以查阅LayUI官方文档,了解更多关于各个模块和组件的详细使用方法和示例代码。
三、注册案例
3.1 创建表
创建一个属性字段为如图所示中的 User 表
3.2 数据库连接及导包
config.properties 文件
#mysql8
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&useSSL=true
user=root
pwd=123456
其中mybatis_ssm是数据库名称,root是账号,123456是密码,每人的都不一样可以根据自己的进行修改编辑。
DBAccess 连接类
package com.CloudJun.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* @author Cloud.Jun
* @com.CloudJun.utils
* @DBAccess(说明):数据库连接类
*/
public class DBAccess {
private static String driver;
private static String url;
private static String user;
private static String password;
static {// 静态块执行一次,加载 驱动一次
try {
InputStream is = DBAccess.class
.getResourceAsStream("config.properties");
Properties properties = new Properties();
properties.load(is);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("pwd");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 获得数据连接对象
*
* @return
*/
public static Connection getConnection() {
try {
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static void close(ResultSet rs) {
if (null != rs) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void close(Statement stmt) {
if (null != stmt) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void close(Connection conn) {
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void close(Connection conn, Statement stmt, ResultSet rs) {
close(rs);
close(stmt);
close(conn);
}
public static boolean isOracle() {
return "oracle.jdbc.driver.OracleDriver".equals(driver);
}
public static boolean isSQLServer() {
return "com.microsoft.sqlserver.jdbc.SQLServerDriver".equals(driver);
}
public static boolean isMysql() {
return "com.mysql.cj.jdbc.Driver".equals(driver);
}
public static void main(String[] args) {
Connection conn = DBAccess.getConnection();
System.out.println(conn);
DBAccess.close(conn);
System.out.println("isOracle:" + isOracle());
System.out.println("isSQLServer:" + isSQLServer());
System.out.println("isMysql:" + isMysql());
System.out.println("数据库连接(关闭)成功");
}
}
3.3 实体类(模型)
User 实体类
package com.CloudJun.entity;
/**
* @author Cloud.Jun
* @com.CloudJun.entity
* @User(说明):实体类(User)
*/
public class User {
private long id;
private String name;
private String loginName;
private String pwd;
private long rid;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public long getRid() {
return rid;
}
public void setRid(long rid) {
this.rid = rid;
}
public User(long id, String name, String loginName, String pwd, long rid) {
super();
this.id = id;
this.name = name;
this.loginName = loginName;
this.pwd = pwd;
this.rid = rid;
}
public User() {
super();
}
public User(String name, String loginName, String pwd, long rid) {
super();
this.name = name;
this.loginName = loginName;
this.pwd = pwd;
this.rid = rid;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", loginName=" + loginName + ", pwd=" + pwd + ", rid=" + rid + "]";
}
public User(String loginName, String pwd) {
super();
this.loginName = loginName;
this.pwd = pwd;
}
}
UserDao 实体方法类
package com.CloudJun.Dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.CloudJun.entity.User;
import com.CloudJun.utils.DBAccess;
/**
* @author Cloud.Jun
* @com.CloudJun.Dao
* @UserDao(说明):实体方法类(User的Dao层)
*/
public class UserDao {
public User login(User u) throws Exception {
User user = null;
String sql = "select * from t_oa_user where loginName = '"+u.getLoginName()+"' and pwd = '"+u.getPwd()+"' ";
Connection conn = DBAccess.getConnection();
PreparedStatement pre = conn.prepareStatement(sql);
ResultSet re = pre.executeQuery();
if (re.next()) {
user = new User(re.getLong(1), re.getString(2), re.getString(3), re.getString(4), re.getLong(5));
}
return user;
}
public Integer Count(String table) throws Exception {
String sql = "select max(id) from "+table+"";
Connection conn = DBAccess.getConnection();
PreparedStatement pre = conn.prepareStatement(sql);
ResultSet re = pre.executeQuery();
int a = 0;
if (re.next()) {
a+=re.getInt(1);
}
return a;
}
public int Add(User u) throws Exception {
String sql = "INSERT INTO t_oa_user VALUES ("+u.getId()+",'"+u.getName()+"','"+u.getLoginName()+"','"+u.getPwd()+"',"+u.getRid()+")";
Connection conn = DBAccess.getConnection();
PreparedStatement pre = conn.prepareStatement(sql);
int a = pre.executeUpdate();
return a;
}
public static void main(String[] args) throws Exception {
// User u = new User(14,"丘比特","qbt","1234",4);
// int add = new UserDao().Add(u);
// System.out.println(add);
int add = new UserDao().Count("t_oa_user");
System.out.println(add);
}
}
3.4 Servlet
enrollServlet 注册
package com.CloudJun.Servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.CloudJun.Dao.UserDao; import com.CloudJun.entity.User; @WebServlet("/enroll.do") public class enrollServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置编码 request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html,charset=utf-8"); PrintWriter out = response.getWriter(); //获取jsp页面传递过来的参数 String name = request.getParameter("name"); String username = request.getParameter("username"); String password = request.getParameter("password"); //实例化Dao UserDao ud = new UserDao(); //实例化user实体 User user; try { user = new User(ud.Count("t_oa_user")+1,name,username, password,4); int i = ud.Add(user); if(i>0) { //注册完成传参"OK" out.write("ok"); }else { //注册失败传参"NO" out.write("no"); } } catch (Exception e1) { e1.printStackTrace(); } } }
3.5 引入LayUI库
将解压的LayUI库进行导入项目的静态文件中,如图所示:
3.6 编写JSP页面
先将公共资源导包封装一个页面
header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<!-- 引入 layui.css -->
<link rel="stylesheet" href="${pageContext.request.contextPath }/static/js/layui/css/layui.css">
<!-- 引入 layui.js -->
<script src="${pageContext.request.contextPath }/static/js/layui/layui.js"></script>
<link rel="stylesheet" rev="stylesheet" href="${pageContext.request.contextPath }/static/css/iconfont.css"
type="text/css" media="all">
<link rel="stylesheet" rev="stylesheet" href="${pageContext.request.contextPath }/static/css/login.css"
type="text/css" media="all">
<body>
</body>
</html>
之后在页面中导入资源页面进行使用如:
<%@ include file="common/header.jsp" %>
编辑前端页面 enroll.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="common/header.jsp" %>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户注册</title>
<style>
body {
color: #;
}
a {
color: #;
}
a:hover {
color: #;
}
.bg-black {
background-color: #;
}
.tx-login-bg {
background: url(static/images/bg.jpg) no-repeat 0 0;
}
</style>
<script>
layui.use(['jquery','layer'], function() {
let $ = layui.jquery;
let layer = layui.layer;
$("#enroll").click(function() {
let name= $("#name").val();
let username= $("#username").val();
let password= $("#password").val();
let passwords= $("#passwords").val();
if(password==passwords){
$.post("enroll.do",{name:name,username:username,password:password},function(data){
if(data=="ok"){
layer.msg("欢迎"+name+",注册成功");
location.href ="login.jsp";
}else{
layer.msg("注册失败");
}
});
}else{
layer.msg('两次密码必须一致才可', {icon: 5});
}
});
});
</script>
</head>
<body class="tx-login-bg">
<div class="tx-login-box">
<div class="login-avatar bg-black">
<i class="iconfont icon-wode"></i>
</div>
<ul class="tx-form-li row">
<li class="col-24 col-m-24"><p>
<input type="text" id="name" placeholder="用户名称"
class="tx-input">
</p></li>
<li class="col-24 col-m-24"><p>
<input type="text" id="username" placeholder="创建账号"
class="tx-input">
</p></li>
<li class="col-24 col-m-24"><p>
<input type="password" id="password" placeholder="密码"
class="tx-input">
</p></li>
<li class="col-24 col-m-24"><p>
<input type="password" id="passwords" placeholder="确认密码"
class="tx-input">
</p></li>
<li class="col-24 col-m-24"><p class="tx-input-full">
<button id="enroll" class="tx-btn tx-btn-big bg-black">注册</button>
</p></li>
<li class="col-12 col-m-12"><p>
<a href="login.jsp" class="f-12 f-gray">已有账号</a>
</p></li>
<li class="col-12 col-m-12"><p class="ta-r">
<a href="#" class="f-12 f-gray">忘记密码</a>
</p></li>
</ul>
</div>
</body>
</html>
给我们带来的收获
学习LayUI的技术可以给我们带来以下收获:
- 1. --**快速开发能力**:LayUI提供了丰富的组件和工具,可以帮助我们快速构建各种界面元素和交互功能,加快项目的开发进度。
- 2.-- **响应式布局**:LayUI具备响应式布局的能力,可以根据不同设备的屏幕尺寸自适应地调整页面布局,使页面在各种设备上显示良好。
- 3. -**丰富的组件库**:LayUI提供了众多常用的界面组件,如按钮、表格、表单、导航等,这些组件已经经过优化和封装,可以直接使用,减少了我们的开发工作量。
- 4. --**一致性和美观的界面**:LayUI采用统一的设计风格和样式,使得我们开发的界面都具备良好的一致性和美观性,提升了用户体验。
- 5. --**模块化开发**:LayUI采用模块化的开发方式,组件之间相互独立,可以按需引入和使用,提高了代码的可维护性和复用性。
- 6. **大量的资源和社区支持**:LayUI拥有庞大的用户社区和活跃的生态圈,有大量的开源模板、插件和资源可供使用,可以借鉴和参考,快速解决开发过程中的问题。
- 7. --**学习与实践能力**:通过学习LayUI的技术,我们可以拓宽前端开发的技术视野,了解现代化前端框架的设计思想和开发方法,提升自己的技术水平和实践能力。
总而言之,学习LayUI的技术可以使我们在前端开发中更加高效和便捷地构建界面,并拥有一致性和美观的用户界面。它为我们提供了丰富的组件和工具,减少了开发工作量,并且拥有强大的社区支持和资源。这些优势将帮助我们更好地应对前端开发的挑战,并提升我们的技术能力和竞争力。