Vue学习笔记(一)

VueJs

数据驱动的组件,为现代化的 Web 界面而生

Vue的核心包括两部分:

  1. 响应的数据绑定:数据驱动视图,操作数据而非DOM,通过指令实现功能扩展;
  2. 组件系统:vue应用可以看成是一棵组件树,vue提供组件间的数据流,自定义事件系统,带特效的组件替换效果等;

Vue官网中专门有一篇文章讲Vue和其它框架的对比,个人觉得有点参考价值,从中可以窥见很多Vue重要的特性:

  1. 对比 angular
  • Vue专注视图层,更轻,性能占优;
  • Vue只允许父组件单向地传递数据给子组件;
  • Vue不执行脏检查,使用基于依赖追踪的观察系统,且使用异步队列更新;
  1. 对比 react
  • Vue建立在真实DOM结构上;
  • 轻量级的 DSL (指令系统),直观简洁的模板;
  • Vue也有自己的状态管理方案:Vuex;
  1. 其它特点
  • 与webpack无缝整合;
  • 支持ES6和CSS预处理器;
  • 另外在组件封装方面,下面一张图就可以很好地展现Vue的特性

vue-component

demo效果

JS代码

在实现这个demo时,Vue的语法显得相当简洁,整个应用的核心逻辑都包裹在一个传输给 Vue 构造函数作为形参的对象中,demo中主要包括:el,data,methods三部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
new Vue({
el: "#app", // 指定应用的根元素
data: { // 数据
newtodo: '',
todos: []
},
methods: { // 方法
addTodo: function() {
if (this.newtodo) {
this.todos.push({
text: this.newtodo
});
}
this.newtodo = '';
},
rmTodo: function(index) {
this.todos.splice(index, 1);
}
}
});

HTML结构

Vue的 HTML 结构和 angular 有类似的地方:两者都是用 HTML 的方式来扩充 HTML 功能,包括双向数据绑定,循环,事件绑定等

1
2
3
4
5
6
7
8
9
10
<div id="app">
<input type="text" v-model="newtodo">
<button v-on:click="addTodo">add</button>
<ul>
<li v-for="todo in todos">
{{todo.text}}
<button v-on:click="rmTodo($index)">&Chi;</button>
</li>
</ul>
</div>

构造函数

构件vue应用的第一步是调用Vue构造函数,传入的选项对象包括:数据,模板,挂载元素,方法,生命周期钩子等。

  • data:每个Vue实例都会代理 data 对象中所有的属性,“代理”属性其实就是建立引用,一方改变,另一方也会变化;
  • 以$开头的属性和方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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 (newVal, oldVal) {
    // 这个回调将在 `vm.a` 改变后调用
    })
  • 生命周期钩子:created,compiled,ready,destroyed等,生命周期的示意图:
    lifecycle

数据绑定语法

插值

  • 文本
    Vue的文本插值采用“mustache”双大括号语法,双大括号中的msg表示data中的msg属性字段,like this:

    1
    <span>msg: {{msg}}</span>
  • HTML
    要插入原始的HTML需要使用三大括号语法:

    1
    {{{ thisis_html }}}

将内容直接以html的方式插入存在风险,建议只对信任的内容做此操作。

  • HTML特性
    mustache标签也可用在HTML特性内:
    1
    <div class="item-{{class}}">

绑定表达式

放在mustache标签内的文本被称为绑定表达式,此表达式内可以由一个简单的JavaScript表达式和可选的过滤器组成。

  • 表达式:单个的表达式内不能有语句和流程控制语句,除此之外支持全功能的JavaScript表达式:

    1
    2
    3
    4
    5
    {{ number + 1 }}
    {{ ok ? 'YES' : 'NO' }}
    {{ message.split('').reverse().join('') }}
  • 过滤器:Vue会以“pipeline”的方式将数据传递给过滤器,语法用 | 表示,同时过滤器也支持传参:

    1
    {{ msg | filterA filterA_arg | filterB }}

    指令

    在Vue中,指令以前缀 v- 开头,其职责是:当其表达式的值改变时把某些特殊的行为应用到DOM上。指令的值称为绑定表达式。 指令的参数用冒号 : 隔开,比如 v-bind 指令用于响应的更新html特性,具体的attribute以冒号后参数的形式传递:

    1
    <a v-bind:href = "url"></a>

