1、概述

LitElement管理您声明的属性及其对应的属性。默认情况下,LitElement将:

  • 确保在任何声明的属性更改时进行元素更新。
  • 捕获已声明属性的实例值。在浏览器注册自定义元素定义之前设置的所有属性值。
  • 使用每个属性的小写名称设置观察到的(未引用的)属性。
  • 处理声明为字符串,数字,布尔值,数组和对象类型的属性的属性转换。
  • 使用直接比较(oldValue !== newValue)测试属性更改。
  • 应用超类声明的所有属性选项和访问器。

属性选项

属性声明是具有以下格式的对象:

{ optionName1: optionValue1, optionName2: optionValue2, ... }

也可以是以下选项:

  • converter: Convert between properties and attributes.
  • type: Use LitElement’s default attribute converter.
  • attribute: Configure observed attributes.
  • reflect: Configure reflected attributes.
  • noAccessor: Whether to set up a default property accessor.
  • hasChanged: Specify what constitutes a property change.

可以在静态属性getter中或使用TypeScript装饰器指定所有属性声明选项。

2、声明属性

通过实现静态 properties 或使用装饰器(注解)来声明元素的属性,就像C的声明与定义分开的写法:

// properties getter
static get properties() {
return {
prop1: { type: String }
};
}
// Decorators (requires TypeScript or Babel)
export class MyElement extends LitElement {
@property( { type : String } ) prop1 = '';

2.1 在静态properties getter中声明属性

static get properties() {
return {
prop1: { type: String },
prop2: { type: Number },
prop3: { type: Boolean }
};
}

注意:如果实现静态属性获取器,请在元素构造函数中初始化属性值。

constructor() {
// Always call super() first
super();
this.prop1 = 'Hello World';
...
}

请记住,首先要在构造函数中调用super(),否则元素将无法渲染。

示例:使用静态属性获取器声明属性

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties() { return {
prop1: { type: String },
prop2: { type: Number },
prop3: { type: Boolean },
prop4: { type: Array },
prop5: { type: Object }
};} constructor() {
super();
this.prop1 = 'Hello World';
this.prop2 = 5;
this.prop3 = false;
this.prop4 = [1,2,3];
this.prop5 = { subprop1: 'prop 5 subprop1 value' }
} render() {
return html`
<p>prop1: ${this.prop1}</p>
<p>prop2: ${this.prop2}</p>
<p>prop3: ${this.prop3}</p>
<p>prop4[0]: ${this.prop4[0]}</p>
<p>prop5.subprop1: ${this.prop5.subprop1}</p>
`;
}
} customElements.define('my-element', MyElement);

2.2 用注解声明属性

翻译为装饰器,但我更喜欢称之为注解(Java框架),一般用在TS文件中

@property({type : String})  prop1 = 'Hello World';

装饰器是JavaScript的一项建议功能,因此您需要使用Babel或Translate编译器(例如TypeScript编译器)来使用装饰器。

如果您使用的是Babel,则需要使用@babel/plugin-proposal-decorators插件

如果你使用TypeScript,你需要激活 experimentalDecorators 编译选项(例如:在tsconfig.json配置文件中设置"experimentalDecorators": true),不推荐也不必要激活emitDecoratorMetadata选项

用注解声明属性的例子:

my-element.ts

import { LitElement, html, customElement, property } from 'lit-element';

@customElement('my-element')
export class MyElement extends LitElement {
@property({type : String}) prop1 = 'Hello World';
@property({type : Number}) prop2 = 5;
@property({type : Boolean}) prop3 = true;
@property({type : Array}) prop4 = [1,2,3];
@property({type : Object}) prop5 = { subprop1: 'prop 5 subprop1 value' }; render() {
return html`
<p>prop1: ${this.prop1}</p>
<p>prop2: ${this.prop2}</p>
<p>prop3: ${this.prop3}</p>
<p>prop4[0]: ${this.prop4[0]}</p>
<p>prop5.subprop1: ${this.prop5.subprop1}</p>
`;
}
}

index.ts

import './my-element.ts';

index.html

<!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">
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
<title>lit-element code sample</title> </head> <body>
<my-element></my-element>
</body> </html>

3、初始化属性值

3.1 在构造方法中初始化属性值

static get properties() { return { /* Property declarations */ }; } 

