Vue + Semantic-UI 实现简单漂亮的 Todo list

Vue 的轻量和灵巧让人惊叹,本文会介绍如何使用 Vue 的数据绑定功能,结合 Semantic-UI 漂亮的 UI,搭建一个在电脑和手机上都能出色显示的 Todo list。

实现功能

1. 用户可以在输入框里输入内容,然后按下确定键或者点击“+”按钮,将 todo 添加到 list 中

2. 用户可以点击 todo 条目边的红色按钮,删去该条目

3. 保证电脑和手机上的显示效果都很棒

UI 设计

1. 整体布局

使用 Semantic-UI 的 Grid 和 Container 来确定整个组件的宽度,并且保证在不同屏幕尺寸上的自适应。

<div class="ui doubling stackable grid container">   <div class="ten wide centered column">   <!-- 主体内容 -->   </div> </div>

其中 ui container 会根据不同的屏幕大小,来选择网页主体的宽度,比如在宽屏上,两边的空白会比较多,而在手机上,网页会占满整个屏幕。而 ui stackable doubling grid 会让整个网页的内容处于一个网格系统中,并且是充分自适应的,在小的屏幕上,会让整体的宽度增倍,以保证小屏幕的显示效果更加完美。

ten wide centered column,表示内容整体居中,并且占据 10/16 = 62.5% 的宽度,因为 Semantic-UI 默认是 16 栏(Bootstrap 是 12 栏)。

2. 标题和输入框

<div class="ui centered blue huge header">Todo list</div>

蓝色的大标题,并且居中。

然后是输入框和边上的“+”按钮:

<div class="ui fluid huge action green input">   <input type="text" placeholder="I'm gonna do ...">   <button class="ui icon button">     <i class="large plus icon"></i>   </button> </div>

右边实际上是一个 ➕图标,放在一个按钮中,后续可以用它来激发事件。

Vue + Semantic-UI 实现简单漂亮的 Todo list

3. todo 条目

左边显示文字,右边有一个小按钮,可以删除内容:

<div class="ui middle aligned divided animated big list">   <div class="item">     Vue.js     <div class="ui red mini right floated circular icon button">        <i class="remove icon"></i>     </div>   </div>   <div class="item">     Semantic-UI     <div class="ui red mini right floated circular icon button">        <i class="remove icon"></i>     </div>   </div> </div>

上面有两个 item,一个 item 的 div 表示一个条目。条目的内容,是纯文字,Vue.js, Semantic-UI,这是我们之后需要进行变量替代的地方。右边的是一个小的圆形按钮,里面放了一个 ❌ 图标,之后我们可以在这个按钮上绑定删除的功能。

Vue + Semantic-UI 实现简单漂亮的 Todo list

这样整体的 UI 就设计好了。

逻辑设计

1. 添加条目

这里用到 Vue 两个强大功能,一个是数据双向绑定,二是事件监听。

在之前的 UI 基础上,添加 v-model 进行双向绑定,以及 v-on 监听事件。

<div class="ui fluid huge action green input">   <input     v-model="newTodoText"     v-on:keyup.enter="addNewTodo"     type="text"     placeholder="I'm gonna do ..."   >   <button class="ui icon button" v-on:click="addNewTodo">     <i class="large plus icon"></i>   </button> </div>

这里我们特别注意两个变量,newTodoText 和 addNewTodo。

v-model=”newTodoText”,这一句是把输入框里的数据和 Vue 实例里的数据绑定在一起了,哪一边变化都会导致另一边的即时变化,非常直接了当。在 Vue 实例中定义该数据:

data: {   newTodoText: ‘’ }

v-on:keyup.enter=”addNewTodo”,这一句是说监听浏览器的事件,当发现用户按下 enter 键的时候,执行 addNewTodo 这个函数,

在右边的图标 button 上,同样绑定了这个函数,<button v-on:click=”addNewTodo”></button>,但监听的事件是 click。这两处的事件都可以用来添加条目。

methods: {   addNewTodo: function () {     this.todosList.push(this.newTodoText)     this.newTodoText = ''   } }

这是 Vue 实例中 addNewTodo 函数的具体定义。实现了两个功能,当用户按下确定或点击➕时,把用户输入的数据 newTodoText 添加(push)到 todosList 这个列表中,然后将 newTodoText 重新设置为空字符串。

todosList 是一个列表,同样在 Vue 实例的 data 中定义,可以添加一些默认值进去。

data: {   newTodoText: '',   todosList: [     'Vue.js',     'Semantic-UI',     'Operating System',     'Database',     'Django',     'Tensorflow'   ] }

2. 注册条目组件

设计好一个组件并注册后,就可以复用它。

Vue.component('todo-item-component', {   props: ['title'],   template: '<div class="item">{{ title }}               <div class="ui red mini right floated circular icon button"                 v-on:click="$emit('remove')">                 <i class="remove icon"></i>               </div>              </div>' });

可以看到这个 template 就是 UI 设计部分里的 item,只是加入了一个 {{ title }},这是 Vue.js 里的约定,表示这是一个绑定好的数据变量。如果你不喜欢 {{…}} 这种形式,你甚至可以自己修改成其它你比较习惯的符号,Vue.js 的作者真是深知程序员的各种癖好啊。。。

props 这个键表示组件里会接受哪些数据变量。

注意 v-on:click=”$emit(‘remove’) 这一句,这是一个自定义事件,表示在用户点击这个组件里的 button 元素时,激发名为 remove 的事件。父元素可以用 v-on 来监听这个事件,一旦它发生了,就会执行预设好的代码,详细情况见下一小节。关于什么是 Vue.js 中的自定义事件,可以参考我的一个答案:杜兵:Vue render函数 中data Object中对on和nativeOn的区别?

3. 删除条目

<div class="ui middle aligned divided animated big list">   <todo-item-component     v-for="(todoItem, index) in todosList"     v-bind:key="index"     v-bind:title="todoItem"     v-on:remove="todosList.splice(index, 1)"   ></todo-item-component> </div>

这里在一个 ui list 元素里嵌入了自定义的 todo-item-component 组件,这是一种很新颖的方式,自定义 HTML 元素,这种组件隔离的方式,使得构建 Single Page Application 变得十分易于理解和操作。

v-for 中的 (totoItem, index) in todosList 是一个遍历语句,比较特别的是加入了 index 这个参数,可以知道每个元素的索引位置。

v-on:remove=”todosList.splice(Inidex, 1)”,这是删除条目的核心逻辑。一旦父元素监听到自定义组件中激发的 remove 事件,立即执行双引号中的 JavaScript 语句,这里对 todosList 列表使用了 splice 操作,效果就是删掉当前的元素。splice 的用法如果不清楚,可参考 MDN 文档:Array.prototype.splice()

这样整个 UI 和 逻辑的部分就完成了,让我们重新梳理一下。

UI 设计: 布局 -> 标题和输入框 -> todo 条目

逻辑设计:添加条目 -> 注册条目组件 -> 删除条目

好了,大功告成,让我们看看在电脑和手机上使用和显示效果怎么样:

Vue + Semantic-UI 实现简单漂亮的 Todo listhttps://www.zhihu.com/video/874088594329972736

Happy coding!

参考资料

Vue.js 文档: https://vuejs.org

《Vue.js 权威指南》

发表评论

电子邮件地址不会被公开。 必填项已用*标注