Vue笔记

作者: Jack_1332 | 来源:发表于2019-01-10 10:29 被阅读0次

阻止同步

使用 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>

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` 改变后调用
})

实例生命周期

lifecycle.png

实例生命周期 Demo

实例被创建

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

语法

  • 动态更新: {{ msg }}

    • 为增加属性 v-once 将插入不更新数据
    <span v-once>这个将不会改变: {{ msg }}</span>
    
  • HTML文本: 为标签增加属性 v-html="实例的vue数据"

    <p>Using v-html directive: <span v-html="rawHtml"></span></p>
    <!-- 注意,你不能使用 v-html 来复合局部模板 -->
    

    注意:你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。

  • 表达式

    • Vue.js 都提供了完全的 JavaScript 表达式支持。有个限制就是,每个绑定都只能包含单个表达式
    <!-- 这是语句,不是表达式 -->
    {{ var a = 1 }}
    
    <!-- 流控制也不会生效,请使用三元表达式 -->
    {{ if (ok) { return message } }}
    

    模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 Math 和 Date 。你不应该在模板表达式中试图访问用户定义的全局变量。

  • 修饰符

    修饰符 (Modifiers) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():

    <form v-on:submit.prevent="onSubmit">...</form>
    
  • 缩写

    v-bind:data 可以缩写为:data v-on:click可以缩写为@click

计算属性

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。

所以我们会用到计算属性

Example :

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})

提醒 : 计算属性的值总是基于被计算属性的值,即:当修改vm.message的值时 vm.reversedMessage 输出的值也会被修改

计算属性缓存 vs 方法

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是<b>计算属性是基于它们的依赖进行缓存的</b>。只在相关依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

总结 : 计算属性只有具有响应式依赖的变量(实例对象中的data)才会动态更新,当计算属性为以下Demo时不会被动态修改,methods则相反。所以计算属性更节省资源,如果你不希望有缓存,请用方法来替换计算属性。

computed: {
  now: function () {
    return Date.now()
    //Date.now不是一个响应式依赖对象
  }
}

侦听属性

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch,通常更好的做法是使用计算属性而不是命令式的 watch 回调。

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  //侦听属性  实时响应Vue实例的数据变动
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

计算属性的 setter

计算属性默认只有 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]
    }
  }
}
//现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。

绑定Html Class

我们可以传给元素一个v-bind:class的对象以动态的切换class,且v-bind:class与class可以共存

v-bind:class的格式是 {className1:boolean,className2:boolean,...}


DEMO - CSS Bind

<style>
  .base{
    /* StyleBody */
  }
  .active{
    /* StyleBody */
  }
  .model{
    /* StyleBody */
  }
</style>
<div class="base" v-bind:class="{ active: isActive , model: isModel}"></div>
new Vue({
  el:"#假定的父级元素ID",
  data:{
    isActive:true;
    isModel:false;
  }
})

最后DIV会被渲染为如下样式,且当改变Vue实例对象中的数据时该DIV样式会对应被改变

<div class="base active"></div>

注意:这种动态改变样式的方式还可以用计算属性实现,同样也是一个常用且强大的模式


另一种实现方式

DEMO

<div v-bind:class="classObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

绑定CSS - 数组语法

我们同样可以为v:bind-class传一个数组,以应用一个class列表

<div v-bind:class="[activeClass, errorClass]"></div>

对应Vue实例

data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

你也可以根据需要来修改数组的表达形式,其中可以包括三元表达式:

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

但是当多个元素都需要做判断的时候,这样的写法显得非常的繁琐,所以在数组语法中也可以使用对象语法:

<div v-bind:class="[{ active: isActive }, errorClass]"></div>

绑定内联样式

v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名:

DEMO

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

同样的,你可以直接绑定Style对象(Object)

DEMO

<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

Style样式也同样拥有数组语法

DEMO

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

注意:部分样式需要添加浏览器内核标识,如transform,Vue.js会自动侦听并添加

条件语句

<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
<!-- v-else 绑定元素需要紧跟在v-if元素或v-else-if后 -->

Tips:如果你想使用 v-if 隐藏多个元素,不妨尝试一下template 参考此处

v-else-if (version 2.1.0)

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

用 key 管理可复用的元素

Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>

那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,<input> 不会被替换掉——仅仅是替换了它的 placeholder。

但是,这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key 属性即可:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

这样,添加了key属性以后,vue会重新渲染元素而不是修改元素,但是请注意<label>元素仍然会被高效使用

v-show

另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:

<h1 v-show="ok">Hello!</h1>

不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。

注意,v-show 不支持 <template> 元素,也不支持 v-else。

v-if vs v-show

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

注意 :不推荐同时使用 v-if 和 v-for 详细信息


列表渲染

v-for

不做详细介绍
DEMO

<ul id="example-1">
<!-- 此处可以使用 of 代替 in -->
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

如果你需要使用到for循环中的索引值

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>

一个对象的 v-for

Vue同样可以使用v-for迭代对象

<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
    }
  }
})

这种方式只会输出对应Map中的Value,这可能不能满足复杂的业务需求

Out Key,Value

DEMO

<div v-for="(value, key) in object">
  {{ key }}: {{ value }}
</div>

同样的,括号里面可以提供第三个参数index

注意 : 除了value以外,key和index的名字是固定的

等同于v-if的默认高效原则,v-for会优先修改元素而不是重新渲染元素,如果你想让每个元素保持独立,同样可以绑定key属性 v-bind:key="key"

相关文章

网友评论

      本文标题:Vue笔记

      本文链接:https://www.haomeiwen.com/subject/syyorqtx.html