Lit 组件接收输入并将其状态存储为 JavaScript 类字段或属性。响应式属性是可以在更改时触发响应式更新周期、重新渲染组件以及可选地读取或写入属性的属性。

Lit 管理您的反应属性及其相应的属性。尤其是:

  • 反应性更新。Lit 为每个反应属性生成一个 getter/setter 对。当反应性属性发生变化时,组件会安排更新。
  • 属性处理。默认情况下,Lit 会设置属性对应的被观察属性,并在属性发生变化时更新属性。属性值也可以选择性地反映回属性。
  • 超类属性。Lit 自动应用超类声明的属性选项。除非您想更改选项,否则您不需要重新声明属性。
  • 元素升级。如果在元素已经在 DOM 中之后定义了 Lit 组件,则 Lit 会处理升级逻辑,确保在升级之前设置在元素上的任何属性在元素升级时触发正确的反应性副作用。

属性选项

attribute
属性是否与属性关联,或者关联属性的自定义名称。默认值:真。如果attribute为 false,converter则忽略reflect和type选项。

converter
用于在属性和属性之间转换的自定义转换器。如果未指定,请使用默认属性转换器。

hasChanged
每当设置属性时调用的函数以确定属性是否已更改,并应触发更新。如果未指定,LitElement 将使用严格的不等式检查 ( newValue !== oldValue) 来确定属性值是否已更改。

noAccessor
设置为 true 以避免生成默认属性访问器。这个选项很少需要。默认值:false。

reflect
属性值是否反映回关联的属性。默认值:false。

state
设置为 true 以将属性声明为内部反应状态。内部反应状态触发更新,如公共反应属性,但 Lit 不会为其生成属性,用户不应从组件外部访问它。相当于使用@state装饰器。默认值:false。

type
在将字符串值的属性转换为属性时,Lit 的默认属性转换器会将字符串解析为给定的类型,反之亦然,将属性反映为属性时。如果converter设置,此字段将传递给转换器。如果type未指定,则默认转换器将其视为type: String.

公共属性 @property

class MyElement extends LitElement {@property()name: string;
}

组件不应更改其自己的公共属性,除非响应用户输入

内部状态 @state()

@state()
private _counter = 0;

内部反应状态是指不属于组件公共 API 的反应属性。这些状态属性没有相应的属性,并且不打算从组件外部使用。内部反应状态应该由组件本身设置。

不应从组件外部引用内部反应状态。在 TypeScript 中,这些属性应标记为私有或受保护。我们还建议使用前导下划线 ( _) 之类的约定来标识 JavaScript 用户的私有或受保护属性。
您可以为内部反应状态指定的唯一选项是hasChanged函数。

声明属性

properties使用装饰器或静态字段声明元素的公共反应属性。在任何一种情况下,您都可以传递一个选项对象来配置属性的功能。

使用@property带有类字段声明的装饰器来声明反应性属性。

class MyElement extends LitElement {@property({type: String})mode: string;@property({attribute: false})data = {};
}

@property装饰器的参数是一个选项对象。省略参数等效于为所有选项指定默认值。

在静态properties类字段中声明属性

class MyElement extends LitElement {static properties = {mode: {type: String},data: {attribute: false},};constructor() {super();this.data = {};}
}

声明属性时避免类字段的问题

类字段与反应属性的交互存在问题。类字段在元素实例上定义。反应性属性被定义为元素原型上的访问器。根据 JavaScript 的规则,实例属性优先于并有效地隐藏了原型属性。这意味着当使用类字段时,反应式属性访问器不起作用。设置属性后,元素不会更新。

在JavaScript 中,声明反应属性时不能使用类字段。相反,必须在元素构造函数中初始化属性:

constructor() {super();this.data = {};
}

可以理解为类字段在构造器上定义后是类上的一个属性;而声明属性,这个属性是响应式的,是组件上的一个属性。

属性更新

更新流程:

  1. 调用属性的设置器。
  2. setter 调用组件的requestUpdate方法。
  3. 比较属性的旧值和新值。
    • 默认情况下,Lit 使用严格的不等式测试来确定值是否已更改(即newValue !== oldValue)。
    • 如果属性具有hasChanged函数,则使用属性的旧值和新值调用它。
  4. 如果检测到属性更改,则会异步安排更新。如果已安排更新,则仅执行一次更新。
  5. 调用组件的update方法,将更改的属性反映到属性并重新呈现组件的模板。

