Vue3 – Advanced syntax supplement

1 Custom directives in Vue

2 Vue built-in component Teleport

3 Vue built-in component Suspense

4 How to install plug-ins in Vue

5 Use of rendering functions in Vue

6 Syntax for writing jsx in Vue

Custom directives in Vue

There are two binding methods for custom instructions, one is local and the other is global.

Instructions can be used by converting part of the js code into instructions. The js function code can be divided into settings and used directly on a separate page, or it can be extracted into hooks function calls. The function of the following js code is to get the focus of the input box immediately when entering this page.

Method to create directly on the page:

<template>
  <div class="app">
    <!-- <input type="text" ref="inputRef"> -->
    <input type="text" v-focus>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
function useInput() {
  const inputRef = ref()

  onMounted(() => {
    inputRef.value?.focus()
  })
}

</script>

<style scoped>

</style>

Extracted into hooks: placed in ./hooks/useInput

import { ref, onMounted } from 'vue';

export default function useInput() {
  const inputRef = ref()

  onMounted(() => {
    inputRef.value?.focus()
  })

  return { inputRef }
}
<template>
  <div class="app">
    <input type="text" ref="inputRef"> 
  </div>
</template>

<script setup>
 1.方式一: 定义ref绑定到input中, 调用focus
 import useInput from "./hooks/useInput"
 const { inputRef } = useInput()
</script>

<style scoped>

</style>

Use instructions to implement the above functions:

Local instructions: can be written with the options api method of vue2, or the setup method of vue3

When writing commands in the setup, you must use v+capital letters to be commands

<template>
  <div class="app">
    <!-- <input type="text" ref="inputRef"> -->
    <input type="text" v-focus>
  </div>
</template>

 <script>
  // 1.方式一:
  export default {
    directives: {
      focus: {
        // 生命周期的函数(自定义指令)
        mounted(el) {
          // console.log("v-focus应用的元素被挂载了", el)
          el?.focus()
        }
      }
    }
  }

</script> 

<script setup>


 2.方式二: 自定义指令(局部指令)这里一定要用v+大写字母才能是指令
 const vFocus = {
  // 生命周期的函数(自定义指令)
   mounted(el) {
     // console.log("v-focus应用的元素被挂载了", el)
     el?.focus()
   }
 }

</script>

<style scoped>

</style>

The use of global instructions is written in main.js:

import { createApp } from 'vue'

// 自定义指令的方式一:
// const app = createApp(App)

// 全局指令1:
  app.directive("focus", {
    // 生命周期的函数(自定义指令)
    mounted(el) {
      // console.log("v-focus应用的元素被挂载了", el)
      el?.focus()
    }
  })
createApp(App).mount("#app")

Note: Write directly in main. js will let main. js has become very large, we can extract it and make it into a directive folder 2:

focus.js code:

export default function directiveFocus(app) {
  app.directive("focus", {
    // 生命周期的函数(自定义指令)
    mounted(el) {
      // console.log("v-focus应用的元素被挂载了", el)
      el?.focus()
    }
  })
}

main.js and index.js code:

1、

index.js:

 

2、

index.js:

 

 

Custom directives have their own life cycle for each phase.

directive modifiers

<template>
  <div class="app">
    <button @click="counter++">+1</button>

    <!-- 1.参数-修饰符-值 -->
    <!-- <h2 v-why:kobe.abc.cba="message">哈哈哈哈</h2> -->

    <!-- 2.价格拼接单位符号 -->
    <h2 v-unit> {
    
    { 111 }} </h2>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const counter = ref(0)

const message = '你好啊, 李银河'

const vWhy = {
  mounted(el, bindings) {
    console.log(bindings)
    el.textContent = bindings.value
  }
}

</script>

<style scoped>

</style>

Custom instruction small case 1

Want to add corresponding symbols to numbers

Create unit.js in the directive folder and enter

This command can enter a default value or directly set the value entered by the user. When the user enters, add a colon and value directly after the command. For example: v-unit="parameters"

 Add instructions to the entry file of the instruction folder

 main.js

where you want to use the directive

 

 

Custom instruction small case 2

Convert timestamp to MM-MM-DD etc. format

<template>
  <div class="app">
    <button @click="counter++">+1</button>

    <!-- 1.参数-修饰符-值 -->
    <!-- <h2 v-why:kobe.abc.cba="message">哈哈哈哈</h2> -->

    <!-- 2.价格拼接单位符号 -->
    <h2 v-unit> {
    
    { 111 }} </h2>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const counter = ref(0)

const message = '你好啊, 李银河'

const vWhy = {
  mounted(el, bindings) {
    console.log(bindings)
    el.textContent = bindings.value
  }
}

</script>

<style scoped>

</style>

ftime.js:

import dayjs from 'dayjs'

