没时间学 Vue (6) —— 渲染(一):列表渲染 v-for

之前我们一直都在说 “绑定”,从现在开始会发散和穿插着说些其他的内容。

在最最基本的知识这块,我们还有这么一些要说的:

1)绑定:用得比较少的知识点,如: v-html、v-once 和日期时间类的 <input>;

2)渲染:在上一篇你可能也注意到了,选项要是一个个手写的话,还是有些费事的 —— 这就是渲染的一个例子;

3)事件处理:好不容易能接收用户数据了,但是要怎么处理 “按钮点击”、“选中某个项目” 这些事件呢?

基于 “功利的实用主义”,掐指一算,咱们还是先从 2)渲染开始讲起。

 

1、列表渲染?


咱们上一篇中有一个是模拟的选择收货地址的,大概是这样的。

其中的各个选项,是这么写的。

          <option value="beijing">北京市</option>
          <option value="tianjin">天津市</option>
          <option value="hebei">河北省</option>
          <option value="shanxi">山西省</option>

还好只写了 4 个,要是把全国 34 个省级辖区都写出来,真要写个半死。

更进一步,要是选择了某个省级辖区之后,还要在另一个选择框中把下辖的各个地市都列出来,又要怎么做呢?

我们需要一种动态的、可以批量生成多个、具有相同格式的组件的技术,否则上面显示地市的需求就不是半死就能解决的了、全死都不一定能搞定。

这种技术,就是接下来要说的 “列表渲染” —— 当然,渲染列表之外的元素也是 OK 的 —— 如果你理解它的本质了的话。

Vue 官方的说明文档在: https://cn.vuejs.org/v2/guide/list.html 。

 

我们先不看 Vue 里面是怎么做的,而是根据掌握的其他知识脑补一下 —— 尤其是如果你用过其他的 “模板渲染引擎” —— 比如说 JSP、Velocity 和 Thymeleaf 的话。

以生成全国 34 个省级辖区的 <option> 组件为例,JSP 的代码大概是这样的:

<select>
    <c:forEach var="province" items="${provinces}">
        <option value="${province.code}">${province.name}</option>
    </c:forEach>
</select>

而 Thymeleaf 的代码大概是这样的:

<select>
    <option th:each="province : ${provinces}" th:value="${province.code}" th:text="${province.name}">
    </option>
</select>

万一你从没用过任何的渲染引擎,那也可以想象一下如果要写成 Java 代码(其他的代码也行)是什么样的。

伪代码可能都长得跟下面差不多:

// 各个省级辖区的数组或者集合
Province[] provinces = [北京市, 天津市, 河北省, xxx, xxx];

// 遍历各个省级辖区,为每个辖区生成一个 <option> 组件
for (var province : provinces) {
   // 生成一个 <option> 组件, 格式为 <option value="xxx">yyy</option>
   OptionComponent option = createOptionComponent(province);

   // 插入到 <select> 组件的 <option> 集合中
   selectComponent.addOption(option);
}

Vue 中实现同样渲染功能的代码,大概是下面这样的。(注意 v-for 语句

        <select v-model="location">
          <option v-for="province in provinces" :value="province.code">{{province.name}}</option>
        </select>

带 <script> 的完整代码,大概是这样的:

    <div id="app">
      <div>位置:
        <select v-model="location">
          <option v-for="province in provinces" :value="province.code">{{province.name}}</option>
        </select>
      </div>
      <div>您选择了:{{location}}</div>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
        data: {
          location: "tianjin",
          provinces: [
            {code: "beijing", name: "北京市"},
            {code: "tianjin", name: "天津市"},
            {code: "hebei", name: "河北省"},
            {code: "shanxi", name: "山西省"}
          ]
        }
      });
    </script>

如果你对 data 中 provinces 的语法看得不是很明白,那么你可能还得速成和习惯一下 JavaScript 的数据类型,尤其是数组和对象 —— 同时,最好忘了之前其他开发语言中的 “对象”。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_Types

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects

 

2、v-for 与 JavaScript 的循环语句


你有没有发现,其实原理非常非常地简单,模板引擎的风格也都大同小异。

通过其中 “小异” 的地方,也可以围观、吐槽和研究一下 JavaScript 的循环语句。

JavaScript 中除了常规的 for ...、do ... while 和 while 这类循环语句 (https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Loops_and_iteration)之外,

