Vue-开发常用知识点

252 阅读3分钟

一、Watch(熟悉)

watch的作用可以监控一个值的变换,简单点说,就是实时监听某个数据的变化。

<template>
  <div class="home">
    <h3>{{obj.age}}</h3>
    <button @click="btnClick">按钮</button>
  </div>
</template>

<script>
export default {
  name: 'Home',
  data(){
    return {
      obj: {
        name: "Lucy",
        age: 13
      }
    }
  },
  methods: {
    btnClick(){
      this.obj.age = 33;
    }
  },
  watch: {
      // 通过点语法获取对象中的属性,然后转为字符串,即是对深度监听的优化
    "obj.age": { // 此时不是一个对象
      handler(val, oldVal){
        console.log(val.age, oldVal.age)		//  33   33
      },
      immediate: true  // 立即监听 (简单数据类型)  
      deep: true  // 深度监听(复杂数据类型)
    } 
  }
}
</script>

二、Mixins混入(熟悉)

mixins就是定义一部分公共的方法或者计算属性,然后混入到各个组件中使用,方便管理与统一修改。同一个生命周期,混入对象会比组件的先执行。

1、导出mixins

在src下创建 mixins/index.js,写入:

export const MixinsFn = {
    created() { 
        console.log("这是mixins触发的created")
    }
}

2、引用mixins

<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>
<script>
import { MixinsFn } from '@/mixins/index.js'
export default {
  created(){
    console.log("这是about触发的created")
  },
  mixins: [MixinsFn]
}
</script>

我们会发现,mixins中的createdabout中的created 优先执行。

三、ref与$refs(掌握)

vue中获取页面里的某个元素(标签或组件),可以给它绑定ref属性,有点类似于给它添加id名。

1、简单使用


<template>
 <div class="">
     <h3 ref="title">{{msg}}</h3>
     <button @click="btnclick">按钮</button>
 </div>
</template>
 
<script>
export default {
  data() {
    return {
      msg: "你好"
    };
  },
  methods: {
    btnclick() {
      console.log(this.$refs.title);		// 得到h3标签
      console.log(this.$refs.title.innerHTML);		// 得到h3标签的文本
    }
  }
};
</script>

2、子组件中的数据获取及方法调用

子组件:

<template>
 <div class="">
     <h4>{{num}}</h4>
 </div>
</template>
 
<script>
export default {
  data() {
    return {
      num: 100
    };
  },
  methods: {
      subFn(){
          console.log('子组件中的方法')
      }
  }
};
</script>

父组件:

<template>
 <div class="">
     <Sub ref="sub" />
     <button @click="btnclick">按钮</button>
 </div>
</template>
 
<script>
import Sub from '../components/Sub'
export default {
  methods: {
    btnclick() {
      console.log(this.$refs.sub.num);	// 100
      this.$refs.sub.subFn();						// '子组件中的方法'
    }
  },
  components: {
      Sub
  }
};
</script>

四、KeepAlive

<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。

KeepAlive用于处理组件缓存。有什么用呢?想象一个业务场景:

在Login页面填写完手机号,发现未注册,需要跳去Register页面完成注册,再返回Login页面填写密码,进行登录,此时如果在Login页面没有保存好手机号,那么跳回来时,用户又得重新输入手机号。为了解决这样的需求,我们需要借助keep-alive。

1、keep-alive结合component

首先,创建 a.vueb.vuec.vue 三个组件,内容大致如下:

<template>
  <li>a组件 <input type="text"></li>
</template>

在某个页面(如:about.vue)中引入:

<template>
  <div class="about">
    <button @click="mycom='acom'">a组件</button>
    <button @click="mycom='bcom'">b组件</button>
    <button @click="mycom='ccom'">c组件</button>
    <ul>
      <component :is="mycom"></component>
    </ul>
  </div>
</template>

<script>
import acom from '../components/a'
import bcom from '../components/b'
import ccom from '../components/c'

export default {
  data(){
    return {
      mycom: "acom"
    }
  },
  components: {
    acom, bcom, ccom
  }
}
</script>

到目前为止,我们可以切换组件,但是在切换时却无法缓存组件内容,因此我们给 component 组件套一个 keep-alive

// 这样我们在三个组件的 input 中输入的东西就会被缓存。
<keep-alive>
   <component :is="mycom"></component>
</keep-alive>

2、include与 exclude

如果我们想缓存指定的组件,可以使用include:

<keep-alive :include="['acom', 'bcom']">
   <component :is="mycom"></component>
</keep-alive>

如果我们想排出部分组件的缓存,可以使用exclude:

<keep-alive :exclude="['ccom']">
   <component :is="mycom"></component>
</keep-alive>

3、keep-alive生命周期

Keep-alive 生命周期包含:activeddeactivated

找到 a.vue,写入:

<script>
export default {
    created(){
        console.log('a组件的created')
    },
    mounted(){
        console.log('a组件的mounted')
    },
    activated(){
        console.log('actived: 进入当前组件时触发')
    },
    deactivated(){
        console.log('deactivated:离开当前组件时触发')
    }
}
</script>

我们可以观察到两个现象:

  • actived在created和mounted之后调用
  • deactivated在离开组件时会触发,无论第几次进入组件,actived都会触发,但created和mounted只会触发一次

