vue基础总结

30 阅读1分钟

对于vue一些基本语法学习

生命周期钩子:

生命周期钩子的 this 上下文指向调用它的 Vue 实例

不要在选项 property 或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())

因为箭头函数并没有this,会利用其词法作用域一直向上查找

created: created钩子可以用来在一个实例被创建之后执行代码

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

 

 

一些语法指令:

v-once:执行一次性地插值,当数据改变时,插值处的内容不会更新

<span v-once>这个将不会改变: {{ msg }}</span>

 

v-html: 将内容渲染为html代码

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

<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

 

v-bind:绑定某个值

<button v-bind:disabled="isButtonDisabled">Button</button>
// 响应式的更新a href的url值
<a v-bind:href="url">...</a>

 

v-if: 进行条件渲染

<p v-if="seen">现在你看到我了</p>

 

v-on: 监听dom事件

<a v-on:click="doSomething">...</a>

 

可以用方括号括起来的 JavaScript 表达式作为一个指令的参数

<a v-bind:[attributeName]="url"> ... </a>
 //这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用

 

在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写

<!--
在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
除非在实例中有一个名为“someattr”的 property,否则代码不会工作。
-->
<a v-bind:[someAttr]="value"> ... </a>

 

缩写:v-bind和v-on支持缩写

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

<!-- 缩写 -->
<a :href="url">...</a>

<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>

------------------------------------------------------------

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

<!-- 缩写 -->
<a @click="doSomething">...</a>

<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>

 

 

在模板中使用javascript表达式,只能使用单个表达式

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>

 

computed: 对于复杂的运算使用计算属性

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

通过方法实现: 

<p>Reversed message: "{{ reversedMessage() }}"</p>

// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

computed:当依赖不发生变化时,不会再次计算,会直接使用缓存。而通过方法计算则会立即调用,每次进行计算。

如果希望有缓存,则使用computed,如果不希望有缓存则使用方法。

 

class与style绑定

 

<div v-bind:class="{ active: isActive }"></div>
// active这个类取决于isActive

// v-bind class 可以与普通类相共存
<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>

// isActive: true,hasError: false

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

绑定的类可以放在对象中或是计算属性中

<div v-bind:class="classObject"></div>
// 使用对象
data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}
// 使用计算属性
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
// 放到数组中
<div v-bind:class="[activeClass, errorClass]"></div>

// 利用三元表达式动态改变类名
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

 

添加样式 v-style

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

// 直接绑定一个样式对象
<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}
// 也可使用计算属性

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

 

vm实例的创建:

var vm = new Vue({
  data: {
   a:1
   }
})
// 其中data的数据只有在初始定义后,才会被监听到,vm.a
vm.b = 'b'
// 后面添加的b属性发生变化则不能被监听到

 

computed:计算属性 watch: 侦听属性

class与style绑定:

class绑定:

<div v-bind:class="{ active: isActive }"></div>
// 表示active这个类取决于isActive的true or false

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

<div v-bind:class="classObject"></div> //绑定一个对象

// 数组语法
<div v-bind:class="[activeClass, errorClass]"></div>
// 三元表达式
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
// 数组中夹杂对象格式
<div v-bind:class="[{ active: isActive }, errorClass]"></div>

style绑定:

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

 

条件渲染:

// v-if
// v-else-if
// v-else
// v-show v-show的元素还是在文档树中,只是切换display,v-show没有v-else
// 如果有频繁的切换则用v-show,v-show的dom一直存在在,所以它的显示切换效率更高
// v-for 比 v-if有更高的渲染效率

 

列表渲染:

<li v-for="item in items" :key="item.message">
    {{ item.message }}
  </li>

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

// 也可以遍历对象
<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>

// 监听数组更新
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
// 非变更方法 使用非变更方法时,可以用新数组进行替换
filter()、concat() 和 slice()

事件处理:

// v-on
<button v-on:click="greet">Greet</button>

 

表单元素:

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
// 双向绑定数据

 

组件基础:

Vue.component('button-counter', {
// 组件的data是一个函数形式,因为每个组件维护一个自己的data
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

// 子组件调用父组件的方法
<button v-on:click="$emit('enlarge-text')">
  Enlarge text
</button>

 

组件注册:

Vue.component('my-component-name', { /* ... */ })
// 通过这种方式注册的,引入方式为<my-component-name> (推荐)
Vue.component('MyComponentName', { /* ... */ })
// 通过这种方式注册的,引入方式为<my-component-name> 和 <MyComponentName>

 

prop:

// 数组类型
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
// 对象类型
props: {
  title: String,
  likes: Number
}
// 静态赋值
<blog-post v-bind:title="post.title"></blog-post>
// 动态赋值
<blog-post
  v-bind:title="post.title + ' by ' + post.author.name"
></blog-post>

 

自定义事件:

this.$emit('update:title', newTitle) // 子组件更新父组件的prop

 

插槽:

<navigation-link url="/profile">
  Your Profile
</navigation-link>

<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>  // 插槽 
</a>
// 此时插槽的内容会被替换为
<navigation-link url="/profile">
  <!-- 添加一个 Font Awesome 图标 -->
  <span class="fa fa-user"></span>
  Your Profile
</navigation-link>
// 父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

// 具名插槽
<template v-slot:header>
    <h1>Here might be a page title</h1>
</template>

// v-slot:header 可以被重写为 #header
<template #header>
    <h1>Here might be a page title</h1>
</template>

//注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确

 

动态组件和异步组件:

<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>
// keep-alive用于缓存

 

过渡动画:

<transition name="slide-fade">
    <p v-if="show">hello</p>
  </transition>

.slide-fade-enter-active {
  transition: all .3s ease;
}
.slide-fade-leave-active {
  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
  transform: translateX(10px);
  opacity: 0;
}

// 设置一些自定义钩子函数,自定义动画
<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <!-- ... -->
</transition>

 

mixins:混入

var Component = Vue.extend({
  mixins: [myMixin]
})

// 有冲突时以组件数据为主
// 混入和组件的钩子函数等都会被调用

 

路由:对于大多数单页面应用,都推荐使用官方支持的 vue-router 库

状态管理: vuex

过滤器: filter

filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。尽管如此我们还是有一些办法来回避这些限制并保证它们的响应性。

// 对象
必须在初始data中添加才是响应式的
Vue.set(vm.someObject, 'b', 2) 
this.$set(this.someObject,'b',2)
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 }) // 添加多个属性

// 数组
Vue.set(vm.items, indexOfItem, newValue) // 更新某个值
vm.$set(vm.items, indexOfItem, newValue)
vm.items.splice(newLength) // 更新length