软件

Obsidian插件Dataview —— JavaScript API 快速入门(八)

波比AI · 5月2日 · 2025年本文共7074个字 · 预计阅读24分钟7次已读

一、JavaScript操作

map

对于所有元素执行相同操作
[1,2,3].map(p=>p+1)可以得到[2,3,4],这个 p 代指操作时的每一个元素,p=>p+1本质上是个函数
再比如dv.pages(`"目标文件夹"`).map(p=>p.file.tags)得到目标文件夹下所有笔记的标签

filter
只保留返回为 true 的元素
dv.pages(`"目标文件夹"`).filter(p=>p.file.tags.includes('标签')只保留了标签中含标签的那些文件数据

JavaScript 其他教程:JavaScript 数组参考手册

二、快速入门

1. 显示Hello World

任意新建一个文档将下面的内容复制粘贴并运行。

greet:: Hello World!

- [ ] `= this.greet`

const page = dv.current()
const inlineGreet = page["greet"]

console.log(inlineGreet)
dv.header(2, inlineGreet)
dv.list([inlineGreet])
dv.el("span", `- [ ] ${inlineGreet}`)
dv.taskList(page.file.tasks)
dv.table(["问候"], [[inlineGreet]])

结果:
Obsidian插件Dataview —— JavaScript API 快速入门(八)

下面我们来分析一下上述示例:

首先,我们在文档中创建了一个内联属性 greet,然后创建了一个任务并通过内联 DQL 查询出 greet 属性并作为任务的名称。

接下来,我们通过调用 dv.current() 函数获取脚本当前正在执行的页面的页面信息,这相当于调用 dv.page("当前文档名") 函数。然后赋值给常量 page,紧接着读取了页面中的内联属性 greet 并赋值给常量 inlineGreet

第一个输出使用浏览器的控制台作为载体,通过调用 JavaScript 的 console.log() 函数来实现。如果你不知道怎么显示开发者工具,1)在 Windows 或 Linux 下可以使用快捷键 Ctrl+Shift+I;2)macOS 请使用Cmd+Opt+I。

接下来我们分别使用了 div.header(2, inlineGreet) 函数来将问候输出为二级标题;使用 dv.list([inlineGreet]) 将其输出为列表元素;使用 dv.el("span", ...) 函数来将其输出为任务(这里只是为了演示,通常我们是从文档中获取任务);使用 dv.taskList(pbobyaiage.file.tasks) 函数将页面中的任务查询出来;最后使用 dv.table(["问候"], [[inlineGreet]]) 函数将其输出为表格显示。

2. 读取属性

在 Obsidian 中我们可以在 Fronat matter 中定义 YAML 属性,也可以使用 Dataview 提供的内联属性在文体任意有效的位置定义属性。

下面是一段包含了各种属性的文档内容片段,我们将基于此进行讲解。

---
---
description: 测试描述
tags:
  - 标签1
  - 标签2
---

inlineProp1:: 测试
inline_test:: 下划线命名测试
InlineTest2:: 大写字母开头命名测试
Test Long Split Words:: 不规则变量名测试
**Bold Text**:: 加粗文本测试
这是内联字段 [inlineProp2:: 在文本内部]
我的名称不可见 (inlineProp3:: 我的变量名不可见)
- 在列表中定义标签 #标签3 和内联变量 [inlineProp4:: 在列表内]
- [ ] 在任务中定义标签 #标签4 和内联变量 [inlineProp5:: 在任务内]
外链:[[2022-01-06]]

我们使用dv.current()获取当前页面的数据,然后使用Object.keys()方法来遍历所有属性。

```dataviewjs
Object.keys(dv.current()).forEach(key => {
    console.log(key);
})

[!tip] dv.current()为dv.page(“文档路径”)的便捷方法

结果:
Obsidian插件Dataview —— JavaScript API 快速入门(八)

我们在命名变量时分别使用了驼峰式命名法、帕斯卡命名法、下划线命令法以及带有空格的属性名。从结果来看当前页面中定义的属性都在了,而且输出的数量远比我们定义的多,这是因为对于不规则的属性名,Dataview 内部进行了规范化。在 JavaScript 中属性通常以 对象.属性名 的方式来读取,同时也可以使用 对象['属性名'] 的方式,后者在通常用于动态计算属性名和特殊属性名读取。

```dataviewjs
const page = dv.current()
console.log(page['test-long-split-words']) // 不规则变量名测试
console.log(page['Test Long Split Words']) // 不规则变量名测试
console.log(page.inline_test) // 下划线命名测试
console.log(page.InlineTest2) // 大写字母开头命名测试
console.log(page.inlineprop1) // 测试

Hello World 字符串为属性变量名举例,建议使用 hello-world,其次是 helloWorld / HelloWorld / hello_world 这三者可自行选用,在不同的编程语言环境都有其适用的场景。

为什么选择以 hello-world 的方式一方面是 YAML 中定义属性支持,然后 DQL 内联查询支持(= hello-world), 再一个很重要的原因这是官方内部默认使用(比如将带空格的属性转化后的结果)。虽然方便了 DQL 的读取,但是使用 API 读取时,我们需要额外多输入中括号和引号(dv.current()['hello-world']),这种成本通常可以忽略不计。