constructor() {
// Always call super() first
super(); // Initialize properties
this.prop1 = 'Hello World';
}

注意:组件实现类的所有构造方法中都必须手动调用父类的构造方法 super()

完整的例子:

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties() { return {
prop1: { type: String },
prop2: { type: Number },
prop3: { type: Boolean },
prop4: { type: Array },
prop5: { type: Object }
};} constructor() {
super();
this.prop1 = 'Hello World';
this.prop2 = 5;
this.prop3 = true;
this.prop4 = [1,2,3];
this.prop5 = { stuff: 'hi', otherStuff: 'wow' };
} render() {
return html`
<p>prop1: ${this.prop1}</p>
<p>prop2: ${this.prop2}</p>
<p>prop3: ${this.prop3}</p> <p>prop4: ${this.prop4.map((item, index) =>
html`<span>[${index}]:${item}&nbsp;</span>`)}
</p> <p>prop5:
${Object.keys(this.prop5).map(item =>
html`<span>${item}: ${this.prop5[item]}&nbsp;</span>`)}
</p>
`;
}
}
customElements.define('my-element', MyElement);

3.2 使用TypeScript 注解初始化属性值

在TypeScript中使用@property注解来初始化属性值

@property({ type : String }) prop1 = 'Hello World';

即可以直接在声明的同时初始化,将 static properties getter()方法和 constructor()方法所作的事情合而为一

例子:

import { LitElement, html, customElement, property } from 'lit-element';

@customElement('my-element')
export class MyElement extends LitElement {
// Declare and initialize properties
@property({type : String}) prop1 = 'Hello World';
@property({type : Number}) prop2 = 5;
@property({type : Boolean}) prop3 = true;
@property({type : Array}) prop4 = [1,2,3];
@property({type : Object}) prop5 = { subprop1: 'hi', thing: 'fasdfsf' }; render() {
return html`
<p>prop1: ${this.prop1}</p>
<p>prop2: ${this.prop2}</p>
<p>prop3: ${this.prop3}</p> <p>prop4: ${this.prop4.map((item, index) =>
html`<span>[${index}]:${item}&nbsp;</span>`)}
</p> <p>prop5:
${Object.keys(this.prop5).map(item =>
html`<span>${item}: ${this.prop5[item]}&nbsp;</span>`)}
</p>
`;
}
}

3.3 在标签中初始化属性值

ndex.html

<my-element
mystring="hello world"
mynumber="5"
mybool
myobj='{"stuff":"hi"}'
myarray='[1,2,3,4]'></my-element>

就像普通的html写法一样

4、配置属性

4.1 properties 和 attributes的转换

虽然元素 properties 可以是任何类型,但是 attributes 始终是字符串。这会影响非字符串属性的  observed attributes 和 reflected attributes:

要 observe 一个属性(set a property from an attribute),属性值必须由string类型转换为匹配的类型

要 reflect 一个属性(set an attribute from a property),属性值必须被转化为string

4.1.1 使用默认转换

在处理 String,Number, Boolean,Array, and Object  属性类型时,LitElement有一个默认的转换规则

要使用默认的转换规则,需要在你的属性声明中指明 type 选项

// Use LitElement's default converter
prop1: { type: String },
prop2: { type: Number },
prop3: { type: Boolean },
prop4: { type: Array },
prop5: { type: Object }

以下信息显示默认转换器如何处理每种类型的转换。

从 attribute 转换到 property :

  • 对于Strings类型, 直接使用,无需转换
  • 对于Numbers类型,调用 Number(attributeValue) 构造函数将
  • 对于Boolean 类型,非null转化为true,null转化为 false
  • 对于Arrays 和 Objects,调用 JSON.parse(attributeValue)

从 property 转换到 attribute  :

  • 对于Strings,如果 property 是

    • null,删除该 attribute
    • undefined,不做改变
    • 否则直接 attribute 作为 property 值
  • 对于Numbers,同上
  • 对于 Booleans,property 值
    • 为真则创建属性
    • 为假则删除属性
  • 对于 Objects and Arrays  ,
    • 如果为 null 或 undefined 则删除属性
    • 否则 JSON.stringify(propertyValue) 转换

