1 最简单的案例
-
下载安装
- 原生实现打印
1.1 创建一个 Vue 实例
每个 Vue 应用都是通过用 Vue
函数创建一个新的 Vue 实例开始的:
var app = new Vue({ // 选项 })
当创建一个 Vue 实例时,你可以传入一个选项对象.
本教程主要描述的就是如何使用这些选项来创建你想要的行为.
一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成.
现在,你只需要明白所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象 (一些根实例特有的选项除外).
回到案例演示,若使用Vue.js 该如何实现打印呢?
无问题,正常打印
1.2 数据与方法
当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data
对象中能找到的所有的属性.
当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值.
// 我们的数据对象 var data = { a: 1 } // 该对象被加入到一个 Vue 实例中 var app = new Vue({ data: data }) // 获得这个实例上的属性 // 返回源数据中对应的字段 app.a == data.a // => true // 设置属性也会影响到原始数据 app.a = 2 data.a // => 2 // ……反之亦然 data.a = 3 app.a // => 3
当这些数据改变时,视图会进行重渲染.
值得注意的是只有当实例被创建时 data 中存在的属性才是响应式的。也就是说如果你添加一个新的属性
比如:
app.b = 'hi'
那么对 b 的改动将不会触发任何视图的更新。如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,那么你仅需要设置一些初始值.
比如:
data: { newTodoText: '', visitCount: 0, hideCompletedTodos: false, todos: [], error: null }
这里唯一的例外是使用 Object.freeze()
,这会阻止修改现有的属性,也意味着响应系统无法再追踪变化.
var obj = { foo: 'bar' } Object.freeze(obj) new Vue({ el: '#app', data: obj })
<div id="app"> <p>{{ foo }}</p> <!-- 这里的 `foo` 不会更新! --> <button v-on:click="foo = 'baz'">Change it</button> </div>
非接管区域内内容,并不感冒它.
而会原封不动输出.
最古老的直接操作DOM的定时操作.
Vue.js 版本代码,不需要再管 dom 操作,而是将注意力都放在对于数据的管理;
数据是什么,页面也就展示什么.
除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法.
它们都有前缀 $
,以便与用户定义的属性区分开来.
例如:
var data = { a: 1 } var vm = new Vue({ el: '#example', data: data }) vm.$data === data // => true vm.$el === document.getElementById('example') // => true // $watch 是一个实例方法 vm.$watch('a', function (newValue, oldValue) { // 这个回调将在 `vm.a` 改变后调用 })
3 开发TodoList(v-model、v-for、v-on)
3.1 列表渲染
3.1.1 用 v-for
把一个数组对应为一组元素
我们用 v-for
指令根据一组数组的选项列表进行渲染。v-for
指令需要使用 item in items
形式的特殊语法,items
是源数据数组并且 item
是数组元素迭代的别名。
<ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul>
var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
结果:
Foo Bar
在 v-for
块中,我们拥有对父作用域属性的完全访问权限.
v-for
还支持一个可选的第二个参数为当前项的索引.
<ul id="example-2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul>
var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
结果:
Parent - 0 - Foo Parent - 1 - Bar
你也可以用 of
替代 in
作为分隔符,因为它是最接近 JavaScript 迭代器的语法:
<div v-for="item of items"></div>
3.1.2 一个对象的 v-for
也可用 v-for
通过一个对象的属性来迭代.
在遍历对象时,是按 Object.keys()
的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下是一致的.
<ul id="v-for-object" class="demo"> <li v-for="value in object"> {{ value }} </li> </ul>
new Vue({ el: '#v-for-object', data: { object: { firstName: 'John', lastName: 'Doe', age: 30 } } })
- 也可以提供第二个的参数为键名:
<div v-for="(value, key) in object"> {{ key }}: {{ value }} </div>
- 第三个参数为索引
<div v-for="(value, key, index) in object"> {{ index }}. {{ key }}: {{ value }} </div>
在遍历对象时,是按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下是一致的。
3.1.3 key
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by="$index" 。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的唯一 id。这个特殊的属性相当于 Vue 1.x 的 track-by ,但它的工作方式类似于一个属性,所以你需要用 v-bind 来绑定动态值 (在这里使用简写):
<div v-for="item in items" :key="item.id"> <!-- 内容 --> </div>
建议尽可能在使用 v-for 时提供 key,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升.
因为它是 Vue 识别节点的一个通用机制,key 并不与 v-for 特别关联.
不要使用对象或数组之类的非原始类型值作为 v-for 的 key。用字符串或数类型的值取而代之.
3.2 回到案例
- 最初文件
- 最初效果
- Vue版实现同效
下面开始逐步实现 todolist功能
3.3 事件处理
3.3.1 监听事件
可以用 v-on
指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<div id="example-1"> <button v-on:click="counter += 1">Add 1</button> <p>The button above has been clicked {{ counter }} times.</p> </div>
var example1 = new Vue({ el: '#example-1', data: { counter: 0 } })
3.3.2 事件处理方法
然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on
指令中是不可行的,因此 v-on
还可以接收一个需要调用的方法名称.
<div id="example-2"> <!-- `greet` 是在下面定义的方法名 --> <button v-on:click="greet">Greet</button> </div>
var example2 = new Vue({ el: '#example-2', data: { name: 'Vue.js' }, // 在 `methods` 对象中定义方法 methods: { greet: function (event) { // `this` 在方法里指向当前 Vue 实例 alert('Hello ' + this.name + '!') // `event` 是原生 DOM 事件 if (event) { alert(event.target.tagName) } } } }) // 也可以用 JavaScript 直接调用方法 example2.greet() // => 'Hello Vue.js!'
3.4 回到案例
来试试绑定点击事件~
3.5 表单输入绑定
3.5.1 基础用法
可用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定.
它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理.
v-model
会忽略所有表单元素的 value
、checked
、selected
特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data
选项中声明初始值。
对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 v-model
不会在输入法组合文字过程中得到更新。如果你也想处理这个过程,请使用 input
事件。
- [文本]
<input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
- [多行文本]
<p style="white-space: pre-line;">{{ message }}</p> <br> <textarea v-model="message" placeholder="add multiple lines"></textarea>
|
Multiline message is:
在文本区域插值 (
<textarea></textarea>
) 并不会生效,应用v-model
来代替。
[复选框]
单个复选框,绑定到布尔值:
<input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label>
多个复选框,绑定到同一个数组:
<div id='example-3'> <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span> </div>
new Vue({ el: '#example-3', data: { checkedNames: [] } })
- [单选按钮]
<div id="example-4"> <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span> </div>
new Vue({ el: '#example-4', data: { picked: '' } })
[选择框]
单选时:
<div id="example-5"> <select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span> </div>
new Vue({ el: '...', data: { selected: '' } })
如果 v-model 表达式的初始值未能匹配任何选项, 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这样提供一个值为空的禁用选项。
3.6 回到案例:实现表单数据绑定
- 初始时值为空串.
- 产生输入后,值发生变化
- 在控制台改变值后,页面值随之改变!
- 如何使得点击事件可以发现输入框的值呢?
来来来,让我们快速进入下一个任务,要实现输入内容提交后打印,何解?
如此即可实现,是不是很简单呢~
可是发现好麻烦呀,每次提交,都需要手动请出前一次输入的内容,何解?
是不是很简单~
至此,todolist 功能实现完毕,无任何DOM操作,全程只操作数据!
Vue完美!
此为MVVM模式~
咱们下回分解MVVM哦~,不见不散!
参考
https://coding.imooc.com/class/203.html
https://cn.vuejs.org/v2/guide/events.html