created()与activated()
created():在创建vue对象时,当html渲染之前就触发;但是注意,全局vue.js不强制刷新或者重启时只创建一次,也就是说,created()只会触发一次;
activated():在vue对象存活的情况下,进入当前存在activated()函数的页面时,一进入页面就触发;可用于初始化页面数据等
使用<keep-alive>会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在activated阶段获取数据,承担原来created钩子中获取数据的任务。
被包含在 <keep-alive> 中创建的组件,会多出两个生命周期的钩子: activated 与 deactivated
activated:在组件被激活时调用,在组件第一次渲染时也会被调用,之后每次keep-alive激活时被调用。
deactivated:在组件被停用时调用。
注意:只有组件被 keep-alive 包裹时,这两个生命周期才会被调用,如果作为正常组件使用,是不会被调用,以及在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,这两个钩子依然不会被调用!另外在服务端渲染时此钩子也不会被调用的。
什么时候获取数据?
当引入keep-alive 的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。
我们知道 keep-alive 之后页面模板第一次初始化解析变成HTML片段后,再次进入就不在重新解析而是读取内存中的数据,即,只有当数据变化时,才使用VirtualDOM进行diff更新。有需要的话,页面进入的数据获取应该在activated中也放一份。数据下载完毕手动操作DOM的部分也应该在activated中执行才会生效。
所以,有需要的话,应该activated中留一份数据获取的代码,或者不要created部分,直接将created中的代码转移到activated中。
vue动态绑定class的最方式
第一种:(最简单的绑定)
1.绑定单个class
html部分:
<div :class="{'active':isActive}"></div> // js部分:判断是否绑定一个active
data() {
return {
isActive: true
};
}
结果渲染为:
<div class="active"></div>
2.若要绑定多个class,需要逗号隔开就行:(这里的activeTwo加不加引号都可以,也一样都能渲染,如下)
<div class="activeOne" v-bind:class="{ activeTwo: isActive, 'activeThree': hasError }"></div>
js部分:判断是否绑定对应class
data() {
return {
isActive: true,
hasError: true
};
}
结果渲染为:
<div class="activeOne activeTwo activeThree"></div>
第二种:(绑定的数据对象)
<div :class="classObject"></div>
data: {
classObject: {
active: true,
}
}
第三种:(绑定一个返回对象的计算属性)
<div :class="classObject"></div>
export default {
data() { return { isActive: true, }; },
computed: {
classObject: function () {
return {
active: this.isActive,
}
}
}
结果渲染为:
<div class="active"></div>
第四种:(单纯数组方法)
<div :class="[activeClass, errorClass]"></div>
data() {
return {
activeClass: "active",
errorClass: "disActive"
};
},
结果渲染为:
<div class="active disActive"></div>
第五种:(数组与三元运算符结合判断选择需要的class)
<div :class="[isActive?'active':'disActive']"></div>
data() {
return {
isActive: false,
}
},
结果渲染为:
<div class="disActive"></div>
file转base64 与 base64转file
// file转base64
getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = (error) => reject(error)
})
},
// base64转file
base64ToFile(data) {
// 将base64 的图片转换成file对象上传 atob将ascii码解析成binary数据
const binary = atob(data.split(',')[1])
const mime = data.split(',')[0].match(/:(.*?);/)[1]
const array = []
for (let i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i))
}
const fileData = new Blob([new Uint8Array(array)], {
type: mime
})
const file = new File([fileData], `${new Date().getTime()}.png`, { type: mime })
return file
},
this.$set
this.$set(obj, key, value)
<script>
export default {
data() {
return {
student: {
name: '张三',
}
}
},
methods: {
setMessage() {
this.$set(this.student, 'age', 15)
console.log(this.student)
}
}
}
</script>
slot-scope
slot-scope的出现却实现了父组件调用子组件内部的数据,子组件的数据通过slot-scope属性传递到了父组件
// 作用域插槽
Vue.component("todo-list",{
inheritAttrs:false,
props:{
todos:[Array,Object]
},
template:
`<ul>
<li v-for="todo in todos" :key="todo.id" style="display: block;" >
//这里的:data=“todo”就是讲子组件todo这个数据传给了父组件
<slot :data="todo">{{todo.text}}</slot>//todo.text是默认值,父组件会把它覆盖掉
</li>
</ul>
`
});
<!--使用作用域插槽,通过slot-scope实现-->
<todo-list :todos="todos">
<template slot-scope="slotProps">
<span v-if="slotProps.data.isTrue">√</span>
{{slotProps.data.text}}
</template>
</todo-list>