使用默认转换的例子:

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties() { return {
prop1: { type: String, reflect: true },
prop2: { type: Number, reflect: true },
prop3: { type: Boolean, reflect: true },
prop4: { type: Array, reflect: true },
prop5: { type: Object, reflect: true }
};} constructor() {
super();
this.prop1 = '';
this.prop2 = 0;
this.prop3 = false;
this.prop4 = [];
this.prop5 = { };
} attributeChangedCallback(name, oldVal, newVal) {
console.log('attribute change: ', name, newVal);
super.attributeChangedCallback(name, oldVal, newVal);
} render() {
return html`
<p>prop1 ${this.prop1}</p>
<p>prop2 ${this.prop2}</p>
<p>prop3 ${this.prop3}</p> <p>prop4: ${this.prop4.map((item, index) =>
html`<span>[${index}]:${item}&nbsp;</span>`)}
</p> <p>prop5:
${Object.keys(this.prop5).map(item =>
html`<span>${item}: ${this.prop5[item]}&nbsp;</span>`)}
</p> <button @click="${this.changeProperties}">change properties</button>
<button @click="${this.changeAttributes}">change attributes</button>
`;
} changeAttributes() {
let randy = Math.floor(Math.random()*10);
let myBool = this.getAttribute('prop3'); this.setAttribute('prop1', randy.toString());
this.setAttribute('prop2', randy.toString());
this.setAttribute('prop3', myBool? '' : null);
this.setAttribute('prop4', JSON.stringify([...this.prop4, randy]));
this.setAttribute('prop5',
JSON.stringify(Object.assign({}, this.prop5, {[randy]: randy})));
this.requestUpdate();
} changeProperties() {
let randy = Math.floor(Math.random()*10);
let myBool = this.prop3; this.prop1 = randy.toString();
this.prop2 = randy;
this.prop3 = !myBool;
this.prop4 = [...this.prop4, randy];
this.prop5 = Object.assign({}, this.prop5, {[randy]: randy});
} updated(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
console.log(`${propName} changed. oldValue: ${oldValue}`);
});
} } customElements.define('my-element', MyElement);

4.1.2 配置自定义转换

您可以使用converter选项在属性声明中指定自定义属性转换器:

myProp: {
converter: // Custom property converter
}

converter可以是一个对象或函数,如果是一个对象,它有2个关键字 fromAttribute 和 toAttribute

prop1: {
converter: {
fromAttribute: (value, type) => {
// `value` is a string
// Convert it to a value of type `type` and return it
},
toAttribute: (value, type) => {
// `value` is of type `type`
// Convert it to a string and return it
}
}
}

如果是一个函数,它被用来替代 fromAttribute:

myProp: {
converter: (value, type) => {
// `value` is a string
// Convert it to a value of type `type` and return it
}
}

如果没有为反射的属性提供toAttribute函数,则该属性将设置为property 值,而无需进行转换。

在更新期间:

  • If toAttribute returns null, the attribute is removed.

  • If toAttribute returns undefined, the attribute is not changed.

自定义转换的例子:

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties() { return {
myProp: {
reflect: true,
converter: {
toAttribute(value) {
console.log('myProp\'s toAttribute.');
console.log('Processing:', value, typeof(value));
let retVal = String(value);
console.log('Returning:', retVal, typeof(retVal));
return retVal;
}, fromAttribute(value) {
console.log('myProp\'s fromAttribute.');
console.log('Processing:', value, typeof(value));
let retVal = Number(value);
console.log('Returning:', retVal, typeof(retVal));
return retVal;
}
}
}, theProp: {
reflect: true,
converter(value) {
console.log('theProp\'s converter.');
console.log('Processing:', value, typeof(value)); let retVal = Number(value);
console.log('Returning:', retVal, typeof(retVal));
return retVal;
}},
};} constructor() {
super();
this.myProp = 'myProp';
this.theProp = 'theProp';
} attributeChangedCallback(name, oldval, newval) {
// console.log('attribute change: ', name, newval);
super.attributeChangedCallback(name, oldval, newval);
} render() {
return html`
<p>myProp ${this.myProp}</p>
<p>theProp ${this.theProp}</p> <button @click="${this.changeProperties}">change properties</button>
<button @click="${this.changeAttributes}">change attributes</button>
`;
} changeAttributes() {
let randomString = Math.floor(Math.random()*100).toString();
this.setAttribute('myprop', 'myprop ' + randomString);
this.setAttribute('theprop', 'theprop ' + randomString);
this.requestUpdate();
} changeProperties() {
let randomString = Math.floor(Math.random()*100).toString();
this.myProp='myProp ' + randomString;
this.theProp='theProp ' + randomString;
}
}
customElements.define('my-element', MyElement);