我们在前面通过遍历 dv.current() 在控制台显示所有属性,接下来我们看一下如何获取指定区域的属性。

(1)YAML中的属性读取

Obsidian 中 tagscssclassesaliases 是内置的默认属性,如果要获取自定义或者第三方插件提供的属性,则需要提前知识有哪些属性名,因为所有属性全挂在了 dv.current() 返回的对象中。要获取 YAML 中的属性我们需要使用 file.frontmatter 属性:

```dataviewjs
console.log(dv.current().file.frontmatter) // {description: '测试描述', tags: Array(2), hello-world: '你好呀'}

(2)列表和任务中的属性读取

Dataview 将任务作为一种特殊的列表来处理,可以使用 page.file.lists 来获取当前页面中的列表数据,使用 page.file.tasks 来获取任务数据。在获取的列表数据同时包含了所有的任务,可通过基属性 task 是否为 true 来判断当前列表是否为任务项。

在列表中定义的属性会挂载在当前列表对象下,而标签则位于 tags 属性中,下面我们分别读取列表和任务中的标签和属性。

```dataviewjs
const lists = dv.current().file.lists;
const tasks = dv.current().file.tasks;

lists.forEach(list => {
    if (list.task) {
        console.log(list.tags) // ['#标签4']
        console.log(list.inlinbobyaieProp5) // 在任务内
    } else {
        console.log(list.tags) // ['#标签3']
        console.log(list.inlineProp4) %% 在列表内 %%
    }
})

tasks.forEach(task => {
    console.log(task.tags) %% ['#标签4'] %%
    console.log(task.inlineProp5) %% 在任务内 %%
})

(3)外链文档中的属性读取

在示例中我们使用外部链接引用了一篇笔记的地址,现在我们通过遍历page.file.outlinks属性来获取外链的元数据,然后将其path属性传入dv.page()中来获取页面的所有信息,接着使用file.tags来读取标签值。

```dataviewjs
const links = dv.current().file.outlinks
links.forEach(link => {
  console.log(dv.page(link.path).file.tags.array()) // ['#daily', '#journal']
})

3. 查询数据输出

在 DQL 中我们可以将查询的结果以表格、任务和日历的方式渲染到当前查询脚本所在的代码块位置。在 JavaScript 中没有对应的日历视图 API,只有 dv.list() 方法对应 LIST 语句,dv.taskList() 方法对应 TASK 语句以及 dv.table() 方法对应 TABLE 语句。虽然没有提供日历输出的方法,但是我们可以 API 中执行 DQL 查询语句变相实现。

(1)dv.list(element,text)方法

用于将结果渲染成列表,可接收 JavaScript 数组及 DataArray 类型。

```dataviewjs
const vanillaArray = [1, 2, [3, 4, 5, [6]]]
const dvArray = dv.array(vanillaArray)

dv.list(dvArray)
// dv.list(vanillaArray)

结果:
Obsidian插件Dataview —— JavaScript API 快速入门(八)

(2)dv.taskList(tasks,groupByFile)方法

用于将结果渲染成任务列表,数据源必须从 page.file.tasks 中获取,默认情况下如果数据从多个文档中获取,则会按文档名进行分组,当然也可以将第二个参数指定为 false 来禁用分组。

下面根据 #daily 标签查询任务来展示 groupByFile 参数的作用,查询语句为:dv.taskList(dv.pages("#daily").file.tasks), 结果如下:

Obsidian插件Dataview —— JavaScript API 快速入门(八)
从结果来看,在指定了第 2 个参数为false后,任务的顺序发生了变化,右则的截图中的任务可能来自于多个页面中。

(3)dv.table(headers,elements)方法

用于将结果渲染成表格数据,headers为一个数组,表示表头名称,而elements为表格数据,其值为数组,数组的每一项值同样为数组,用于表示表格的行数据。

```dataviewjs
const headers = ["姓名", "年龄", "性别", "爱好"]
const data = [    ["张三", 20, "男", "打篮球"],
    ["李四", 25, "女", "踢足球"],
    ["王五", 30, "男", "游泳"]
]
dv.table(headers, dv.array(data))

结果:
Obsidian插件Dataview —— JavaScript API 快速入门(八)

(4)日历输出

Dataview 并没有提供dv.calendar()方法来将查询的数据渲染为日历显示,但是我们可以通过dv.execute(source)来执行 DQL 查询,实现在 API 中渲染日历的功能。

```dataviewjs
const query = `
CALENDAR file.day
FROM "10 Example Data/dailys"
`
dv.execute(query)

结果:
Obsidian插件Dataview —— JavaScript API 快速入门(八)

4. HTML渲染

我们使用的表格、任务和列表在 Obsidian 中实际上都是最终用特定的 HTML 标签元素表示的,比如说表格为 <table></table> 标签,列表分为有符号列表 <ol></ol>,无符号列表 <ul></ul>,定义列表 <dl></dl>,像日历这种比较复杂的组件则是由多个 <div></div> 等元素嵌套而成的。