调用组件的update方法,将更改的属性反映到属性并重新呈现组件的模板。

这个应该相当于vue里的监听

注: 请注意,如果您更改对象或数组属性,它不会触发更新,因为对象本身没有更改

更改对象和数组属性

改变对象或数组不会更改对象引用,因此不会触发更新。解决方式有两种:

  • 不可变的数据模式。将对象和数组视为不可变的。例如,要从 中删除一个项目myArray,请构造一个新数组:
this.myArray = this.myArray.filter((_, i) => i !== indexToRemove);
  • 手动触发更新。改变数据并requestUpdate()直接触发更新。例如:
this.myArray.splice(indexToRemove, 1);
this.requestUpdate();

属性

默认情况下,Lit 会为每个公共响应属性设置一个观察到的属性,并在属性更改时更新该属性。属性值也可以选择性地被反映(写回属性)。

虽然元素属性可以是任何类型,但属性始终是字符串。这会影响非字符串属性的观察属性和反射属性:

  • 要观察属性(从属性设置属性),必须将属性值从字符串转换为与属性类型匹配。
  • 要反映属性(从属性设置属性),必须将属性值转换为字符串。

设置属性名称

默认情况下,Lit 为所有公共响应属性创建相应的观察属性。观察到的属性的名称是属性名称,小写:

// 在组件上,属性就是 "myvalue"
@property({ type: Number })
myValue = 0;

要创建具有不同名称的观察属性,请设置attribute为字符串:

// 属性名将是 my-name,而不是myname
@property({ attribute: 'my-name' })
myName = 'Ogden';

要防止为属性创建观察到的属性,请设置attribute为false。该属性不会从标记中的属性初始化,并且属性更改不会影响它。

@property({ attribute: false })
myData = {};

大体意思就是这个属性将不再是相应式的,属性改变,模板不会更新

@customElement('base-app')
export class BaseApp extends LitElement {@property({ type: String }) aName = 'Lit'// 渲染组件render() {return html`<button @click="${this._changeName}">改变</button><simple-greeting name="${this.aName}"></simple-greeting>`;}private _changeName() {this.aName = 'World!';}
}

当将组件simple-greetingname属性设置为 @property({ type: String, attribute: false }) 再次点击按钮,内容将不会被改变

注: 内部反应状态永远不会有关联的属性。内部反应状态即@state()定义的属性

使用默认转换器

Lit 具有处理String、Number、Boolean、Array和Object属性类型的默认转换器。
要使用默认转换器,type请在属性声明中指定选项

@property({ type: Number })
count = 0;

使用自定义转换器

可以使用以下converter选项在属性声明中指定自定义属性转换器,converter可以是对象或函数。

额,这个没太理解,以后清楚了再补上。

启用属性反射

您可以配置一个属性,以便每当它发生变化时,它的值都会反映到其对应的属性中。这样保证当属性的值发生变化后,模板能够实时更新。默认值是false,该属性可以结合css和js

import {LitElement, html, css} from 'lit';
import {customElement, property} from 'lit/decorators.js';@customElement('my-element')
class MyElement extends LitElement {@property({type: Boolean, reflect: true})active: boolean = false;static styles = css`:host {display: inline-block;}:host([active]) {border: 1px solid red;}`;render() {return html`<span>Active: ${this.active}</span><button @click="${() => this.active = !this.active}">Toggle active</button>`;}
}

注:要注意与attribute属性的区别。attribute是父组件与子组件之间的响应,reflect是组件内部的响应

属性通常应被视为来自其所有者的元素的输入,而不是受元素本身的控制,因此应谨慎地将属性反映到属性。
就像vue中的props属性,一般都是通过emit来进行更新,而不是组件内部之间修改。

