Knowledge points such as Vue custom plug-ins (notes for personal use, test code based on vue 3)

Table of contents

1. provide, inject dependency injection

2.directive custom instruction

3.plugin custom plugin install, app.use()

4 .teleport Hang some elements of the component directly on other dom elements

5. Non-Props feature


1. provide, inject dependency injection

When the parent component wants to pass parameters to the descendant components, it is cumbersome to define the props transfer layer by layer

<script>
    const app = Vue.createApp({
      data() {
        return {
          count: 1
        }
      },
      template:`
        <div>
          <child :count="count"/>
        </div>
      `
    })
    
    app.component('child',{
      props:['count'],
      template:`
        <div>
          子组件{
   
   { count }}
          <child-child :count="count"/>
        </div>
      `
    })

    app.component('child-child',{
      props:['count'],
      template: '<div>子-子组件{
   
   { count }}</div>'
    })
    const vm = app.mount('#root')
  </script>
  • provide / inject 
  • The parent component uses provide to pass parameters
  • Subcomponents can be received using inject
  • But when the parent component changes the parameters, the value of the child component will not change accordingly, because provide is a one-time delivery, not a two-way binding, and there are solutions for subsequent learning
<script>
    const app = Vue.createApp({
      data() {
        return {
          count: 1
        }
      },
      provide() {
        return {
          count: this.count
        }
      },
      template:`
        <div>
          父组件 {
   
   { count }}
          <child />
          <button @click="count++">+1</button> // 后代组件的 count 不会跟着改变
        </div>
      `
    })

    app.component('child',{
      inject: ['count'],
      template:`
        <div>
          子组件{
   
   { count }}
          <child-child />
        </div>
      `
    })

    app.component('child-child',{
      inject: ['count'],
      template: '<div>子-子组件{
   
   { count }}</div>'
    })
    const vm = app.mount('#root')
  </script>

2.directive custom instruction

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://unpkg.com/vue@3"></script>
  <style>
    .header{
      position: absolute
    }
  </style>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  // 局部自定义指令
  const directives = {
    focus: {
      mounted(el) {
        el.focus()
      }
    }
  }

  const app = Vue.createApp({
    data() {
      return {
        distence: 100
      }
    },
    directives: directives, // 局部自定义指令
    template: `
      <div>
        <div class="header" v-pos:right="distence">
          <input v-focus/>
        </div>
      </div>
    `
  });
  // 全局指令
  /* app.directive('pos', {
    mounted(el, binding) {
      el.style[binding.arg] = binding.value + 'px'
    },
    updated(el, binding) {
      el.style[binding.arg] = binding.value + 'px'
    },
  }) */
  // 以上写法可简化为:
  app.directive('pos', (el, binding) => {
    el.style[binding.arg] = binding.value + 'px'
  })

  const vm = app.mount('#root');
</script>
</html>

3.plugin custom plugin install, app.use()

  • Encapsulate common performance
  • app.config.globalProperties extended global properties (vue 3)

 Can encapsulate provide, directive, mixin, etc.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>lesson 32</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  // plugin 插件, 也是把通用性的功能封装起来
  const myPlugin = {
    install(app, options) {
      app.provide('name', 'Dell Lee');
      app.directive('focus', {
        mounted(el) {
          el.focus();
        }
      })
      app.mixin({
        mounted(){
          console.log('mixin')
        }
      })
      app.config.globalProperties.$sayHello = 'hello world';
    }
  }

  const app = Vue.createApp({
    template: `
      <my-title />
    `
  });

  app.component('my-title', {
    inject: ['name'],
    mounted() {
      console.log(this.$sayHello);
    },
    template: `<div>{
   
   {name}}<input v-focus /></div>`
  })

  app.use(myPlugin, { name: 'dell'});

  const vm = app.mount('#root');
</script>
</html>

Data validation plug-in development example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>lesson 33</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  // 对数据做校验的插件
  const app = Vue.createApp({
    data() {
      return { name: 'dell', age: 23}
    },
    rules: {
      age: {
        validate: age => age > 25,
        message: 'too young, to simple'
      },
      name: {
        validate: name => name.length >= 4,
        message: 'name too short'
      }
    },
    template: `
      <div>name:{
   
   {name}}, age:{
   
   {age}}</div>
    `
  });

  const validatorPlugin = (app, options) => {  //或是: install(app, options) {}
    app.mixin({
      created() {
        for(let key in this.$options.rules) {
          const item = this.$options.rules[key];
          this.$watch(key, (value) => {
            const result = item.validate(value);
            if(!result) console.log(item.message);
          })
        }
      }
    })
  }

  app.use(validatorPlugin);
  const vm = app.mount('#root');
</script>
</html>

4 .teleport Hang some elements of the component directly on other dom elements

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://unpkg.com/vue@3"></script>
  <style>
    .area{
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 200px;
      height: 300px;
      background-color: green;
    }
    .mask{
      position: absolute;
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
      background-color: #000;
      opacity: 0.5;
    }
  </style>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return {
        show: false
      }
    },
    template: `
      <div>
        <div class="area">
          <button @click="show = !show">点击</button> 
          <teleport to="body">
            <div v-show="show" class="mask"></div>
          </teleport>
        </div>
      </div>
    `,
    created() {
      console.log('app created')
    },
    mounted() {
    },
    methods: {
      handleClick() {
        console.log('app click')
      }
    }
  });
   
  const vm = app.mount('#root')
</script>
</html>

5. Non-Props feature

  • If the parameters passed by the parent component are not received by the child component through props, then the parameters will be bound to the dom node of the child component
  • Do not inherit the parameters passed by the parent component  inheritAttrs: false
  • When to use the Non-Props feature? 

     Pass attributes such as style or class

  • When the child component has multiple root nodes, Non-Props is invalid, use $attrs to put all the attributes passed by the parent component on the current component

  • Get a certain attribute  $attrs. attribute value 

  • You can also use this.$attrs in other lifecycle functions or js methods

    ​​​​​

Do not inherit the parameters passed by the parent component  inheritAttrs: false 

  • When to use the Non-Props feature? 

        Pass attributes such as style or class

 When the child component has multiple root nodes, Non-Props is invalid, use $attrs to put all the attributes passed by the parent component on the current component

 ​​​​​​

Get a certain attribute  $attrs. attribute value 

You can also use this.$attrs  in other lifecycle functions or js methods

Guess you like

Origin blog.csdn.net/weixin_39763711/article/details/126528710