五、NextTick

1、数据更新延迟的问题

当侦听到你的数据发生变化时, Vue将开启一个队列(该队列被Vue官方称为异步更新队列)。视图需要等队列中所有数据变化完成之后,再统一进行更新。

2、NextTick使用方法

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

NextTick有两种基本使用方法:

// 1、CallBack形式
this.$nextTick(()=>{
  console.log(this.$refs.title.innerHTML);
})

// 2、Promise形式
this.$nextTick().then(()=>{
  console.log(this.$refs.title.innerHTML);
})
// 案例
<template>
 <div class="">
     <h2 ref="title">{{num}}</h2>
     <button @click="btnClick">按钮</button>
 </div>
</template>
 
<script>
export default {
  data() {
    return {
      num: 1
    };
  },
  methods: {
    btnClick() {
      this.num++;
      console.log(this.$refs.title.innerHTML);		// 1
      // this.$nextTick(()=>{
      //   console.log(this.$refs.title.innerHTML);	// 2
      // })
      this.$nextTick().then(()=>{
        console.log(this.$refs.title.innerHTML);	// 2
      })
    }
  }
};
</script>

3、应用场景

1、如果要在created()钩子函数中进行的DOM操作,由于created()钩子函数中还未对DOM进行任何渲染,所以无法直接操作dom,需要通过$nextTick()来完成。

created () {
    this.$nextTick(()=>{
        this.$refs.ptag.innerText = "一个p标签"
    })
}

注:在created()钩子函数中进行的DOM操作,不使用$nextTick()会报错:

//  Error in created hook: "TypeError: Cannot set property 'innerText' of undefined"
created(){
    this.$refs.ptag.innerText = "一个p标签"
}

六、Transition

<transition> 元素作为单个元素/组件的过渡效果。<transition> 只会把过渡效果应用到其包裹的内容上,而不会额外渲染 DOM 元素,也不会出现在可被检查的组件层级中。

<button @click="flag = !flag">切换h3显示</button>
<transition name="fade">
  <h3 v-show="flag">你好,标题</h3>
</transition>

export default {
  data() {
    return {
     flag:false
    };
  },
<style lang="less" scoped>
 // 完整写法 需自己修改
.fade-enter, .fade-leave-to{
  opacity: 0;
}
.fade-enter-active, .fade-leave-active{
  transition: opacity 1s;
}
.fade-enter-to, .fade-leave{
  opacity: 1;
}
</style>

一个完整的transiton组件的class类,有6个,通过指定不同的class来添加样式来达到过渡的CSS效果。

  1. v-enter:定义进入过渡的开始状态。
  2. v-enter-active:定义进入过渡生效时的状态。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to: 定义进入过渡的结束状态。
  4. v-leave: 定义离开过渡的开始状态。
  5. v-leave-active:定义离开过渡生效时的状态。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to: 定义离开过渡的结束状态。

默认类名是以上6个,如果在transition标签中指定了name=’xxx’,那么6个类名将会变成xxx开头的,例如xxx-enter-active。

七、图片懒加载

1、安装

yarn add vue-lazyload
//  或者
npm i vue-lazyload -S

2、全局引入与配置

import VueLazyload from 'vue-lazyload'

// 配置项
Vue.use(VueLazyload, {
    preLoad: 1.3,
    // error: 'dist/error.png',
    // 这里注意,不能写相对路径,因此打包上线也需要修改这个地址
    loading: 'http://codesohigh.com/store-pc/img/img_loading.gif', 
    attempt: 1
})

3、设定loading大小

App.vue 中:

img[lazy="loading"] {
  display: block;
  width: 30% !important;
  height: 30% !important;
  margin: 0 auto;
}

4、:src --> v-lazy

<img v-lazy="item...">

八、设置title与favicon.ico

当我们完成项目后,想要在webpack修改 index.html 的title标签,可以在 vue.config.js 中:

module.exports = {
  chainWebpack: (config) => {
    config.plugin("html").tap((args) => {
      args[0].title = "百度";
      return args;
    });
  },
  publicPath: "./",
};

如果想改favicon.ico,可以在网上扒一个你想要的,然后替换 public 下的favicon.ico即可。

九、生命周期


//  beforeCreate(初始化界面前)
//  created(初始化界面后)
//	beforeMount(渲染dom前)
//	mounted(渲染dom后)
//	beforeUpdate(更新数据前)
//	updated(更新数据后)
//	beforeDestroy(卸载组件前)
//	destroyed(卸载组件后)

十、插槽(slot)

作用域插槽的多种写法

img

// 1、基本写法
<one-comp>
  <button slot="btn" slot-scope="scope">按钮{{scope.msg}}</button>
</one-comp>

// 2、基本写法之模板写法
<one-comp>
  <template slot="btn" slot-scope="scope">
    <button>按钮{{scope.msg}}</button>
  </template>
</one-comp>

// 3、指令写法
<one-comp v-slot:btn="scope">
  <button>按钮{{scope.msg}}</button>
</one-comp>

// 4、指令写法之模板写法
<one-comp>
  <template v-slot:btn="scope">
    <button>按钮{{scope.msg}}</button>
  </template>
</one-comp>