export default function directiveFtime(app) {
  app.directive("ftime", {
    mounted(el, bindings) {
      // 1.获取时间, 并且转化成毫秒
      let timestamp = el.textContent
      if (timestamp.length === 10) {
        timestamp = timestamp * 1000
      }

      timestamp = Number(timestamp)

      // 2.获取传入的参数
      let value = bindings.value
      if (!value) {
        value = "YYYY-MM-DD HH:mm:ss"
      }

      // 3.对时间进行格式化
      const formatTime = dayjs(timestamp).format(value)
      el.textContent = formatTime
    }
  })
}

There are also some issues regarding administrator permissions after logging in. Ordinary administrators can operate few functions and can use instructions to judge and limit the displayed results.

Vue built-in component Teleport

Transfer the component you wrote (it can also be a normal tag) to another location. If it is actually mounted, the page will change.

Probably mainly used in js control.

<template>
  <div class="app">
    <div class="hello">
      <p class="content">
        <!-- <teleport to="body">
          <hello-world/>
        </teleport> -->
        <teleport to="#abc">
          <hello-world/>
        </teleport>
      </p>
    </div>

    <div class="content">
      <teleport to="#abc">
        <h2>哈哈哈哈哈</h2>
      </teleport>
    </div>
  </div>
</template>

<script setup>

import HelloWorld from "./HelloWorld.vue"

</script>

<style scoped>

</style>

Vue built-in component Suspense

Turn the component into an asynchronous one. When the page loads, the page needs to load this component. Before it is loaded, the default prompt can be displayed. After loading, the prompt is cleared and replaced with the specified component.

<template>
  <div class="app">
    <suspense>
      <template #default>
        <async-home/>
      </template>
      <template #fallback>
        <h2>Loading</h2>
      </template>
    </suspense>
  </div>
</template>

<script setup>
import { defineAsyncComponent } from 'vue';

const AsyncHome = defineAsyncComponent(() => import("./AsyncHome.vue"))

</script>

<style scoped>

</style>

How to install plug-ins in Vue

One of the functions is to use it in the app

You can convert the originally separated app into the function into a chain call,
similar to createApp(App).use(directives).mount("#app")

import { createApp } from 'vue'
import directives from "./01_自定义指令/directives/index"
import router from "./router"


// 自定义指令的方式一:
// const app = createApp(App)
// // useDirectives(app)
// directives(app)
// app.mount('#app')

// 自定义指令的方式二:使用插件
createApp(App).use(directives).use(router).mount("#app")

The use of rendering functions in Vue

The template template will execute the render function to convert the label into a virtual DOM.

The h function is the createVNode function:

 

We can delete the template and use render to render by ourselves. The render function needs to return a createVNode. At this time, we can use the h function instead. The usage method is the same.

Basic usage: 

_render function counter implementation:

<script>
  import { h } from 'vue'
  import Home from "./Home.vue"

  export default {
    data() {
      return {
        counter: 0
      }
    },

    render() {
      return h("div", { className: "app" }, [
        h("h2", null, `当前计数: ${this.counter}`),
        h("button", { onClick: this.increment }, "+1"),
        h("button", { onClick: this.decrement }, "-1"),
        h(Home)
      ])
    },
    methods: {
      increment() {
        this.counter++
      },
      decrement() {
        this.counter--
      }
    }
  }
</script>

<style scoped>

</style>

render rendering component:

<script>
  import { h } from 'vue'
  import Home from "./Home.vue"

  export default {
   

    render() {
      return h("div", { className: "app" }, [
        h(Home)
      ])
    }
   
  }
</script>

<style scoped>

</style>

Use vue3 to implement the above functions:

// 这个template里面的render标签是setup语法糖的要求的写法。setup函数不用写这个。
<template>
  <render/>
  <h2 class="">内容</h2>
</template>

<!-- <script>
  import { h, ref } from 'vue'
  import Home from "./Home.vue"

  export default {
    setup() {
      const counter = ref(0)

      const increment = () => {
        counter.value++
      }
      const decrement = () => {
        counter.value--
      }

      return () => h("div", { className: "app" }, [
        h("h2", null, `当前计数: ${counter.value}`),
        h("button", { onClick: increment }, "+1"),
        h("button", { onClick: decrement }, "-1"),
        h(Home)
      ])
    }
  }
</script> -->

<script setup>

import { ref, h } from 'vue';
import Home from './Home.vue'

const counter = ref(0)

const increment = () => {
  counter.value++
}
const decrement = () => {
  counter.value--
}

const render = () => h("div", { className: "app" }, [
  h("h2", null, `当前计数: ${counter.value}`),
  h("button", { onClick: increment }, "+1"),
  h("button", { onClick: decrement }, "-1"),
  h(Home)
])

</script>

<style scoped>

</style>

Guess you like

Origin blog.csdn.net/weixin_56663198/article/details/131748533