4.1.3 配置观察属性

只要 observed attribute 发生更改,就会触发自定义元素API回调 attributeChangedCallback。默认情况下,每当某个属性触发此回调时,LitElement就会使用属性的 fromAttribute函数从该attribute 设置property值。

默认情况下,LitElement为所有声明的属性创建一个相应的观察属性。被观察属性的名称是属性名称,小写:

// observed attribute name is "myprop"
myProp: { type: Number }

要使用其他名称创建观察到的属性,请将attribute设置为字符串:

// Observed attribute will be called my-prop
myProp: { attribute: 'my-prop' }

为了防止为从property创建observed attribute,请将attribute设置为false。该property 不会从标记中的attributes 初始化,并且attribute 更改不会对其产生影响。

// No observed attribute for this property
myProp: { attribute: false }

配置observed attributes的例子

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties() { return {
myProp: { attribute: true },
theProp: { attribute: false },
otherProp: { attribute: 'other-prop' },
};} constructor() {
super();
this.myProp = 'myProp';
this.theProp = 'theProp';
this.otherProp = 'otherProp';
} attributeChangedCallback(name, oldval, newval) {
console.log('attribute change: ', name, newval);
super.attributeChangedCallback(name, oldval, newval);
} render() {
return html`
<p>myProp ${this.myProp}</p>
<p>theProp ${this.theProp}</p>
<p>otherProp ${this.otherProp}</p> <button @click="${this.changeAttributes}">change attributes</button>
`;
} changeAttributes() {
let randomString = Math.floor(Math.random()*100).toString();
this.setAttribute('myprop', 'myprop ' + randomString);
this.setAttribute('theprop', 'theprop ' + randomString);
this.setAttribute('other-prop', 'other-prop ' + randomString);
this.requestUpdate();
} updated(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
console.log(`${propName} changed. oldValue: ${oldValue}`);
});
}
}
customElements.define('my-element', MyElement);
设置了 theProp: { attribute: false }, 所以当 attribute更改时,其值不会发生改变

4.1.4 配置反射属性

您可以配置property ,以便每当property 更改时,其值都会反射到其 observed attribute 中。例如:

// Value of property "myProp" will reflect to attribute "myprop"
myProp: { reflect: true }

property更改后,LitElement使用属性转换器中的toAttribute函数从新property值中设置attribute值。

  • If toAttribute returns null, the attribute is removed.

  • If toAttribute returns undefined, the attribute is not changed.

  • If toAttribute itself is undefined, the property value is set to the attribute value without conversion.

LitElement跟踪更新期间的反射状态。LitElement跟踪状态信息,以避免在属性与观察到的反射属性之间创建无限循环的变化。

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties() { return {
myProp: { reflect: true }
};} constructor() {
super();
this.myProp='myProp';
} attributeChangedCallback(name, oldval, newval) {
console.log('attribute change: ', newval);
super.attributeChangedCallback(name, oldval, newval);
} render() {
return html`
<p>${this.myProp}</p> <button @click="${this.changeProperty}">change property</button>
`;
} changeProperty() {
let randomString = Math.floor(Math.random()*100).toString();
this.myProp='myProp ' + randomString;
} }
customElements.define('my-element', MyElement);

4.2 配置属性访问器

默认情况下,LitElement为所有声明的属性生成一个属性访问器。每当您设置属性时,都会调用访问器:

// Declare a property
static get properties() { return { myProp: { type: String } }; }
...
// Later, set the property
this.myProp = 'hi'; // invokes myProp's generated property accessor

生成的访问器会自动调用requestUpdate,如果尚未开始,则启动更新。

4.2.1 创建自己的属性访问器

也就是Java类常用的自定义属性的get set方法

要指定属性的获取和设置的工作方式,可以定义自己的属性访问器。例如:

static get properties() { return { myProp: { type: String } }; }

set myProp(value) {
const oldValue = this.myProp;
// Implement setter logic here...
this.requestUpdate('myProp', oldValue);
}
get myProp() { ... } ... // Later, set the property
this.myProp = 'hi'; // Invokes your accessor

