jCO--http://www.cnblogs.com/zfswff/p/5671148.html

2024-06-23 11:38

本文主要是介绍jCO--http://www.cnblogs.com/zfswff/p/5671148.html,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SAP接口编程 之 JCo3.0系列(01):JCoDestination

字数2101 阅读103 评论0 

JCo3.0是Java语言与ABAP语言双向通讯的中间件。与之前1.0/2.0相比,是重新设计的产品。API和架构设计与NCo3.0比较类似,前面也说过,NCo3.0的设计参考了JCo3.0。从本篇开始,系统介绍JCo3.0编程的技术要点。

JCo3.0安装

从https://service.sap.com/connectors 可以下载JCo3.0,注意下载的时候根据操作系统JVM版本(32位还是64)选择不同的版本。安装就是解压,将文件解压到目标文件夹。以Windows系统为例,主要的文件包括:

sapjco3.dll
sapjco3.jar

SAP强烈推荐将这两个文件放在同一文件夹下。测试安装是否成功,可以在命令窗口下,进入安装文件夹,运行下面的命令:

java -jar sapjco3.jar

如果安装成功,应该显示如下界面:

id="iframe_0.16730619855632956" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload-images.jianshu.io/upload_images/1765749-7e0730f1f0f37a62.png?imageMogr2/auto-orient/strip%257CimageView2/2/w/1240&_=5670223%22%20style=%22border:none;max-width:999px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.16730619855632956',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="margin: 0px; padding: 0px; border: none; width: 392px; height: 450px;">
jco3安装成功的显示界面

JCoDestination

JCoDestination代表后台SAP系统,程序员不用关心与SAP的连接,jco3.0运行时环境负责管理连接和释放连接。我们先以一个简单的例子看看jco3.0 JCoDestination类的一些要点。

我使用的编程环境是Eclipse,环境准备如下:

  • 新建一个Java项目,项目名为JCo3Demo。
  • 将sapjco3.jar加入到项目的build path中。注意前面所说的sapjco3.jar和sapjco3.dll要放在同一个文件夹下。
  • 在Eclipse Java项目文件夹下,新建一个文本文件,文件名命名为ECC.jocdestination, 文件的内容如下(SAP系统的连接参数的设置):

    #SAP Logon parameters!
    #Tue Dec 08 16:41:30 CST 2015
    jco.client.lang=EN
    jco.client.client=001
    jco.client.passwd=xxxxxx
    jco.client.user=STONE
    jco.client.sysnr=00
    jco.client.ashost=192.168.65.100

对照SAP GUI,不难理解:

id="iframe_0.6278244840647245" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload-images.jianshu.io/upload_images/1765749-97643b097b86c2a3.jpg?imageMogr2/auto-orient/strip%257CimageView2/2/w/1240&_=5670223%22%20style=%22border:none;max-width:999px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.6278244840647245',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="margin: 0px; padding: 0px; border: none; width: 540px; height: 556px;">
SAP GUI

环境准备好了,先来一段最简单的代码:

package jco3.demo1;import java.util.Properties;
import org.junit.Test;
import com.sap.conn.jco.JCoDestination; import com.sap.conn.jco.JCoDestinationManager; import com.sap.conn.jco.JCoException; public class JCoDestinationDemo { public JCoDestination getDestination() throws JCoException { /** * Get instance of JCoDestination from file: ECC.jcodestination * which should be located in the installation folder of project */ JCoDestination dest = JCoDestinationManager.getDestination("ECC"); return dest; } @Test public void pingDestination() throws JCoException { JCoDestination dest = this.getDestination(); dest.ping(); } }

代码说明:

  • getDestination()方法中,JCoDestinationManager.getDestination("ECC")从ECC.jcodestination文件中获取连接参数,创建JCoDestination对象的实例。
    这里有一个重要的约定,JCoDestinationManager.getDestination("ECC")方法,会从Eclipse Java项目的根目录,查找ECC.jcodestination文件(文件路径和扩展名不能改变)是否存在,如果存在,从文件的内容中获取连接参数。这是DestinationDataProvider接口的一个默认实现,在开发和测试的时候还是很方便的,但如果在真实项目中使用,安全性和灵活性就不够。后面会介绍解决方法。

  • pingDestination()方法调用JcoDestination对象的ping()方法测试SAP系统的连接。

  • @Test: 使用junit进行测试