还有 for ... in 和 for ... of 这类有些费解、但事实上在 Java、C# 等语言中也被广泛采用的循环语句。

 

1) for ... in 和 for ... of 表达式

for ... in  是个可以用来遍历各种类型的数据的、全能型循环语句。(参照:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in

跟之前我们提到的全能型的 <input> 组件一样,for ... in 也充满了各种各样、违背直觉的诡异问题 —— 尤其是遍历数组的时候。

比如说下面这段代码:

// 名字的数组
var names = ["张三", "李四", "王五"];

// 输出 names 中的每个名字
for (var name in names) {
  console.log(name);
};

看起来灰常简单,输出结果应该是 张三、李四、王五 。

可是呢,实际的输出结果是:0、1、2 —— 也就是各个元素的 index。

为了正确输出各个名字,咱们得这么写:(拜吐槽了,谁叫这个语法也是爷爷级的 ......)

// 名字的数组
var names = ["张三", "李四", "王五"];

// 输出 names 中的每个名字
for (var index in names) {
  console.log(names[index]);
};

为了避免被后浪的口水淹死,JavaScript 推出了 for ... of 这个补丁,用来按照比较符合直觉的方式处理各种可以迭代的类型 —— 比如数组、集合、字符串(中的各个字符)等。

(具体参照:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of

使用 for ... of 的遍历代码如下:

// 名字的数组
var names = ["张三", "李四", "王五"];

// 输出 names 中的每个名字
for (var name of names) {
  console.log(name);
};

虽然有了这个补丁,用 for ... in 来遍历数组的话仍然不会报错。所以,我们只能把这么重要的事情默念 3 遍:用 for ... of 来遍历数组,用 for ... of 来遍历数组,用 for ... of 来遍历数组。

 

等等!那 v-for 表达式里,是该用 in 还是 of 呢?

答案是两种都行。Vue 官网上是这么说的:

2)Array.forEach() 函数

除了上面那两个容易混淆的 for ... in 和 for ... of 之外,我们还可以使用数组的 forEach() 函数来遍历每一个元素。

// 名字的数组
var names = ["张三", "李四", "王五"];

// 输出 names 中的每个名字
names.forEach(function(name) {
  console.log(name);
});

或者,换成更时髦的 Lambda 表达式风格的写法,看起来会更加亲切一些。

// 名字的数组
var names = ["张三", "李四", "王五"];

// 输出 names 中的每个名字
names.forEach(name =>
  console.log(name)
);

Array.forEach() 函数比较神奇的地方是,用于处理每个元素的回调函数中可以接收多个参数。

// 名字的数组
var names = ["张三", "李四", "王五"];

// 输出 names 中的每个名字
names.forEach(function(element, index, array) {
  // element: 当前正在处理的元素
  // index: 当前正在处理的元素的 index。可选。
  // array: 当前正在遍历的数组。可选。
  console.log("第 " + index + " 个元素:" + element);
});

使用 Lambda 表达式的版本是这样的:

// 名字的数组
var names = ["张三", "李四", "王五"];

// 输出 names 中的每个名字
names.forEach((element, index, array) => {
  // element: 当前正在处理的元素
  // index: 当前正在处理的元素的 index。可选。
  // array: 当前正在遍历的数组。可选。
  console.log("第 " + index + " 个元素:" + element);
});

其中的第 2 个参数 index,也就是当前正在处理的元素的 index,经常会被我们用来显示各个元素的编号。

v-for 中同样也支持这个 index 参数:

 

3、v-for 的其他用法

Vue 官网上,还有对于 v-for 处理数组之外的其他用法的描述。

https://cn.vuejs.org/v2/guide/list.html

https://cn.vuejs.org/v2/api/#v-for

1)遍历对象(Object)

要理解这个用法,你得先理解万能的 for ... in 是如何遍历对象的。

估计是把对象滥用成了字典 (Map),所以才有了这种特有的、非 Iterable 的遍历。

用到 v-for 中也非常少见,所以要是有时间的话,你自己吧啦吧啦相关的资料吧 😀

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in

2)遍历指定区间

v-for 还提供了一个遍历指定区间内所有整数的便利方式。(不知道是不是受 Python 的启发 ......)

 

4、思考题

有了 v-for,我们就能做一些比较有意思的东东了。比如说这个:

你可能要速成一下 <table> 组件的用法。

https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/table

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值