Vue初探

2017-08-21  本文已影响71人  放风筝的小小马

疑问点

Vue实例

语法:var vm = new Vue({});
说明:通过new Vue来实例化一个Vue对象,在实例化时,可以传入:数据、模板、挂载元素、方法、生命周期钩子等选项

**注意:

// 我们的数据对象
var data = { a: 1 }
// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
  data: data
})
// 对data中a的更改会体现在vm的data中
vm.a === data.a    // true
data.a = 2;        // 会导致 vm.a = 2
vm.a =3            // 会导致data.a = 3

vm.b = 4            // 这样是无效的,b并不能被添加到vm实例中
console.log(vm.b);   // 输出 undefined

// 如果知道b会在将来使用,那么必须在创建vm实例时添加,如下:
var vm = new Vue({
  data: {
      a: 1,
      b: ''         // 将b设置为空即可
  }
})

参考: Vue数据与方法

模板语法

插值

原始HTML

通过v-html可以将html代码插入到页面中
如:

<div id="app">
  <div v-html="rawhtml"></div>
  <div>{{msg}}</div>
</div>

var vm = new Vue({
   el: "#app",
   data: {
      rawhtml: "<a href='www.baidu.com'>baidu</a>",
      msg: "<a href='www.baidu.com'>baidu</a>"
   }
});

上面代码实际输出如下:

v-html演示

说明:通过v-html可以将rawhtml作为原始html替换掉当前的div,而使用{{}},则表示将msg作为文本插入到所在的位置
注意: 动态的渲染html是非常危险的,很可能导致XSS攻击

特性

mustache语法不能用在html的特性上,需要使用v-bind指令来绑定特性,如:
<div v-bind:class="dynamicClass"></div>
注意:dynamicClass是一个变量

缩写

实例属性

通过 $可以访问到实例属性

var data = {a: 1};
var app  = new Vue({
   el: "#app",
   data: data
});
app.$data === app.data    // true
app.$el === document.getElementById('app');

// 还有一些实例方法
app.$watch('a', function(newValue, oldValue) {
   // 该回调函数会在a被改变后调用
});

实例生命周期

var vm = new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
  }
})

created方法会在实例被创建时被调用

绑定数据到HTML的特性上

可以通过v-bind:来绑定变量到HTML的特性上
注意:一般来说,HTML的特性(如:id、class、style等,其实就是html的属性)接收的是字符串,而如果我们需要绑定一个变量到HTML的特性上,那么就需要使用v-bind:来操作

如:

// id 
<p v-bind:id="dynamicId"></p>  
// class
<p v-bind:class="dynamicClass"></p>

注意:上面代码中的dynamicIddynamicClass都是变量

使用JS的表达式

上面说的是绑定简单的属性到HTML的特性上,同时,还可以使用JS表达式来绑定数据
注意:使用表达式时,只支持单个表达式

// 表达式里面的id是变量
<div v-bind:id="'list-' + id"> </div>

类似于下面的语句不会生效

<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

指令

指令是带有v-前缀的特殊属性,指令属性的值预期是单个JS表达式v-for指令例外)
指令的职责:指令的值改变时,将其产生的连带影响,响应式的作用于DOM中
如:

// 如果seen表达式为真,则插入文本,为假则不插入
<p v-if="seen">现在你看到我了</p>

v-on指令
通过v-on指令可以来指定监听事件

// 监听click事件
<button v-on:click="dosome"></button> 

在监听的事件之后,还可以添加修饰词,例如有时候,我们需要阻止事件的默认行为

// 通过添加prevent修饰符, 提交事件不再重载页面 
<a v-on:click.prevent="doSomething">

缩写

v-bind缩写

<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>

v-on缩写

<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>

计算属性

计算属性其实就是在Vue实例的computed属性上定义的一些函数;
如:

computed: {
  now: function () {
    return Date.now()
  }
}

我们知道可以通过在Vue实例的 methods属性上定义函数,这两者产生的结果是相同的,那么这两者有什么区别呢?

注意:这里定义了一个计算属性now,并为其添加了函数,其本质就是将该函数用作now属性的getter函数,当访问now时,就调用该函数

计算属性computed和methods的区别
其最主要的区别在于:当它们进行计算求值时,如果依赖的数据没有发生改变,它们两者会进行不同的操作,computed是基于它的依赖进行缓存的,只有在依赖的数据发生改变时,才进行重新求值;而对于methods则不管依赖的数据有没有发生改变,只要调用方法,就会重新求值,进行渲染;