缩写

vue提供特定指令的缩写形式:

v-bind:缩写形式中可以直接去掉v-bind:

1
<a :href = "url"></a>;

v-on:用 @ 表示:

1
<a @click = "dosomething">;

计算属性

计算属性是一个function,在function中返回一个值,这个值可能会依赖于其它数据,定义在 computed 属性下:

1
2
3
4
5
6
7
8
9
10
11
12
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})

Class与Style绑定

Vue对Class与Style绑定做了专门优化,支持对象与数组语法。

  • Class
  1. 对象语法

    1
    <div v-bind:class="{'class-a': isA, 'class-b': isB'}"></div>
  2. 数组语法

    1
    <div v-bind:class="[classA, classB]">

数组语法与对象语法不同之处在于:对象语法中data里存的是属性值命名的字段,而数组中则直接是数组元素命名的字段。

  • Style
    style绑定语法与class类似,不再赘述,如
    1
    2
    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
    <div v-bind:style="[styleObjectA, styleObjectB]">

条件渲染

  • v-if:根据 v-if 绑定的值来控制是否渲染DOM,其可以配合 <template></template> 实现多个元素的渲染控制,此外还可搭配 v-show 语法:

    1
    2
    3
    4
    5
    <template v-if="isShow">
    <h1>header</h1>
    <p>this is content.</p>
    </template>
    <p v-else>sorry.</p>
  • v-show:根据绑定值控制DOM元素是否显示。使用方法与 v-if 类似。但不可使用 <template> 和 v-show。

两者的区别在于 v-if 是真实的条件渲染,而 v-show 只是控制 display 属性来展示/隐藏元素,DOM元素始终存在,具体使用哪个应该根据场景切换频率来定。

列表渲染

列表渲染使用 v-for ,使用方法如下:

1
2
3
4
5
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
1
2
3
4
5
6
7
8
9
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})

方法与事件处理

基本的使用方法:

1
<button v-on:click="say('hello!', $event)">Submit</button>

1
2
3
4
5
6
methods: {
say: function (msg, event) {
// 现在我们可以访问原生事件对象
event.preventDefault()
}
}

##事件修饰符

Vue为 event.preventDefault() 和 event.stopPropagation() 提供了两个修饰符:.prevent 和 .stop:

1
2
3
4
5
6
7
8
9
10
11
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat">
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

1.0.16 添加了两个额外的修饰符:

1
2
3
4
5
<!-- 添加事件侦听器时使用 capture 模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>

表单控件绑定

使用 v-model 指令在表单元素上创建双向数据绑定。

常见表单元素的绑定方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!--text-->
<input type="text" v-model="message">
<!--textarea-->
<textarea v-model="message"></textarea>
<!--checkbox-->
<input type="checkbox" id="checkbox" v-model="checked">
<!--radio:不需要通过name来绑定一组radio-->
<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>
<!--select:option有value选项时取value值,否则去innerText值-->
<select v-model="selected">
<option selected>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
<!--v-model配合v-bind使用以绑定value到动态属性上-->
<input type="checkbox" v-model="pick" v-bind:true-value="a" v-bind:false-value="b">
<span>Selected: {{ pick }}</span>
<!--使用lazy参数将事件从input变为change-->
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model="msg" lazy>
<!--将用户的输入转为 Number 类型(如果原值的转换结果为 NaN 则返回原值) -->
<input v-model="age" number>
<!--debounce 设置一个最小的延时,在每次敲击之后延时同步输入框的值与数据。-->
<!--注意 debounce 参数不会延迟 input 事件:它延迟“写入”底层数据。-->
<input v-model="msg" debounce="500">

谢谢你请我吃糖果