如果您的类为属性定义了自己的访问器,则LitElement不会用生成的访问器覆盖它们。如果您的类没有为属性定义访问器,即使超类定义了一个或多个属性,LitElement也会生成它们。

LitElement生成的设置器会自动调用requestUpdate。如果编写自己的设置器,则必须手动调用requestUpdate,并提供属性名称及其旧值。

例子:

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties() {
return { prop: { type: Number } };
} set prop(val) {
let oldVal = this._prop;
this._prop = Math.floor(val);
this.requestUpdate('prop', oldVal);
} get prop() { return this._prop; } constructor() {
super();
this._prop = 0;
} render() {
return html`
<p>prop: ${this.prop}</p>
<button @click="${() => { this.prop = Math.random()*10; }}">
change prop
</button>
`;
}
}
customElements.define('my-element', MyElement);

如果要将自己的属性访问器与@property装饰器一起使用,则可以通过将装饰器放在getter上来实现此目的:

_myProp: string = '';

  @property({ type: String })
public get myProp(): string {
return this._myProp;
}
public set myProp(value: string) {
const oldValue = this.myProp;
this._myProp = value;
this.requestUpdate('myProp', oldValue);
}

4.2.2 防止LitElement生成属性访问器

在极少数情况下,子类可能需要为其父类上存在的属性更改或添加属性选项

为了防止LitElement生成覆盖父类的已定义访问器的属性访问器(防止覆盖父类属性get set 方法),请在属性声明中将noAccessor设置为true:

static get properties() {
return { myProp: { type: Number, noAccessor: true } };
}

定义自己的访问器时,无需设置Accessor。

例如,

父类

import { LitElement, html } from 'lit-element';

export class SuperElement extends LitElement {
static get properties() {
return { prop: { type: Number } };
} set prop(val) {
let oldVal = this._prop;
this._prop = Math.floor(val);
this.requestUpdate('prop', oldVal);
} get prop() { return this._prop; } constructor() {
super();
this._prop = 0;
} render() {
return html`
<p>prop: ${this.prop}</p>
<button @click="${() => { this.prop = Math.random()*10; }}">
change prop
</button>
`;
}
}
customElements.define('super-element', SuperElement);

子类

import { SuperElement } from './super-element.js';

class SubElement extends SuperElement {
static get properties() {
return { prop: { reflectToAttribute: true, noAccessor: true } };
}
} customElements.define('sub-element', SubElement);

4.3 配置属性更改

所有声明的属性都有一个函数hasChanged,只要设置了属性,就会调用该函数。

hasChanged比较属性的旧值和新值,并评估属性是否已更改。如果hasChanged返回true,则如果尚未安排元素更新,则LitElement将开始元素更新。有关更新如何工作的更多信息,请参见Element更新生命周期文档。

  • hasChanged returns true if newVal !== oldVal.
  • hasChanged returns false if both the new and old values are NaN.

要为属性定制hasChanged,请将其指定为属性选项,也就是自定义属性更改的比较规则,相当于Java重写equals方法

myProp: { hasChanged(newVal, oldVal) {
// compare newVal and oldVal
// return `true` if an update should proceed
}}

例子:

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties(){ return {
myProp: {
type: Number, /**
* Compare myProp's new value with its old value.
*
* Only consider myProp to have changed if newVal is larger than
* oldVal.
*/
hasChanged(newVal, oldVal) {
if (newVal > oldVal) {
console.log(`${newVal} > ${oldVal}. hasChanged: true.`);
return true;
}
else {
console.log(`${newVal} <= ${oldVal}. hasChanged: false.`);
return false;
}
}
}};
} constructor(){
super();
this.myProp = 1;
} render(){
return html`
<p>${this.myProp}</p>
<button @click="${this.getNewVal}">get new value</button>
`;
} updated(){
console.log('updated');
} getNewVal(){
let newVal = Math.floor(Math.random()*10);
this.myProp = newVal;
} }
customElements.define('my-element', MyElement);

