1 Vue中自定义指令
2 Vue内置组件Teleport
3 Vue内置组件Suspense
4 Vue中安装插件的方式
5 Vue中渲染函数的使用
6 Vue中编写jsx的语法
Vue中自定义指令
自定义指令的绑定方法有两种,一种是局部的,一种是全局的。
指令可以将部分js代码转换成指令的方式来使用,js功能的代码可以分成直接在单独页面设置使用,还可以抽取成hooks函数调用。下面这个js代码的功能是进入这个页面的时候马上获取输入框焦点。
直接在页面创建的方法:
<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>
抽取成hooks:放在了./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>
使用指令的方式来实现上述的功能:
局部指令:可以用vue2的options api方法写,也可以是vue3的setup写法
在setup里面写指令一定要用v+大写字母才能是指令
<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>
全局指令的使用是在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")
注意:直接写在main。js里面会让main。js变得很庞大,我们可以抽取出来做成一个directive的文件夹2中写法:
focus.js代码:
export default function directiveFocus(app) { app.directive("focus", { // 生命周期的函数(自定义指令) mounted(el) { // console.log("v-focus应用的元素被挂载了", el) el?.focus() } }) }
main.js和index.js代码:
1、
index.js:
2、
index.js:
自定义指令有自己每个阶段的生命周期。
指令的修饰符
<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>
自定义指令小案例一
想要给数字添加对应的符号
在指令文件夹里面创建unit.js并输入
这个指令可以输入默认值,也可以直接设置用户输入的值。用户输入的时候直接在指令后面添加冒号和值。 例如: v-unit="参数"
在指令文件夹的入口文件添加指令
main.js
想要使用指令的地方
自定义指令小案例二
将时间戳转换成MM-MM-DD等等的格式
<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 } }) }
还有一些关于管理员登录后权限的问题,普通管理员能够操作的功能少,可以通过指令来判断和限制显示的结果。
Vue内置组件Teleport
将你写的组件(也可以是普通标签)传输到其他位置,是真的挂载过去了,页面会有变化。
大概主要是用在js控制的。
<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内置组件Suspense
将组件变成一个异步的,当页面加载时,页面需要去加载这个组件,在没加载出来之前可以先显示默认的提示,等加载好之后把提示清除替换成指定组件。
<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>
Vue中安装插件的方式
作用之一是用在app里面
可以将本来分开的app传入的到函数里面转变成链式调用的写法
类似于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")
Vue中渲染函数的使用
template模板会执行render函数,把标签转换成虚拟DOM。
h函数就是createVNode函数:
我们可以把template删除掉,改用render来自己渲染,而render函数需要返回一个createVNode,此时可以用h函数来代替,使用方法一样的。
基本使用:
_render函数计数器实现:
<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渲染组件:
<script> import { h } from 'vue' import Home from "./Home.vue" export default { render() { return h("div", { className: "app" }, [ h(Home) ]) } } </script> <style scoped> </style>
使用vue3来实现上面的功能:
// 这个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>