惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
J
Java Code Geeks
MongoDB | Blog
MongoDB | Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
美团技术团队
N
Netflix TechBlog - Medium
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
F
Fortinet All Blogs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MyScale Blog
MyScale Blog
aimingoo的专栏
aimingoo的专栏
Last Week in AI
Last Week in AI
The Cloudflare Blog
量子位
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
DataBreaches.Net
H
Hackread – Cybersecurity News, Data Breaches, AI and More

追梦人物的博客

小度智能设备接入 Home Assistant,支持小爱同学语音控制 - 追梦人物的博客 0x05:Merkle Tree & Patricia Trie 0x04:ECDSA - 以太坊设计与实现 LeetCode 105 从前序与中序遍历构造二叉树 迭代算法原理 + 完整证明 0x03:Address - 以太坊设计与实现 0x02:Secp256k1 - 以太坊设计与实现 0x00:专栏开篇 - 以太坊设计与实现 0x01:RLP 编码 - 以太坊设计与实现 Bellman-Ford 算法原理及其在 DeFi 套利中的应用 - 追梦人物的博客 迪杰斯特拉(Dijkstra)最短路径算法原理、实现与证明 - 追梦人物的博客 实战:CEX-DEX 稳定币套利监控程序开发 - 追梦人物的博客 CEX-DEX 稳定币套利模型 - 追梦人物的博客 Uniswap 手续费和协议费机制剖析 - 追梦人物的博客 Uniswap 流动性机制及相关数学原理分析 - 追梦人物的博客 uv 替代 pyenv + pipx + poetry 环境管理实践 Rust 项目从创建到发布 - 追梦人物的博客 VS Code 调试 Python - 追梦人物的博客 比特币跨市场套利的数学模型 - 追梦人物的博客 ERC-20 相关知识点总结 - 追梦人物的博客 Django 老项目如何从 SQLite 迁到 PostgreSQL 自动生成接口文档 - HelloDjango - django REST framework 教程 单元测试 - HelloDjango - django REST framework 教程 限制接口访问频率 - HelloDjango - django REST framework 教程 API 版本管理 - HelloDjango - django REST framework 教程 如何在 Windows 下搭建高效的 django 开发环境 拓展Python Markdown - 追梦人物的博客 加缓存为接口提速 - HelloDjango - django REST framework 教程 基于 drf-haystack 实现文章搜索接口 - HelloDjango 评论接口 - HelloDjango - django REST framework 教程 实现分类、标签、归档日期接口 - HelloDjango - django REST framework 教程
入门仪式:Hello Vue - Vue 2.x Todo 教程
2019-01-07 · via 追梦人物的博客

Hello Vue

既然是学习编程,那就遵循一下那个古老的传统仪式。

首先我们新建一个 todos.html 文件,用任何一个你喜欢的文本编辑器或者 IDE 打开(例如 vscode、sublime、记事本、notepad++、webstorm 等等),然后写上下面的代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Vue Todo Tutorial</title></head>
<body>
<div id="app">{{ message }}</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: function () {
            return {message: 'Hello Vue!'}
        }
    })
</script>
</html>

我们写了一个简单的 HTML 文件,使用 Script 标签引入了 Vue,版本是 2.5.16。然后我们写了几行 js 代码。在代码中我们 new(创建) 了一个 Vue 对象,并向这个对象传递了一些选项,例如告诉 Vue 挂载的元素(el,即elements 的缩写)是 idapp 的那个 div,并且在 data 中绑定了一个名为 message 的变量,其值为 'Hello Vue!',然后我们就可以在 HTML 文档中引用这个 message 。Vue 在后面帮我们做么很多神奇的事情,它把 {{ message }} 替换成了 Vue 对象中对应的值。

保存代码并用浏览器打开,可以看到浏览器显示了 “Hello Vue!”,你也可以尝试修改 message 的值,发现显示的内容会跟着变化。

表单绑定

再来看一个神奇的例子,我们把代码换成下面这样:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Vue Todo Tutorial</title></head>
<body>
<div id="app">
  <input type="text" v-model="value">
  <input type="button" value="发送">
  <div>value 的值是:{{ value }}</div>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: function () {
            return {value: ''}
        }
    })
</script>
</html>

这里要关注一下文档的 input 标签里 v-model="value" 这个东西。v-model 被称为 Vue 的指令,指令可以用来做很多事,比如用于 if 条件判断的 v-if,用于绑定值的 v-bind、用于绑定监听事件的 v-on 等等,这在以后会接触到。而这个 v-model 指令的作用是将 input 元素 value 属性的值和我们创建的 Vue 对象中 value 的值进行绑定,我们知道 input 有一个 value 属性,它的值会在浏览器显示(例如后面那个 button 按钮的发送),Vue 将这个值绑定后,在 input 中引起的 value 值变化就会实时反映到关联的 Vue 对象,所以会看到下方引用的 {{ value }} 也会跟着变化。

