整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

12. 教你零基础搭建小程序:模板语法—数据绑定(1

12. 教你零基础搭建小程序:模板语法—数据绑定(1)


瑞巴迪,

从这章开始,我们要讲微信小程序的模板语法



模板语法的定义:

WXML(WeiXin Markup Language)是框架设计的?套标签语?,结合基础组件、事件系统,可以构建出页面的结构。

模板语法有以下四个种类,

1、数据绑定

2、运算

3、列表渲染

4、条件渲染

这是我们接下来要一一重点讲解的。


这一章,我们来初步学习模板语法中的数据绑定


大家可以点击下方链接,找到我们的教科书(微信官方文档)去学习一下基本定义,有一个大致的了解。

https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/data.html


数据绑定: WXML 中的动态数据均来自对应 Page 的 data



我们还是老方法 ,在实践中学习,在实操中认识。



1、在全局配置文件app.json 中新增demo03文件,便于我们示范以下具体操作。

代码如下:



2、打开 pages 文件夹--打开demo03 文件夹--打开demo03.wxml 文件,页面如下:



在demo03.wxml 文件中,可以看到如下代码:



代码中包含标签和普通文本两部分内容。


我们先对”text“标签做简单描述:

”text“相当于传统web中的span标签,是行内元素, 当页面中存在多个text 标签时,各标签也是不换行的。


比如:

我们在demo03.wxml 文件中输入以下代码:

<text>1</text>,
<text>2</text>


按下保存键,发现,左侧的屏幕中,1,2是在同一行的。

这就是说,当页面中存在多个text 标签时,各标签也是不换行的。



2.1 补充:对另一个标签——”view“标签进行描述。


”view“标签相当于以前web 中的 div 标签, 是块级元素, 当页面中有多个 view 标签时,是会换行的。


比如:

我们在demo03.wxml 文件中输入以下代码:

<view>1</view>,
<view>2</view>


按下保存键,发现,左侧的屏幕中,1,2是各占一行的。

这就是说,当页面中存在多个view 标签时,各标签是换行的。



3、数据绑定中,数据要定义在哪里?


我们打开 pages 文件夹--打开 demo03.js 文件, 文件中,一新建后就有内容存在。如下图所示。



我们来具体解读一下,demo03.js 文件中的内容


page: 这里指的是大型的配置方法



其中,page包括的data字段, 这里面都是关键字,是不能更改的哦,

而且,里面要放的都是一些初始化的数据,比如变量。

与data 同层级的有很多方法,基本都是生命周期函数,这在以后的章节中会介绍到的。



3.1 这里,给大家介绍一个小技巧:

我们把demo03.js 文件中的内容全部删除,使其文件呈现空白状态。

在demo03.js 文件中输入”page“,会有下拉提示框, 这里选择page , 就会重新出现删除前的文件内容。



在我们编辑demo03.js 文件时,如果出现了错误, 我们可以选择全部删除,然后再用这种方法重新输入page方法。


欧克,本章数据绑定部分的一部分知识,讲解到此,下一章我们继续讲解数据绑定的知识。



搜索并关注微信公众号:飞寝旺食

获取更多小程序运营干货、免费的开发教程、源代码等!

做小程序我们是认真的!

们可以使用数据绑定(Data Binding)来完成带可选项的列表,这些可选项来自某个导入的数据源,比如数据库、XML 文件或者脚本。


数据绑定

下面的控件是支持数据绑定的列表控件:

  • asp:RadioButtonList

  • asp:CheckBoxList

  • asp:DropDownList

  • asp:Listbox

以上每个控件的可选项通常是在一个或者多个 asp:ListItem 控件中定义,如下:

<html>

<body>

<form runat="server">

<asp:RadioButtonList id="countrylist" runat="server">

<asp:ListItem value="N" text="Norway" />

<asp:ListItem value="S" text="Sweden" />

<asp:ListItem value="F" text="France" />

<asp:ListItem value="I" text="Italy" />

</asp:RadioButtonList>

</form>

</body>

</html>

然而,我们可以使用某种独立的数据源进行数据绑定,比如数据库、XML 文件或者脚本,通过数据绑定来填充列表的可选项。

通过使用导入的数据源,数据从 HTML 中分离出来,并且对可选项的修改都是在独立的数据源中完成的。

在下面的三个章节中,我们将描述如何从脚本化的数据源中绑定数据。

信我或关注微信号:狮范课,回复:学习,获取免费学习资源包。

声明式数据绑定的情况

数据绑定最早是被 Angular、Backbone 和 Ember 等框架推广而流行开来的,现在则在某种程度上是编写视图的标准途径。它能让“视图作为数据的函数”,意味着每当某些数据发生变化时,相关视图将“自动”更新。

不需要冗长的 DOM 操作来保持数据和视图同步,只需更新数据,视图就会随之变化。这是一项杀手级功能,如今但凡理智的开发人员就会用它。所以很容易理解为什么开发人员会使用提供了数据绑定功能的框架,就算框架对于应用来说太大材小用也无所谓:既然框架打理好了一切,何必要费心费力处理那些麻烦的 DOM 操作呢?

但数据绑定并不是什么魔法,你用不着为了用它而动用整个框架。在 Web 组件里只需要几行代码就能轻松搞定数据绑定了,没什么特殊的。


如何实现

就像我上面说的那样,数据绑定并没有那么神奇。当基础数据发生变化时,你的视图不是凭空“神奇”地更新的。在框架深处,不为人知的某个角落里的设置代码负责在数据更改时调用并更新视图。

AngularJS 使用了所谓的“摘要循环”:这是一种粗暴的检查机制,不断检查哪些数据已更改,以便随时更新对应的视图。

React 面世时提供了另一种据称性能更好的解决方案,称为虚拟 DOM:它是一种 DOM 的 JavaScript 表示,只更新已更改的 DOM 部分。这对列表来说很合适——列表的少数项目发生变化时无需重新渲染整个列表,只需更新已更改的项目。

哪种工具最合适?



图源:https://xkcd.com/974/

这对于具有复杂 UI 的较大应用程序来说非常有用,但对于大多数应用程序来说实在有些杀鸡用牛刀了。编写一些监视数据的代码并在数据发生变化时更新相关视图并不是什么难事。问题是这些数据通常需要传递给也需要数据绑定的子组件,所以最后往往会有很多 DOM 操作。

你需要的是一种在数据被推送到子组件时触发子组件中相同的数据绑定操作的方法。只要父组件的数据发生更改并且某些数据绑定到子组件的视图,该子组件的视图也需要更新。

一种方法是利用所有组件的基类,因为 Web 组件是使用 JavaScript 类创建的,所以这是一个很好的选择。默认情况下 Web 组件扩展 HTMLElement,但我们也可以创建自己的基类来扩展 HTMLElement,如下所示:


export class CustomElement extends HTMLElement

然后我们创建的每个 Web 组件都扩展了这个 CustomElement 基类:


export class MyComponent extends CustomElement

如果你想直接查看代码,可以访问 Github 链接。

我们将 CustomElement 的内部 state 属性绑定到视图来实现数据绑定:


class CustomElement extends HTMLElement {
 constructor() {
 super();
 this.state={};
 }
}

我的第一个想法是将 this.state 实现为 Proxy,这样 state 对象的任何突变都将被自动拦截;但由于 Proxy 可能会影响性能,因此我决定实现一个 setter,它还能同时设置多个属性:


class CustomElement extends HTMLElement {
 ...
 setState(newState) {
 Object.entries(newState)
 .forEach(([key, value])=> {
 this.state[key]=this.isObject(this.state[key]) && 
 this.isObject(value) ? {...this.state[key], ...value} : value;
 });
 }
}

setState 方法遍历 newState 对象的所有条目,并将所有值设置为 this.state 上的对应属性,随后我们就应该使用这些值来更新视图。

通过标准 data 属性将值绑定到视图上,在本例中为 data-bind:


<p data-bind="title"></p>

这里的 textContent 绑定到负责管理视图的组件内的 this.state.title 的值上:


class DemoElement extends CustomElement {
 constructor() {
 super();
 const shadowRoot=this.attachShadow({mode: 'open'});
 shadowRoot.innerHTML=`
 <p data-bind="title"></p>
 `;
 }
}
const element=document.querySelector('demo-element');
element.setState({title: 'Hello World'});
// the paragraph will now contain the text "Hello World"

这种绑定可以达到任意深度,所以下面这种情况也能做到:


<p data-bind="user.address.city"></p>
element.setState({
 user: {
 address: {
 city: 'Amsterdam'
 }
 }
});
---> <p>Amsterdam</p>

还可以将数据绑定到 Web 组件的特定属性。在此示例中,数据绑定到的 title 属性上:


<parent-element>
 <demo-element data-bind="title:name"></demo-element>
</parent-element>
parentElement.setState({name: 'foo'}); //demoElement.title==='foo'

视图的更新实际是在 CustomElement 中的 updateBindings 方法中实现的。通过 setState 方法更新 state 时,它会解析更新的属性以查找绑定到这些属性的 HTML 元素。

例如下面这样:


element.setState({
 user: {
 address: {
 city: 'Amsterdam'
 }
 }
});

更新 Web 组件内的 this.state.user.address.city,并将数据对象中的键转换为 user.address.city,然后使用它来查找这个数据绑定的元素:


const elements=this.shadowRoot.querySelectorAll('[data-bind$="user.address.city"]');

这将查找所有的 data-bind 属性以 user.address.city 结尾的元素(注意 data-bind 结尾的),因此它将找到 data-bind=“user.address.city”,但也可以找到 data-bind=“ name:user.address.city“,其中数据专门绑定到 name 属性。

每当数据绑定到元素的特定属性(如 data-bind=“name:user.address.city”)时,组件将检查该元素是否也是扩展 CustomElement 的 Web 组件;如果是,则通过它的 setState 方法更新该属性。这样,数据绑定就能一直传播到所有子组件上。

如果绑定数据的元素是常规 HTML 元素,那么将简单地更新其 textContent。在这两种情况下,只需几行代码即可有效实现 DOM 的更新。

列表该怎么处理?

像虚拟 DOM 这样的解决方案真正的用武之地是渲染列表。例如只更改列表的一部分时,虚拟 DOM 将仅更新已更改的部分,而不是重新渲染整个列表。

其机制是在第一次渲染列表时创建 DOM 节点,然后在列表更改时只更新这些现有节点(textContent、属性等)。复用已经创建的节点比重新渲染整个列表重建所有节点的开销小得多,因此对于非常大的列表来说这种方法效率更高。

但如果你的列表平均只有 25 个项目时,你可能会想知道重新渲染整个列表能比虚拟 DOM 的方法慢多少。当你渲染 250 个项目时可能会变得很慢,但理智的开发人员在这种情况下就应该分页了。

我不是说大家就应该抛弃虚拟 DOM,因为它的确是很棒的技术。如果遇到真正需要虚拟 DOM 的情况,自然一定要使用它。我只是希望大家遇到比较轻量的问题时先思考一下能不能找到一个比较轻量的解决方案,而不是上来就动用重量级的杀手锏。

customElement 演示的 Github 仓库包含一个 Web 组件,它在 li 标签内渲染任何设置为其 items 属性的字符串数组。只要将 items 设置为新数组它就会重新渲染整个列表,但是复用现有的 li 标记也很简单。

结论

答案很清楚了,只需几行代码即可对 Web 组件进行声明式数据绑定。我觉得自己已经清楚地证明了数据绑定很容易实现,并且你不需要动用整个框架也能使用它。

上面提到的 Github 仓库中的代码不是 React 或 Vue.js 等框架的替代品,本来也没这个意思。框架提供的并不只有数据绑定,本文和涉及的代码是为了证明你不一定需要一个框架来实现声明式数据绑定。

除了数据绑定之外,customElement 还提供了一些方便的方法来选择元素以及显示和隐藏元素。

来源网络,侵权联系删除

私信我或关注微信号:狮范课,回复:学习,获取免费学习资源包。