在vue3+typescript中使用选择集有些很有意思的地方。
d3的选择集通过 d3.select()
或者 de.selectAll()
实现。
在typescript中,它们都需要指定两个泛型以保证准确的类型识别。
function select<GElement extends d3.BaseType, OldDatum>(selector: string)
The first generic "GElement" refers to the type of element to be selected. The second generic "OldDatum" refers to the type of the datum, on the selected element. This is useful when re-selecting an element with a previously set, know datum type.
第一个泛型 GElement
继承自 d3.BaseType
,它是所有页面组件的基类,如果不能确定组件的类型,可以声明为 d3.BaseType
:
type BaseType = Element | EnterElement | Document | Window | null;
/*
Element is the most general base class from which all objects in a Document inherit. It only has methods and properties common to all kinds of elements. More specific classes inherit from Element.
EnterElement is an interface describing the element type of the Enter Selection group elements created when invoking selection.enter().
Document: any web page loaded in the browser and serves as an entry point into the web page's content, which is the DOM tree.
A window containing a DOM document; the document property points to the DOM document loaded in that window.
*/
特别的,对于选择或者添加的 SVG 标签,其组件类型为 SVGSVGElement
。
第二个泛型 OldDatum
指的是通过 .datum()
方法与所选组件绑定的数据的数据类型。如果通过 .data()
绑定的是数组的话,指的就是数组的元素的数据类型。
d3.select()
或者 d3.selectAll()
方法返回的是一个 d3.Selection
对象:
interface Selection<GElement extends BaseType, Datum, PElement extends BaseType, PDatum> { /**/ }
声明 d3.Selection
类型的数据需要提供四个泛型:
GElement
选择的组件的类型,在选择时指定Datum
选择的组件绑定的 Datum 类型PElement
d3选择链中父组件的类型PDatum
d3选择链中父组件的绑定的 Datum 类型
特别的,第一次使用d3选择器得到的组件其 PElement
泛型为 HTMLElement
,PDatum
泛型默认为 any
。
在 vue 组件中,使用 d3 选择当前组件并添加一个 svg:
const svg = d3.select(this.$el).append('svg')
如果不显示指定类型,则 svg
的数据类型为:
d3.Selection<SVGSVGElement, unknown, null, undefined>
可以指定选择器的泛型:
const svg = d3.select<SVGSVGElement, null>(this.$el).append("svg")
// svg: d3.Selection<SVGSVGElement, null, HTMLElement, any>
甚至指定选择集的泛型:
const svg: d3.Selection<SVGSVGElement, null, HTMLElement, null> = d3.select<SVGSVGElement, null>(this.$el).append("svg")
使用 .attr()
为选择集设置属性并不会影响选择集的组件类型。
在选择集上再次使用 select*
进行选择时,只需要提供一个泛型,这表示数据绑定的类型应该在第一次选择时指定:
select<SVGRectElement>(selector: string)
评论区