Lit(二):响应式属性相关推荐

  1. vue的computed如果没有出现在模板里面,当它依赖的响应式属性发生变化,getter会触发吗?

    有知乎网友问: vue的computed如果没有出现在模板里面,当它依赖的响应式属性发生变化,getter会触发吗? 先说答案,不会触发! 原因说穿了其实也很简单,因为你没有在模板中使用该计算属性,所 ...

  2. 网页设计与制作(项目二--响应式页面制作)

    政务网站制作要点 (一 )响应式的制作 1.排列方式:导航:一行变为两行:水平结构:变成纵向排列: 2.隐藏显示:在某个宽度的时候,特定的标签显示或者隐藏: 3.尺寸变化:典型--->轮播部分, ...

  3. Vue添加新的响应式属性

    vm.userProfile = Object.assign({}, vm.userProfile, {age: 27,favoriteColor: 'Vue Green' }) 转载于:https: ...

  4. vue新增属性是否会响应式更新?

    原文地址 在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的. 根据官 ...

  5. 从 JavaScript 属性描述器剖析 Vue.js 响应式视图

    学习每一门语言,一般都是从其数据结构开始,JavaScript也是一样,而JavaScript的数据结构中对象(Object)是最基础也是使用最频繁的概念和语法,坊间有言,JavaScript中,一切 ...

  6. 从JavaScript属性描述器剖析Vue.js响应式视图

    学习每一门语言,一般都是从其数据结构开始,JavaScript也是一样,而JavaScript的数据结构中对象(Object)是最基础也是使用最频繁的概念和语法,坊间有言,JavaScript中,一切 ...

  7. Vue数据绑定和响应式原理

    Vue数据绑定和响应式原理 当实例化一个Vue构造函数,会执行 Vue 的 init 方法,在 init 方法中主要执行三部分内容,一是初始化环境变量,而是处理 Vue 组件数据,三是解析挂载组件.以 ...

  8. 前端追梦人响应式网页设计

    一. 响应式元素及媒介 1.1 基于宽度百分比的图像缩放 <!DOCTYPE html> <html lang="en"> <head>< ...

  9. vue2的动画,混入Mixin,插件,指令,渲染函数,响应式,MVVM

    文章目录 过渡 & 动画 Transition 组件 基于 CSS 的过渡效果 CSS 过渡类名 class 为过渡效果命名 CSS 过渡 transition 实例1: 实例2: CSS 动 ...

最新文章

  1. python pexpect包的一些用法
  2. Visual Studio中的《C# 语言规范》
  3. Vue2.0配置mint-ui踩过的那些坑
  4. 崔巍 计算机考研怎么样,中国科学院大学研究生导师教师师资介绍简介-崔巍
  5. 流水线冒险及解决方法
  6. 机器学习笔记(三十二):集成学习、随机森林
  7. nltk 句子结构分析
  8. 命令查看(获取)本机IP地址
  9. java 建立tlsv1.2报错_Java 7的javax.net.ssl.SSLHandshakeException
  10. 星星之火OIer:TunaParetoUnija
  11. java sin 40_sin40度等于多少
  12. CI第一篇 Jenkins+github fir im 蒲公英pgyer com
  13. 英文字符和数字间隔突然变大
  14. Kibana 7.13.2 启动时报错 TaskManager is unable to start as there the Kibana UUID is invalid
  15. 【C++ 程序】 随机数
  16. 决战燕京城-08 武穆帅印
  17. 重庆邮电大学计算机2019湖北分数线,2019重庆邮电大学录取分数线多少?预测指南,重庆邮电大学分数线...
  18. 华为路由器:DHCP详解之DHCP中继实验(下)
  19. iOS 关于音频开发
  20. 推荐一个免费的论文查询,检索和查重网站

热门文章

  1. 研究者们公布图像识别软件方面的最新进展
  2. 大数据分析:结合 Hadoop或 Elastic MapReduce使用 Hunk
  3. MATLAB中安装YALMIP及CPLEX详细步骤
  4. linux弹珠游戏实现,弹珠游戏台玩具的详细制作图解
  5. 什么是redis?redis如何使用?
  6. Python多线程爬虫之二:爬取王者荣耀高清壁纸(多线程)
  7. MySQL SQL语句 生成32位 UUID
  8. C语言-思路与编程1
  9. 百药食坊-团队项目开始介绍
  10. Testlink解决大用例导入问题