Vue 的小奇技

监听第三方组件的生命周期钩子

通过使用 @hook: 前缀监听生命周期中的钩子,并指定回调函数。
举个例子,如果你想要在第三方组件 v-runtime-template 渲染时做一些事情,那么你可以监听它的生命周期中的 updated 钩子:

<v-runtime-template @hook:updated="doSomething" :template="template" />

用Object.freeze 方法阻止vue的data中数据响应

比如我们请求的数据是一个很大的数据列表。如地图的标记点 markers 列表数据,这就是一个拥有很多对象的大型数组,我们不会对这些数据进行操作,其实可以理解成这是一个常量。

export default {
  data: () => ({
    users: {}
  }),
  async created() {
    const users = await axios.get("/api/users");
    this.users = Object.freeze(users);
  }
};

如果你确实有需要去修改请求得到的列表数据,那么你仍然可以通过创建一个新的数组来实现。

this.users = Object.freeze([...this.users, user]);

Vue2.6.0 中的新指令 v-slot

(1)作用域插槽
原方法:

<template>
    <List :items="items">
        <template slot-scope="{ filteredItems }">
            <p v-for="item in filteredItems" :key="item">{{ item }}p>
        template>
    List>
template>

然而,我们可以直接在组件标签上使用新指令v-slot,避免了额外的嵌套:
记住 v-slot指令只能用在组件或 template标签上,而不能使用在原生 html 标签上

<template>
    <List v-slot="{ filteredItems }" :items="items">
        <p v-for="item in filteredItems" :key="item">{{ item }}p>
    List>
template>

(2)v-slot指令也提供了一个绑定slotscope-slot 指令的方式,但是需要使用一个 : 来分割它们
原方法:

<template>
  <Promised :promise="usersPromise">
    <p slot="pending">Loading...p>

    <ul slot-scope="users">
      <li v-for="user in users">{{ user.name }}li>
    ul>

    <p slot="rejected" slot-scope="error">Error: {{ error.message }}p>
  Promised>
template>

v-slot指令重写如下:

<template>
    <Promised :promise="usersPromise">
        <template v-slot:pending>
            <p>Loading...p>
        template>

        <template v-slot="users">
            <ul>
                <li v-for="user in users">{{ user.name }}li>
            ul>
        template>

        <template v-slot:rejected="error">
            <p>Error: {{ error.message }}p>
        template>
    Promised>
template>

v-slot以符号 # 作为其指令的简写模式,v-slot指令默认应该简写为#default

<template>
    <Promised :promise="usersPromise">
        <template #pending>
            <p>Loading...p>
        template>

        <template #default="users">
            <ul>
                <li v-for="user in users">{{ user.name }}li>
            ul>
        template>

        <template #rejected="error">
            <p>Error: {{ error.message }}p>
        template>
    Promised>
template>

$attrs/$listeners使用

$attrs$listeners的主要应用是实现多层嵌套传递。

组件A与组件B通信一般都会使用组件B中转,即A传递给B,B再给C,但是如果A到C组件之间嵌套的组件过多,需要传递的事件和属性较多,会导致代码繁琐,代码维护困难。在vue2.4中,为了解决该需求,引入了$attrs$listeners,新增了inheritAttrs选项
具体使用查看:$attrs/$listeners的使用

provider/inject使用

在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量
不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据。

动态组件 & is 的用法

Vue 文档中关于动态组件部分的描述大概就是:使用保留的 元素配合动态绑定的 is 属性就可以在同一个挂载点切换不同的组件
这里面动态的关键在于 is 属性,而不在于 ,换句话说,就是随便你用什么标签,只要有 is 属性,它就算是动态组件, 当然你也可以静态地给 is 赋值一个字符串,不过这样它就只能表示某一个组件,失去了动态的意义了。
文档中有个render的列子

Vue.component('anchored-heading', {
  render: function (createElement) {
    return createElement(
      'h' + this.level,   // tag name
      this.$slots.default // array of children
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

其实就单单这个例子来说,也可以使用 is + template 的方法,比 render function 还要简洁直观:

<script type="text/x-template" id="anchored-heading-template">
  <component :is="'h' + level">
    <slot></slot>
  </component>
</script>

将组件插入body中

mounted放法中写

this.$nextTick(() => {
      const body = document.querySelector("body");
      if (body.append) {
        body.append(this.$el);
      } else {
        body.appendChild(this.$el);
      }
    });

修改scoped样式

// 普通样式中
  .a >>> .b { /* ... */ }
  
// sass 、less
.a{
  /deep/ .b{
    /* ... */
  }
}

定时器清除

一般我们都是在beforeDestroy()生命周期内清除定时器,但是下面这个方法更加简洁

const timer = setInterval(() =>{                    
    // 某些定时器操作                
}, 500);            
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once('hook:beforeDestroy', () => {            
    clearInterval(timer);                                    
})

类似于其他需要在当前页面使用,离开需要销毁的组件(例如一些第三方库的picker组件等等),都可以使用此方式来解决

你可能感兴趣的:(vue)