1、provide, inject

用于父组件向子组件、孙子组件传递数据。

​ provide, inject是成对出现的,provide在父组件使用,用于传递变量 ;inject在子、孙子组件使用,用于接收变量。

​ 相对于props,主要用于跨组件传递。

​ 传递的数据为非响应式数据。父组件中主动触发修改变量的操作,不会影响子组件展示。

1.1、使用

​ 父组件:

export default {
  components: {
    Othertext
  },
  provide() {
    return {
      currentPermission: this.currentPermission
    }
  },
  data() {
    return {
      currentPermission: 'editor',
    }
  }
}

​ 子组件:

export default {
  inject: {
      currentPermission: {
          default: () => ({})
      }
  },
}

1.2、注意

​ 1) provide 的值需要是一个对象或者是返回对象的函数,与data属性类型。

​ 2) inject的值需要是个数组,或者对象,与props属性类似。

​ 3) 传递的值为非响应式数据,由于父组件的主动行为引起属性发生变化时,子组件并不会响应。

​ 4) 一般vue项目的根页面为vue.app,同时也是所有页面的父页面。我们会根据项目要求存储些公共变量或者方法,如果需要在其他页面调用,可以将app.vue的当前实例传进去。

// app.vue
provide() {
  return {
    app: this
  }
}

...

// 其他页面
inject: {
  app: {
    default: () => ({})
  },
},

但是我们不建议这样使用。对于公共变量完全可以放到vuex中,公共方法可以进行提取调用。

2、watch两个属性 immediate 、deep

2.1、使用

watch: {
    info1: {
      handler(newVal, oldVal) {
        // todo
      },
      deep: true
    },
    
    info2: {
      handler(newVal, oldVal) {
        // todo
      },
      immediate: true
    }
  },

2.2 区别

deep: 深度监听。在vue2.x的版本中,响应式使用Object.defineProperty(),在组件实例创建时,只是对对象的存在属性做了响应式。但是在实际开发过程中我们可能会存在增加属性的情况。对于这种情况,我们可以使用$set() 或者 深拷贝的方式来解决。对于对象的监听,尤其是上述增加属性的情况,deep可以做到深层次的监听,即当属性发生变化时也会watch到当前对象发生了变化。

immediate: 主要是用于页面加载时需不需要触发watch函数。如果是true则触发,否则之后在属性或对象发生变化时才会触发。

2、slot

​ 插槽。当父组件调用子组件时,允许将子组件内容、逻辑以插槽的形式写在父组件中。插槽有默认插槽,即v-slot:default,也有具名插槽,下面demo主要是具名插槽使用。

3.1 使用

​ slot.vue

<template>
  <div class="container-wrapper">
      slots.vue
      <br/>
      <Testslot>
        // v-slot只能用在<template>;
        // v-slot: 可以使用 # 来简化, 接收对应子组件插槽传递的数据value直接在对应v-slot后加={value},value可以使用解构赋值
        // v-slot:name 其中name为具名插槽的name,即代码插入位置
          <template #header="{ user: { name } }">
            <h1>header</h1>
            <h2>{{ username }}</h2>
            <h3>{{ name }}</h3>
          </template>
          <template v-slot:default>
            <p>middle</p>
          </template>
          <template #footer>
            <h2>footer</h2>
          </template>
      </Testslot>
      <Vfor :arr="permission">
        // v-slot 接收的参数可以key
        <template #vfor="arritem">
          <span v-if="arritem.item != 1">{{ arritem }}</span>
        </template>
      </Vfor> 
  </div>
</template>
<script>
import Testslot from './_testslot';
import Vfor from './vfor';
export default {
  name: "",
  components: { Testslot, Vfor },
  data() {
    return {
        username: 'xiaoming',
        permission: ['1', '2', '3']
    };
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  //方法集合
  methods: {},
};
</script>

​ Testslot.vue

<template>
  <div class="container-wrapper2">
    <header>
      // 需要将子组件的值传递给父组件是,使用v-bind:prpperty = "data"
      // 具名插槽需要使用name,默认name="default"
      <slot name="header" v-bind:user="user"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

<script>
export default {
  name: "",
  props: [],
  components: {},
  data() {
    return {
      user: {
        name: '1'
      }
    };
  },
  computed: {},
  watch: {},
  created() {

  },
  mounted() {},
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  //方法集合
  methods: {},
};
</script>
<style lang='scss' scoped>
//@import url(); 引入公共css类
</style>

​ Vfor.vue

<template>
  <div class="container-wrapper">
      <ul>
          <li v-for="(item, index) in arr" :key="index">
            // 这里将item传递给父组件,这里v-bind:item可以写成:item, :后面的[item]可以修改,传递给父组件的时候,需要父组件自定义key.[item] 获取到数据
            // 后备显示内容为item
              <slot name="vfor" v-bind:item="item">{{ item }}</slot>
          </li>
      </ul>
  </div>
</template>

<script>
export default {
  name: "",
  props: {
      arr: {
          type: Array
      }
  },
  components: {},
  data() {
    return {};
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  //方法集合
  methods: {},
};
</script>
<style lang='scss' scoped>
//@import url(); 引入公共css类
</style>

3、delimiters

改变纯文本插入分隔符。

现在我们的插值形式就变成了${},代替了{{ }},在页面中就可以使用 ${xxxxx} 绑定对应的值。

4、inheritAttrs

如果你不希望组件的根元素继承特性,你可以在组件的选项中设置 inheritAttrs: false

当inheritAttrs: false ,使用组件时组件自定义的属性不会覆盖组件中属性名称的值,同时组件中未定义的属性也不会添加到组件中

当inheritAttrs:true,使用组件时组件自定义的属性会覆盖组件中属性名称的值,同时组件中未定义的属性会添加到组件中

但是在组件中插入style、class时,不管inheritAttrs是true还是false,都会叠加到一起。

arrt使vbind=arrt 使用:给组件添加v-bind=arrts。 当设置为true或者false时功能与上述一致。

<div id ="wxApp" class ="appclass"> 
        <blog-post title="标题" demo-one="未定义属性1" demo-tow="未定义属性2" class="cointer2" style="color:red"></blog-post>
 </div>
 
 Vue.component("blog-post",{
            props:{
                title:String,
            },
            inheritAttrs:false,
            template:`<div demo-one="hello" class="cointer" style="width:500px" >
                <h1>title:{{title}}</h1>
            </div>
            `
    })

当inheritAttrs为false时,

当inheritAttrs为true时

参考:https://blog.csdn.net/weixin_49868928/article/details/111935639