LitElement(四)属性的更多相关文章

  1. Struts2(四)属性驱动和模型驱动

    一.概述 所谓模型驱动,就是使用单独的JavaBean实例贯穿整个MVC流程,与之相对应的属性驱动方式,则使用属性作为贯穿MVC流程的信息携带者.属性无法独立存下,它必须依附于一个对象,这个对象就是A ...

  2. vue(四)--属性绑定

    v-bind通过v-bind进行属性绑定v-bind:href, 可以简写成 :href <body> <div id="app"> <a v-bin ...

  3. HTML5 Canvas 数据持久化存储之属性列表

    属性列表想必大家都不会陌生,正常用 HTML5 来做的属性列表大概就是用下拉菜单之类的,而且很多情况下,下拉列表还不够好看,怎么办?我试着用 HT for Web 来实现属性栏点击按钮弹出多功能选框, ...

  4. Java获取项目根目录等其他系统属性

    一 相对路径的获得 说明:相对路径(即不写明时候到底相对谁)均可通过以下方式获得(不论是一般的java项目还是web项目) String relativelyPath=System.getProper ...

  5. wpf控件开发基础(3) -属性系统(2)

    原文:wpf控件开发基础(3) -属性系统(2) 上篇说明了属性存在的一系列问题. 属性默认值,可以保证属性的有效性. 属性验证有效性,可以对输入的属性进行校验 属性强制回调, 即不管属性有无发生变化 ...

  6. wpf控件开发基础(4) -属性系统(3)

    原文:wpf控件开发基础(4) -属性系统(3) 知识回顾 接上篇,上篇我们真正接触到了依赖属性的用法,以及依赖属性的属性元数据的用法,并且也实实在在地解决了之前第二篇提到的一系列问题.来回顾一下 属 ...

  7. 03.JavaScript 面向对象精要--理解对象

    JavaScript 面向对象精要--理解对象 尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的对象.JavaScript中的对象是动态的. 一.定义属性 当一个属性第1次 ...

  8. 想要学好JQuery看这里

    一.简介 jQuery 库可以通过一行简单的标记被添加到网页中 jQuery 是一个 JavaScript 函数库. jQuery 库包含以下特性: HTML 元素选取 HTML 元素操作 CSS 操 ...

  9. java路径问题总结

    平时写程序的时候,很多时候提示文件找不到,而抛出了异常,现在整理如下[一 相对路径的获得] 说明:相对路径(即不写明时候到底相对谁)均可通过以下方式获得(不论是一般的java项目还是web项目) St ...

随机推荐

  1. js磁力线代码(非压缩,自己在压缩的版本上优化了代码,易于阅读)

    拿去白嫖吧: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=" ...

  2. C++ const和constexpr

    const expression , 常量表达式 , 在<C++ Primer>的定义:值不会改变并且在编译过程就能得到计算结果的表达式.   它要求两点:值不会改变,编译过程得到结果. ...

  3. 小白的java学习之路 “ 二重循环”

    二重循环: 1.什么是二重循环: 一个循环体内又包含另一个完整的循环结构 语法: while(循环条件1) { //循环操作1 while(循环条件2) { //循环操作2 } } do { //循环 ...

  4. C# VS2017 WinForm 打包和升级

    C# WinFrom打包不怎么常用,但一年总有那么一两次,每次都记不全,为了方便自己回看,于是有了本篇文章. 本例使用<C#工具类LogHelper>的解决方案作为例子,实现WinForm ...

  5. C# 中indexOf、lastIndexOf、subString方法的理解

    一.indexOf() indexOf("\\"):返回"\\"字符在此实例中第一个出现的索引位置,实例的下标是从0开始,如果未找到则返回-1. indexOf ...

  6. LeetCode-21 有序链表的合并

    问题描述: 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4输出:1->1-& ...

  7. 题解【洛谷P1596】[USACO10OCT]Lake Counting

    题面 \(\text{Flood Fill}\) 模板题. \(\text{Flood Fill}\) 可以快速求出一个图中连通块的个数. 大概就是遍历每一个点,如果它没有被遍历过且是一个新连通块,那 ...

  8. 安卓android eclipse运行提示no compatible targets were found

    在eclipse中开发安卓应用,运行项目时,右击项目名称---Run As---Android Application时, 系统提示"No compatible targets were f ...

  9. Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class 消费者提示需要配置数据源

    使用 由于给前端做分页 在启动消费者的时候遇到了这个问题 Failed to configure a DataSource: 'url' attribute is not specified and ...

  10. Ajax基础原理与应用

    Ajax函数封装ajax.js // Get / Post // 参数 get post // 是否异步 // 如何处理响应数据 // URL // var handleResponse = func ...