对于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