打开浏览器,然后在文本框做一些输入,试试效果!

加点方法

接下来我们在 Vue 对象中加点方法,还是上面的例子,只是在 Vue 对象中加了一个方法:

var app = new Vue({
        el: '#app',
        data: function () {
            return {value: ''}
        },
        // 这是新增的方法
        methods: {
            send: function () {
                alert('发送成功!');
                this.value = ''
            }
        }
    })

方法声明在 method 对象中,key 为方法名,值为对应的函数。我们想做的事情很简单,就是点击发送按钮后显示一个发送成功的消息,然后将 value 的值清空。

打开浏览器,发现怎么点都没有效果!因为 Vue 并不知道我们点击了按钮,为了让 Vue 监听到我们点击按钮的事件,需要在被点击的元素上绑定一个 click 事件,前面说过绑定事件用 v-on,因此在发送按钮上加上相应的代码:

<input type="button" value="发送" v-on:click="send"/>

在输入框输入一些文字,然后点击发送按钮试试。

计算属性

Vue 还可以根据绑定的数据做一些计算,然后我们就可以引用计算的结果。假设我们想实时统计输入的字数,我们可以在 Vue 对象里加上对 value 长度的计算值:

var app = new Vue({
        el: '#app',
        data: function () {
            return {value: ''}
        },
        methods: {
            // 省略...
        },
        // 这是新增的计算属性
        computed: {
            count: function () {
                return this.value.length
            }
        }
    })

计算属性申明到 computed 对象里,这个对象的键是计算的结果,值是计算函数,这里我们计算了 value 的长度。以后在 Vue 对象中就可以使用 this.count 引用计算结果,也可以在关联的模板中直接引用,和绑定的数据 value 的用法非常类似。比如我们在文档中引用这个 count:

<div id="app">
  <input type="text" v-model="value">
  <input type="button" value="发送" v-on:click="send"/>
  <div>value 的值是:{{ value }}</div>
  <!-- 引用 count -->
  <div>字数:{{ count }}</div>
</div>

打开浏览器看看效果。

加点样式

Vue 还可以动态地帮我们为元素绑定样式(class 属性),假设如果我们希望 input 中没有任何值输入,即 value 的值为空时,input 的边框为红色以提醒用户没有内容。首先我们写一个简单的样式(这个样式非常简单,不需要有 CSS 基础也看得懂),样式通常写到 head 标签里,用 style 包裹:

<head>
  <meta charset="UTF-8"><title>Vue Todo Tutorial</title>
  <style>
    .empty {
      border-color: red;
    }
  </style>
</head>

然后将这个 empty 用于 input 的 class 属性,浏览器就会渲染对应的样式:

<div id="app">
  <input type="text" class='empty' v-model="value">
  ...
</div>

当然现在无论 value 为何值边框都是红色的,因为 class 始终为 empty,现在让 Vue 来帮我们。前面说了,绑定值用 v-bind 指令,我们修改一下代码,为 input 的 class 绑定一个值:

<div id="app">
  <input type="text" 
         v-bind:class='{empty: !count}' 
         v-model="value">
  ...
</div>

Vue 会根据 empty 后的表达式 !count 的真假来判断 class 的值是否为 empty,如果为真(即 count = 0 的情况),则 class 的值为 empty,否则为空。

打开浏览器看看效果!

练习

我们通过这几个循序渐进的例子体会了 Vue 的部分核心特性,这些特性对我们开发 Todo 应用非常有帮助。当然这个例子还有一点小瑕疵,就由你来作为练习改进一下。

练习一:尽管我们在用户没有输入时用红色边框提醒用户内容为空,但是用户点击按钮后任然显示提交成功的通知,这是不合理的。合理的情况应该是弹出通知提示用户请输入内容。修改示例的代码,使其达到上述效果。(提示:修改 send 方法)

练习二:即使内容为空,输入框下方依然显示 value 的值是:,这看起来很奇怪。我们希望只有用户真正地输入了内容后,才提示 value 的值,请参阅 Vue 关于指令的官方文档,找到满足我们需求的指令,修改示例代码以达到上述效果。(提示:我们应该通过判断 value 是否有值来决定是否显示输入框下边的 div 元素。)

Vue 的指令文档:https://cn.vuejs.org/v2/guide/conditional.html

接下来正式开始我们的 Todo 应用的开发吧!

本节练习参考答案地址:https://www.zmrenwu.com/post/77/

-- EOF --