我们在 Obsidian 页面编辑时可以输入标题(1-6 号),正文内容,插入图片、代码等,这都可以使用 API 来动态设置。

  • dv.header(level, text) 用于渲染标题,其中 level 取值为 1-6
  • dv.paragraph(text) 用于渲染段落,即 <p></p> 标签。
  • dv.span(text) 用于渲染行内元素,即 <span></span> 标签。
  • dv.el(element, text) 用于渲染指定的 <element></element> 标签内容。
```dataviewjs
dv.header(2, "HTML渲染")
dv.paragraph("HTML段落元素渲染")
dv.span("行内容元素渲染")

const html = `
<div style="display: flex; align-items: flex-start;margin: 10px 0;">
    <div width="60" height="60">
        <img src="https://via.placeholder.com/60" style="border-radius:50%;" alt="Avatar">
    </div>
    <div style="margin-left: 10px;">
        <div style="font-size: 18px; font-weight: bold;">User name</div>
        <div style="font-size: 14px; color: #666;">User Description</div>
    </div>
</div>
`
dv.el("div", html)

结果:
Obsidian插件Dataview —— JavaScript API 快速入门(八)

5. Markdown原始内容输出

在 Obsidian 中我们可以通过标题栏右则的【更多选项】-> 【源码模式】来切换至 Markdown 原始内容视图。我们可以将任何 Markdown 文本内容渲染到页面中。

```dataviewjs
const raw = `
## 2号标题

这是文本内容。

- 列表
- [x] 任务

**文字加粗**
双链:[[2022-08-03]]

## 表格

| 姓名 | 年龄 | 性别 | 爱好  |
| -- | -- | -- | --- |
| 张三 | 20 | 男  | 打篮球 |
| 李四 | 25 | 女  | 踢足球 |
| 王五 | 30 | 男  | 游泳  |
`
dv.paragraph(raw)

结果:
Obsidian插件Dataview —— JavaScript API 快速入门(八)
上面我们是手动提供的 Markdown 原始数据进行演示的,如果我们相要获取查询页面中的列表、任务或者表格的原始数据,该如何作呢?Dataview 已经为我们准备好了开箱bobyai即用的方法:

  • dv.markdownTable(headers, values) 将结果输出为原始的 Markdown 表格表示形式,参数同 dv.table()
  • dv.markdownList(values) 将结果输出为原始的 Markdown 列表形式,即:- xxx
  • dv.markdownTaskList(tasks) 将结果输出为原始的 Markdown 任务形式,即:- [ ] xxx 或者 - [x] xxxx

将上述输出的 Markdown 原始数据使用 dv.paragraph() 挂载即可在页面中显示,当然也可以使用 dv.el() 选择其它的标签来作为容器。

6. 解析DQL查询语句

DQL(数据查询语言)为普通用户提供了一种便捷的查询方式,使用户无需编写复杂的代码即可满足大部分数据管理需求。这种方式不仅简化了操作过程,还提高了使用效率和友好性。

在有些场景下我们使用 DQL 查询语句会更加高效,可以将其结合在代码中发挥特定的作用。当然,也有些场景下我们必须用到,如前面提到的日历渲染。Dataview 为我们提供了以下几个方法来解析 DQL 查询语句或者 DataviewJS 语句。

  • dv.execute(source) 执行任意数据视图查询并将视图嵌入到当前页面中。
  • dv.executeJs(source) 执行任意 DataviewJS 查询并将视图嵌入到当前页面中。

使用方式:

```dataviewjs
dv.executeJs("dv.list([1, 2, 3, 4])") // 相当于 dv.list([1, 2, 3, 4])
dv.execute("TASK FROM #daily")

三、同系列

  • [[Obsidian插件Dataview —— 安装与设置(一)]]
  • [[Obsidian插件Dataview —— YAML简介(二)]]
  • [[Obsidian插件Dataview —— 认识属性(三)]]
  • [[Obsidian插件Dataview —— 数据查询(四)]]
  • [[Obsidian插件Dataview —— DQL查询语言详解(五)]]
  • [[Obsidian插件DataviewJS —— TypeScript速成(六)]]
  • [[Obsidian插件Dataview —— 深入理解DataviewJS(七)]]
  • [[Obsidian插件Dataview —— DataArray接口介绍(九)]]
  • [[Obsidian插件Dataview —— Dataviewjs JavaScript API 进阶用法(十)]]
  • [[Obsidian插件Dataview —— Luxon库介绍(十一)]]
  • [[Obsidian插件Dataview —— 实用案例讲解(初级篇)(十二)]]
  • [[Obsidian插件Dataview —— 实用案例讲解(中级篇)(十三)]]
  • [[Obsidian插件Dataview —— 实用案例讲解(高级篇)(十四)]]

四、参考

[Total: 0 Average: 0]
0 条回应

必须 注册 为本站用户, 登录 后才可以发表评论!