配置文件的生成

刚才我们手工编辑了ECC.jcodestination文件,对于这个配置文件,因为很多连接参数来自于DestinationDataProvider接口,如果想通过代码来创建配置文件,可以使用如下代码:

package jco3.demo2;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; import org.junit.Test; import com.sap.conn.jco.ext.DestinationDataProvider; public class DestinationFile { private Properties setProperties() { // logon parameters and other properties Properties connProps = new Properties(); connProps.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.65.100"); connProps.setProperty(DestinationDataProvider.JCO_SYSNR, "00"); connProps.setProperty(DestinationDataProvider.JCO_USER, "STONE"); connProps.setProperty(DestinationDataProvider.JCO_PASSWD, "xxxxxx"); connProps.setProperty(DestinationDataProvider.JCO_CLIENT, "001"); connProps.setProperty(DestinationDataProvider.JCO_LANG, "EN"); return connProps; } private void doCreateFile(String fName, String suffix, Properties props) throws IOException { /** * Write contents of properties into a text file * which was named [fName+suffix.jcodestination] */ File cfg = new File(fName+"."+suffix); if (!cfg.exists()){ // file not exists // Create file output stream, not using append mode FileOutputStream fOutputStream = new FileOutputStream(cfg, false); // store the properties in file output stream // and also add comments props.store(fOutputStream, "SAP logon parameters:"); fOutputStream.close(); }else{ throw new RuntimeException("File alreay exists."); } } @Test public void createConfigFile() throws IOException { Properties props = this.setProperties(); String fileName = "SAP_AS"; // sap application server // jcodestination suffix is required by JCoDestinationManager this.doCreateFile(fileName, "jcodestination", props); } }

代码说明:

  • setProperties()方法属性参照DestinationDataProvider类的常量设置Properties的实例。
  • doCreateFile()方法根据需求的文件名,扩展名在Eclipse项目的根文件夹下,创建一个文本文件,文件的内容就是Properties实例的内容。
  • createConfigFile()方法,调用上面的两个方法,创建配置文件。

更改配置文件名的路径和扩展名

我们看到,默认情况下,SAP对配置文件的路径和扩展名都不能改变,如果我们想把文件放在任意位置,扩展名也使用其他的扩展名,有没有办法?答案是有,方法是实现DestinationDataProvider接口,并改写(override)getDestinationProperties()方法,然后通过Environment.registerDestinationDataProvider()方法进行注册。

OK, 一起来看看代码,代码分为三个部分:

  • 第一部分: 创建FileDestinationDataProviderImp类,实现DestinationDataProvider接口
  • 第二部分: 创建FileDestinationDataProvider类,注册FileDestinationDataProviderImp的实例,并提供getDestination()方法供调用
  • 第三部分:调用FileDestinationDataProvider类的getDestination()方法

第一部分:DestinationDataProvider接口的实现:

package jco3.demo2;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.util.Properties; import com.sap.conn.jco.ext.DestinationDataEventListener; import com.sap.conn.jco.ext.DestinationDataProvider; public class FileDestinationDataProviderImp implements DestinationDataProvider { private File dir; private String destName; // destination name private String suffix; public void setDestinationFile(File dir, String destName, String suffix) { this.dir = dir; this.destName = destName; this.suffix = suffix; } private Properties loadProperties(File dir, String destName, String suffix) throws IOException { Properties props = null; // create a file with name: fullName in destDirectory File destFile = new File(dir, destName+"."+suffix); if (destFile.exists()){ FileInputStream fInputStream = new FileInputStream(destFile); props = new Properties(); props.load(fInputStream); fInputStream.close(); }else{ throw new RuntimeException("Destination file does not exist."); } return props; } @Override public Properties getDestinationProperties(String destName) { Properties props = null; try { props = this.loadProperties(this.dir, this.destName, this.suffix); } catch (IOException e) { e.printStackTrace(); } return props; } @Override public void setDestinationDataEventListener(DestinationDataEventListener listener) { throw new UnsupportedOperationException(); } @Override public boolean supportsEvents() { return false; } }

第二部分: 创建FileDestinationDataProvider类,注册FileDestinationDataProviderImp的实例,并且提供getDestination()方法。

package jco3.demo2;import java.io.File;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException; import com.sap.conn.jco.ext.Environment; public class FileDestinationDataProvider { public static JCoDestination getDestination() throws JCoException { File directory = new File("."); // current directory; String fileName = "SAP_AS"; String suffix = "txt"; FileDestinationDataProviderImp destDataProvider = new FileDestinationDataProviderImp(); destDataProvider.setDestinationFile(directory, fileName, suffix); Environment.registerDestinationDataProvider(destDataProvider); JCoDestination dest = JCoDestinationManager.getDestination(fileName); return dest; } }

我们看到,getDestination方法中,文件的路径,文件的扩展名,都是我们自己定义的。文件名作为JCoDestinationManager.getDestination方法的destination name。从这里也可可以看到,JCoDestinationManager.getDestination方法从哪里查找连接参数,是依赖于Environment注册的DestinationDataProvider实现

第三部分:测试代码FileDestinationDataProvidergetDestination方法:

package jco3.demo2;import org.junit.Test;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoException; public class TestFileDestinationProvider { @Test public void pingSAPDestination() throws JCoException { JCoDestination dest = FileDestinationDataProvider.getDestination(); dest.ping(); } }

DestinationDataProvider另一种实现

记得nco3.0可以将登陆参数写在代码中吗,如果我们也想将连接参数直接写在代码中,怎么做呢?刚才说过了,关键就是实现DestinationDataProvider接口,并改写getDestinationProperties()方法。不多说,上代码。

第一部分:DestinationDataProvider接口实现

package jco3.demo3;import java.util.HashMap;
import java.util.Map;
import java.util.Properties; import com.sap.conn.jco.ext.DestinationDataEventListener; import com.sap.conn.jco.ext.DestinationDataProvider; public class DestinationDataProviderImp implements DestinationDataProvider { /** * DestinationDataProvider is an interface * We define DestinationDataProviderImp class to implements this interface * so that we can define the logon parameters more flexibly * not just in xxx.jcodestionation file. * * The key point is that we override getDestinationProperties() method * Afterwards, instance of DestinationDataProvider should be registered * using Environment.registerDestinationDataProvider() method to take effect */ @SuppressWarnings("rawtypes") private Map provider = new HashMap(); @SuppressWarnings("unchecked") public void addDestinationProperties(String destName, Properties props) { provider.put(destName, props); } @Override public Properties getDestinationProperties(String destName) { if (destName == null){ throw new NullPointerException("Destinantion name is empty."); } if (provider.size() == 0){ throw new IllegalStateException("Data provider is empty."); } return (Properties) provider.get(destName); } @Override public void setDestinationDataEventListener(DestinationDataEventListener listener) { throw new UnsupportedOperationException(); } @Override public boolean supportsEvents() { return false; } }

第二部分:创建DestinationProivder类,提供getDestination()方法,注册DestinationDataProviderImp类的实例:

package jco3.demo3;import java.util.Properties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager; import com.sap.conn.jco.JCoException; import com.sap.conn.jco.ext.DestinationDataProvider; import com.sap.conn.jco.ext.Environment; public class DestinationProvider { private static Properties setProperties() { // logon parameters and other properties Properties connProps = new Properties(); connProps.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.65.100"); connProps.setProperty(DestinationDataProvider.JCO_SYSNR, "00"); connProps.setProperty(DestinationDataProvider.JCO_USER, "STONE"); connProps.setProperty(DestinationDataProvider.JCO_PASSWD, "xxxxxx"); connProps.setProperty(DestinationDataProvider.JCO_CLIENT, "001"); connProps.setProperty(DestinationDataProvider.JCO_LANG, "EN"); return connProps; } public static JCoDestination getDestination() throws JCoException { String destName = "SAP_AS"; Properties props = setProperties(); DestinationDataProviderImp destDataProvider = new DestinationDataProviderImp(); destDataProvider.addDestinationProperties(destName, props); Environment.registerDestinationDataProvider(destDataProvider); JCoDestination dest = JCoDestinationManager.getDestination(destName); return dest; } }

第三部分:测试DestinationProvidergetDestination()方法:

package jco3.demo3;import org.junit.Test;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoException; public class TestDestionProvider { @Test public void pingSAPDestination() throws JCoException { JCoDestination dest = DestinationProvider.getDestination(); dest.ping(); } }
 

JCo3.0调用SAP函数的过程

大致可以总结为以下步骤:

  • 连接至SAP系统
  • 创建JcoFunction接口的实例(这个实例代表SAP系统中相关函数)
  • 设置importing参数
  • 调用函数
  • 从exporting参数或者table参数获取数据

代码:

package jco3.demo4;import org.junit.Test;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager; import com.sap.conn.jco.JCoException; import com.sap.conn.jco.JCoField; import com.sap.conn.jco.JCoFunction; import com.sap.conn.jco.JCoRepository; import com.sap.conn.jco.JCoStructure; public class RFC { public void getCompanyCodeDetail(String cocd) throws JCoException { // JCoDestination instance represents the backend SAP system JCoDestination dest = JCoDestinationManager.getDestination("ECC"); // JCoFunction instance is the FM in SAP we will use JCoRepository repository = dest.getRepository(); JCoFunction fm = repository.getFunction("BAPI_COMPANYCODE_GETDETAIL"); if (fm == null){ throw new RuntimeException("Function does not exists in SAP system."); } // set import parameter(s) fm.getImportParameterList().setValue("COMPANYCODEID", cocd); // call function fm.execute(dest); // get company code detail from exporting parameter 'COMPANYCODE_DETAIL' JCoStructure cocdDetail = fm.getExportParameterList() .getStructure("COMPANYCODE_DETAIL"); this.printStructure(cocdDetail); } private void printStructure(JCoStructure jcoStru) { for(JCoField field : jcoStru){ System.out.println(String.format("%s\\t%s", field.getName(), field.getString())); } } @Test public void test() throws JCoException { this.getCompanyCodeDetail("Z900"); } }

JCoFunction接口说明

  • JCoFunction是一个接口,代表SAP系统的函数

  • JCoFunction包含importing参数,exporting参数,changing参数,table参数。分别使用getImportParameterList方法,getExportParameterList方法,getChangingParameterList方法和getTableParameterList获得。这些方法的返回值都是JCoParameter类型

  • JCoFunction.execute方法实际执行函数

如何创建JCoFunction对象

上面的代码是第一种创建JCoFunction实例的方法:

JCoRepository repository = dest.getRepository();    
JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");

如果我们不关心JCoRepository,也可以这样写:

JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");

第三种方法是使用JCoFunctionTemplate.getFunction方法,JCoFunctionTemplate也是一个接口,代表SAP函数的meta-data。

JCoFunctionTemplate fmTemplate = dest.getRepository().getFunctionTemplate("BAPI_COMPANYCODE_GETDETAIL");
JCoFunction fm = fmTemplate.getFunction();

JCoStructure接口

BAPI_COMPANY_CODE_GETDETAIL函数的COMPANYCODE_DETAIL参数是一个结构,刚才我们看到遍历结构所有字段的方式:

private void printStructure(JCoStructure jcoStru) { for(JCoField field : jcoStru){ System.out.println(String.format("%s\\t%s", field.getName(), field.getString())); } }

因为JCoStructure实现了Iterable接口,所以可以采取上面的办法进行迭代。另外一种方法进行遍历:

private void printStructure2(JCoStructure jcoStructure) { for (int i = 0; i < jcoStructure.getMetaData().getFieldCount(); i++){ System.out.println(String.format("%s\\t%s", jcoStructure.getMetaData().getName(i), jcoStructure.getString(i))); } }

BAPI_COMPANYCODE_GETDETAIL是一个适合演示的函数,没有import paramter参数,调用后COMPANYCODE_GETDETAIL 表参数返回SAP系统中所有公司代码的清单。只包括公司代码ID和公司代码名称两个字段。

JCo中,与表参数相关的两个接口是JCoTableJCoRecordMetaDtaJCoTable就是RFM中tabl参数,而JCoRecordMetaDtaJCoTableJCoStructure的元数据。

在.net环境中,我喜欢将IRfcTable转换成DataTable,但Java没有类似的数据结构,所以决定直接在方法中传递JCoTable算了。但为了方便显示,可以考虑使用一个通用代码进行输出:

package jco3.utils;import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoRecordMetaData;
import com.sap.conn.jco.JCoTable;public class JCoUtils
{public static void printJCoTable(JCoTable jcoTable) { // header // JCoRecordMeataData is the meta data of either a structure or a table. // Each element describes a field of the structure or table. JCoRecordMetaData tableMeta = jcoTable.getRecordMetaData(); for(int i = 0; i < tableMeta.getFieldCount(); i++){ System.out.print(String.format("%s\t", tableMeta.getName(i))); } System.out.println(); // new line // line items for(int i = 0; i < jcoTable.getNumRows(); i++){ // Sets the row pointer to the specified position(beginning from zero) jcoTable.setRow(i); // Each line is of type JCoStructure for(JCoField fld : jcoTable){ System.out.print(String.format("%s\t", fld.getValue())); } System.out.println(); } } }

要点说明

对JCoTable,输出表头和行项目。表头通过获取JCoTable的meta-data,然后使用meta-data的getName()方法。

JCoRecordMetaData tableMeta = jcoTable.getRecordMetaData();        
for(int i = 0; i < tableMeta.getFieldCount(); i++){System.out.print(String.format("%s\t", tableMeta.getName(i))); }

JCoTable每一行都是一个JCoStructure,可以通过setRow()设置指针的位置,然后再遍历各个field:

        for(int i = 0; i < jcoTable.getNumRows(); i++){// Sets the row pointer to the specified position(beginning from zero) jcoTable.setRow(i); // Each line is of type JCoStructure for(JCoField fld : jcoTable){ System.out.print(String.format("%s\t", fld.getValue())); } System.out.println(); }

完成输出之后,接下来就是RFM调用:

package jco3.demo5;import org.junit.Test;
import com.sap.conn.jco.*;
import jco3.utils.JCoUtils; public class JCoTableDemo { public JCoTable getCocdList() throws JCoException { /** * Get company code list in SAP * using BAPI BAPI_COMPANYCODE_GETLIST. * * Since JCoTable is rather flexible, we simply use * this interface as return value */ JCoDestination dest = JCoDestinationManager.getDestination("ECC"); JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETLIST"); fm.execute(dest); JCoTable companies = fm.getTableParameterList().getTable("COMPANYCODE_LIST"); return companies; } @Test public void printCompanies() throws JCoException { JCoTable companies = this.getCocdList(); JCoUtils.printJCoTable(companies); } }

Table参数作为import parameter

table作为输入参数,主要解决填充table的问题,基本模式如下:

someTable.appendRow();
someTable.setValue("FLDNAME", someValue);

以RFC_READ_TABLE为例,读取SAP USR04表。

package jco3.demo5;import org.junit.Test;
import com.sap.conn.jco.*;
import jco3.utils.JCoUtils; public class JCoTableAsImport { public JCoTable readTable() throws JCoException { /** * Shows how to process JCoTable (as importing) */ JCoDestination dest = JCoDestinationManager.getDestination("ECC"); JCoFunction fm = dest.getRepository().getFunction("RFC_READ_TABLE"); // table we want to query is USR04 // which is user authorization table in SAP fm.getImportParameterList().setValue("QUERY_TABLE", "USR04"); // output data will be delimited by comma fm.getImportParameterList().setValue("DELIMITER", ","); // processing table parameters JCoTable options = fm.getTableParameterList().getTable("OPTIONS"); // modification date >= 2012.01.01 and <= 2015.12.31 options.appendRow(); options.setValue("TEXT", "MODDA GE '20120101' "); options.appendRow(); options.setValue("TEXT", "AND MODDA LE '20151231' "); // We only care about fields of [user id] and [modification date] String[] outputFields = new String[] {"BNAME", "MODDA"}; JCoTable fields = fm.getTableParameterList().getTable("FIELDS"); int count = outputFields.length; fields.appendRows(count); for (int i = 0; i < count; i++){ fields.setRow(i); fields.setValue("FIELDNAME", outputFields[i]); } fm.execute(dest); JCoTable data = fm.getTableParameterList().getTable("DATA"); return data; } @Test public void printUsers() throws JCoException { JCoTable users = this.readTable(); JCoUtils.printJCoTable(users); } }

在代码中我们使用了两种方法来插入table的行项目,第一种方法:

JCoTable options = fm.getTableParameterList().getTable("OPTIONS");
// modification date >= 2012.01.01 and <= 2015.12.31 options.appendRow(); options.setValue("TEXT", "MODDA GE '20120101' "); options.appendRow(); options.setValue("TEXT", "AND MODDA LE '20151231' ");

第二种方法:

String[] outputFields = new String[] {"BNAME", "MODDA"};
JCoTable fields = fm.getTableParameterList().getTable("FIELDS"); int count = outputFields.length; fields.appendRows(count); for (int i = 0; i < count; i++){ fields.setRow(i); fields.setValue("FIELDNAME", outputFields[i]); }

JCoTable重要方法总结

id="iframe_0.6286778007291249" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload-images.jianshu.io/upload_images/1765749-980063a33463da2f.gif?imageMogr2/auto-orient/strip&_=5671148%22%20style=%22border:none;max-width:999px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.6286778007291249',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="margin: 0px; padding: 0px; border: none; width: 629px; height: 472px;">
jcoTable_methods.gif


这篇关于jCO--http://www.cnblogs.com/zfswff/p/5671148.html的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1087049

相关文章

vue, 左右布局宽,可拖动改变

1:建立一个draggableMixin.js  混入的方式使用 2:代码如下draggableMixin.js  export default {data() {return {leftWidth: 330,isDragging: false,startX: 0,startWidth: 0,};},methods: {startDragging(e) {this.isDragging = tr

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

js+css二级导航

效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Con

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页:

vue+el国际化-东抄西鉴组合拳

vue-i18n 国际化参考 https://blog.csdn.net/zuorishu/article/details/81708585 说得比较详细。 另外做点补充,比如这里cn下的可以以项目模块加公共模块来细分。 import zhLocale from 'element-ui/lib/locale/lang/zh-CN' //引入element语言包const cn = {mess

vue同页面多路由懒加载-及可能存在问题的解决方式

先上图,再解释 图一是多路由页面,图二是路由文件。从图一可以看出每个router-view对应的name都不一样。从图二可以看出层路由对应的组件加载方式要跟图一中的name相对应,并且图二的路由层在跟图一对应的页面中要加上components层,多一个s结尾,里面的的方法名就是图一路由的name值,里面还可以照样用懒加载的方式。 页面上其他的路由在路由文件中也跟图二是一样的写法。 附送可能存在

vue+elementUI下拉框联动显示

<el-row><el-col :span="12"><el-form-item label="主账号:" prop="partyAccountId" :rules="[ { required: true, message: '主账号不能为空'}]"><el-select v-model="detailForm.partyAccountId" filterable placeholder="

vue+elementui分页输入框回车与页面中@keyup.enter事件冲突解决

解决这个问题的思路只要判断事件源是哪个就好。el分页的回车触发事件是在按下时,抬起并不会再触发。而keyup.enter事件是在抬起时触发。 so,找不到分页的回车事件那就拿keyup.enter事件搞事情。只要判断这个抬起事件的$event中的锚点样式判断不等于分页特有的样式就可以了 @keyup.enter="allKeyup($event)" //页面上的//js中allKeyup(e

vue子路由回退后刷新页面方式

最近碰到一个小问题,页面中含有 <transition name="router-slid" mode="out-in"><router-view></router-view></transition> 作为子页面加载显示的地方。但是一般正常子路由通过 this.$router.go(-1) 返回到上一层原先的页面中。通过路由历史返回方式原本父页面想更新数据在created 跟mounted