⭐⭐vue生命周期
vue指令
1.v-if
2.v-for
3.v-once 只渲染一次
4.v-html 插入html片段
5.v-on
6.v-bind
動態參數
<img v-bind:[imageUrl]="a" />
...
data(){
return{
imageUrl:'url'
}
}
v-on、v-bind縮寫
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
⭐⭐vue計算屬性與侦听器
計算屬性computed
computed與method 不同的是method沒有緩存機制,每次都會調用該函數,浪費性能,而computed卻有是基于它们的响应式依赖进行缓存的緩存機制,所以我們大量運算表達式可以用計算屬性進行計算。黨應用data數據發生變化時,computed會重新進行計算。
<template>
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</template>
<script>
export default{
name:'component1',
data(){
return {
message:'1111'
}
},
computed:{
reversedMessage(){
return this.message+'2222'
}
}
}
</script>
偵聽器watch
偵聽器監聽頁面響應式數據,數據變化會觸發偵聽器,可以利用偵聽器去觸發一些所需動作,需要一些開銷比較大的函數或異步函數,可以用偵聽器
<template>
<p>Original message: "{{ message }}"</p>
</template>
<script>
export default{
data(){
return{
message:'aa'
}
},
methods:{
a(){
this.message = 'sss';
},
b(){
for(let i = 0; i <= 10e8; i++){
console.log(i);
}
},
},
watch:{
message(newVal,oldVal){
if(newVal == 'ss'){
this.b()
}
}
}
}
</script>
⭐⭐class綁定
<template>
<div v-bind:class="{a:true,b:lc}">111</div>
</template>
<script>
export default{
data(){
return {
lc:false
}
}
}
</script>
上面渲染的結果
<div class="a">111</div>
<template>
<div :class="a">2222</div>
</template>
<script>
export default{
name:'try',
data(){
return {
a:{
b:true,
'vv':true
}
}
},
}
</script>
也可以利用計算屬性
<template>
<div :class="classObject">2222</div>
</template>
<script>
export default{
name:'try',
data(){
return {
a:{
b:true,
'vv':true
}
}
},
computed:{
classObject(){
return {
active-class: a.b
lll:a['vv']
}
}
}
}
</script>
數組語法
<template>
<div :class="[classObjec, errClass]"></div>
</template>
<script>
data(){
return{
classObject:'aaa',
errClass:'bbb'
}
}
</script>
渲染結果
<div class="aaa bbb"></div>
<div :class=[true?isAvtice]:'',errClass>222</div>
<script>
data(){
return{
isAvtice:'sss',
errClass:'lll'
}
}
</script>
渲染結果
<div class="sss lll"></div>
⭐⭐ style綁定
對象語法
<template>
<div :style="{color:styleColor, fontSize:styleFont}">222</div>
<div :style="styleObject">222</div>
</template>
<script>
export default{
data(){
return{
styleColor:'red',
styleFont:'12px',
styleObject:{
color:'red',
fontSize:'32px'
}
}
}
}
</script>
數組語法
<template>
<div :style="[styleColor,styleFont]">222</div>
</template>
<script>
export default{
name:'a',
data(){
styleColor:'green',
styleFont:'24px'
}
}
</script>
自動添加兼容前缀
vue會自動檢測css樣式是否需要加上前缀值
多重值
你可以添加重複前缀值,系統會自動幫你檢測那個合適,留下最適合值。
⭐⭐ 條件渲染 v-if 與 v-show
😋用key管理元素復用
vue會用已有元素進行復用這種高效的方法,但是這種通常元素上的值會保持不變。可以給元素加上key值來控制不復用。(注意label沒加也還是采用復用機制)
<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>
v-show
這個指令只是簡單對dom元素進行display設置css樣式切換而已,實際不想v-if是直接刪除頁面元素
v-if與v-for一起使用
v-for比v-if更先優先級,在項目中v-if不能跟v-for同用一個元素上,不然檢測出錯誤。
⭐⭐ v-for
v-for基礎
不要使用對象或者數組做為key,得使用字符串作爲key
v-for采用的是就地更新,如果數據項順序改變,vue不會移動dom元素順序,而是就地更新每個元素。(這種用index作爲key只適合少量dom元素)
如果大量dom元素需要渲染,需要采用唯一key值,以免造成大量dom元素反復渲染影響性能
數組更新檢測
能檢測更新數組方法
1.push
2.pop
3.shift
4.unshift
5.splice
6.sort
7.reverse
檢測不了數組方法
1.filter
2.concat
3.slice
這三個方法會生成返回新的數組,可用新的數組賦予舊的數組變量值,來彌補檢測不了數組方法以至於視圖無法更新的bug
** 显示过滤/排序后的结果** 這種情況可以采用計算屬性computed和方法method
computed
<template>
<div v-for="n of zjArr">{{n}}</div>
</template>
<script>
export default{
data(){
return{
l:[3,5,100,4,1,2]
}
},
computed:{
zjArr(){
return this.l.filter(number=>{
return number%2 === 0
})
}
}
}
</script>
method
<template>
<div v-for="n of zjArr(n)">{{n}}</div>
</template>
<script>
export default{
data(){
return{
l:[[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
}
},
method:{
zjArr(n){
return this.n.filter(number=>{
return number%2 === 0
})
}
}
}
</script>
⭐⭐ v-on
事件修飾符
.stop阻止单击事件继续传播.prevent阻止默認事件發生.capture.self觸發當前元素事件.once.passiveonce事件只觸發一次
鼠標修飾符
.left.right.middle
按鍵修飾符
⭐⭐ v-model
修飾符
.lazy將v-model默認的input事件換成change事件進行同步雙向綁定.number將輸入的字符串轉換數字類型trim將輸入的内容去除空格
<input v-model.lazy="msg">
<input v-model.number="age" type="number">
<input v-model.trim="msg">
⭐⭐ 组件基础
data必须是个函数
因为组件复用的原因,所以data必须是一个函数,每次复用都会返回一份独立拷贝的数据。如果是对象的话就会发生浅拷贝现象
在组件使用v-model
组件写法
单向数据流
父级直接改变子组件数据是被允许的,但是子组件直接改变父组件的数据是不被允许,如果直接改变父级组件数据,从而导致你的应用的数据流向难以理解。(会报错),可以利用emit进行改变。
Vue.component('my-component',
{ props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: { type: String, required: true },
// 带有默认值的数字
propD: { type: Number, default: 100 },
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: { validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
}
)
禁用 Attribute 继承
.async修饰符
⭐⭐插槽
具名插槽
组件内部可以利用及外部可以使用 来传进你所需的HTML片段,如果没有 没有name属性,外部可以用default或者直接写入传进组件内部
// 组件内部
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
<base-layout>
<template v-slot:header>
<h1>aaaaa</h1>
</template>
<template v-slot:default>
<p>bbbbbb</p>
<p>cccccc</p>
</template>
<template v-slot:footer>
<p>dddddd</p>
</template>
</base-layout>
⭐⭐ 作用域插槽
插槽里面的值往父级外面传
// 插槽内部
<span>
<slot name="aa" :user="user">
{{user.name}}
</slot>
</span>
// 父级 slotVal是所有插槽带出来所有值,可以解构你所需要的相应值
<case-div>
<template v-slot:aa="slotVal">
{{slotVal.user.name}}
</template>
</case-div>
具名插槽缩写
// 插槽内部
<span>
<slot name="aa" :user="user"> {{user.name}} </slot>
</span>
// 父级 slotVal是所有插槽带出来所有值,可以解构你所需要的相应值
<case-div>
<template #aa="slotVal"> {{slotVal.user.name}} </template>
</case-div>
⭐⭐ 混入
如果混入变量名函数名等与本身组件变量名函数名等相同,会以组件本身为主(选项合并)。
var myMixin = {
data(){
return {
a;'22'
}
},
method:{
b(){
console.log('0000')
}
}
}
var componet = vue.extend({
mixins:[myMixin]
})
⭐⭐ 自定义指令
全局注册自定义指令
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus',{
// 当被绑定元素插入dom时执行
inserted:function(el){
//聚焦元素
el.focus()
}
})
局部注册自定义指令
组件接受一个选项directive
directive:{
focus:{
inserted:function(el){
el.focus()
}
}
}
指令钩子
bind
只调用一次,第一次绑定到元素进行调用,在这里可以进行一次性的初始化配置。
inserted
被绑定元素插入父级元素调用(仅保证父元素存在,但不一定已插入文档中)
update
所在组件的vnode更新时调用,但是可能发生在其子vnode更新之前。
componentUpdate
指令所在组件vnode及其子vnode更新之后调用
unbind
只调用一次,指令与组件解绑之后调用
钩子参数
对象字面量
⭐⭐ 过滤器
过滤器可以用在双花括号和v-bind表达式
// 在双花括号中
{{message | capitalize}}
// 在v-bind中
<div v-bind:id="message | capitalize"></div>
过滤器还可以串联及传入参数
⭐⭐ 响应式原理
当你把一个普通对象传入vue中选项data中时,vue会利用object.defineProperty将这个对象里面的属性遍历变成getter和setter。
Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
检测变化的注意事项
由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。尽管如此我们还是有一些办法来回避这些限制并保证它们的响应性。
对象
vue无法侦察object添加/移除属性
// 可以使用this.$set(改变对象,'属性名','赋予新值')
this.$set(this.a,objectName,value)
数组
不能检测两种情况
- 当你利用索引直接设置一个数组项时,例如:
vm.items[indexOfItem] = newValue - 当你修改数组的长度时,例如:
vm.items.length = newLength
// this.$set(数组项,下标,赋予的新值)
this.$set(this.items, indexOfItem, newValue)
// 使用splice修改长度
this.items.splice(newLength)
⭐⭐ 异步更新队列 nextTick
当我们需要访问渲染过后的vue时,可以使用nextTick来访问
method:{
a(){
this.$nextTick(()=>{
// 访问dom渲染后的vue
......
})
}
}
因为nextTick 会返回一个promise对象,所以可以使用async/await语法完成相同事情
method:{
async a(){
await this.$nextTick(()=>{})
console.log('aaaaaaaaaa')
}
}
⭐⭐keep-alive
include :字符串、数组、或者正则表达式。只有名称匹配得组件会被缓存。
exclude :字符串、数组、或者正则表达式。符合名称匹配得组件不会被缓存。
max :数字。最多可以缓存多少组件实例。