注意:计算属性只有getter,如果需要设置值,那么就要自己实现setter,如下:

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

观察watch

观察属性可以让我们对某些数据进行观测,当数据发生变化时,就执行相应的函数,这在异步获取数据时,很有用;
如下:

ar watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    // 如果 question 发生改变,这个函数就会运行
    question: function (newQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.getAnswer()
    }
  },
}

上面代码中,当question发生变化时,就会执行后面的函数

通过v-bind绑定class与style

绑定class

对象语法

// 表示如果isActive变量为true,则添加active类, 如果为false,则不添加
<p v-bind:class="{active: isActive}"></p>

当然,还可以添加多个:

<div class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>

// Vue实例中的数据
data: {
  isActive: true,
  hasError: false
}

利用计算属性(很实用的绑定class的方式)

<div :class="classObj">数据</div>

var wm = new Vue({
  data: {
     isActive: false,
     error: null
  },
  computed: {
     classObj: function() {
       // 返回的是一个对象
       // 该计算属性依赖于isActive和error,因此,当需要更改时,只要更改isActive和error即可
        return {  
           active: this.isActive && !this.error
           'text-danger': this. error && this.error.type === 'fatal'
        }
     }
  }
});

数组语法
还可以传递一个数组

<div v-bind:class="[activeClass, errorClass]">
// Vue实例中的data
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}
// 渲染后的结果
<div class="active text-danger"></div>

还可以使用三元运算符:

<div v-bind:class="[isActive ? activeClass : '', errorClass]">
//此例始终添加 errorClass ,但是只有在 isActive 是 true 时添加 activeClass

// 上面的语法可以改写为:
<div v-bind:class="[{ active: isActive }, errorClass]">

绑定内联样式

对象语法

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

// Vue实例中的data
data: {
  activeColor: 'red',
  fontSize: 30
}

通常,直接绑定一个样式对象更好

<div v-bind:style="styleObject"></div>

// Vue实例中的data
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

数组语法
v-bind:style 的数组语法可以将多个样式对象应用到一个元素上:

<div v-bind:style="[baseStyles, overridingStyles]">

条件渲染

v-show

带有v-show指令的元素一直在DOM树中,v-show只是简单的切换css的display: nonedisplay: block

注意v-show不支持<template>语法,同时,也不支持v-else

v-if VS v-show

v-if: 是真正的条件渲染,因为它会确保在切换的过程中条件块内的事件监听器和子组件适当的被销毁或重建
v-if也是惰性的:因为如果在初始化渲染时条件不成立, 那么就什么也不会做,直到条件为真时,才会被渲染到页面上
v-show则不同,不管条件是否为真都会被渲染到页面上,它只是简单的进行display的切换

v-if有更高的切换开销,而v-show则有更高的初始渲染开销,因此如果需要频繁的切换,则使用v-show更合适;如果在运行时不需要经常切换,则使用v-if更好

注意:v-ifv-show同时使用时,v-show的优先级更高

数组更新检测

变异方法

调用这些方法时,将会导致视图更新,方法如下:

变异方法会改变原始数组

非变异方法

非变异方法不会改变原数组,它们会返回一个新的数组

注意事项

对数组的更改

Vue不能检测以下变动的数组:

  1. 当利用索引值直接设置一个项时,如:vm.items[index] = newValue
  2. 当修改数组的长度时,如:vm.items.length = newLength
    当使用上面两种方式设置数组时,Vue将无法检测到,也就是说,如果在视图上不会进行相应的更新,如下:
<div id="app-11">
    <li v-for="(item, index) in objects">
       {{index}} - {{item.todo}}
    </li>
</div>

// js
var app11 = new Vue({
  el: "#app-11",
  data: {
    objects: [
      {todo: 'a'},
      {todo: 'b'},
      {todo: 'c'}
    ]
  }
});

// 如果如下更改,则不会生效
app11.objects[0] = {todo: 'change'}      // Vue将无法检测到该变动,视图不会更新

// 使用以下方式,则会生效
// 方法一:使用Vue.set
Vue.set(app11.objects, 0, {todo: 'change'});
// 方法二:使用splice
app11.objects.splice(0, 1, {todo: 'change'});

// 如果需要改变数组长度,则可以使用如下方式:
app11.objects.splice(5);    // 表示将长度修改为5

总结:

参考:列表渲染

对对象的更改

与数组类似,Vue也无法检测到对象属性的添加和删除

测试代码

上一篇下一篇

猜你喜欢

热点阅读