vue积累-3

146 阅读3分钟

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>