Vue3高级使用

785 阅读1分钟

h 函数

hypeScript 是JavaScript插件,用于编写模板

示例:创建一个h2标签内容为hello render

<script>
// hypeScript 是JavaScript插件,用于编写模板
import { h } from "vue"
  export default {
    render() {
      return h("h2", {class: "title"}, "hello render")
    }
  }
</script>

h 函数的使用

在vue3中两种使用方式:

import { h,ref } from "vue"
  • 使用render函数:

        setup() {
          const counter = ref(0)
          return {
            counter
          }
        },
        render() {
          return h("div", {class: "wrapper"}, [
            h("h2", null, `当前计数: ${this.counter}`),
            h("button", {
              onClick: () => this.counter++
            }, "+1"),
            h("button", {
              onClick: () => this.counter --
            }, "-1")
          ])
        }
    
  • 在setup的返回值中写

        setup() {
          const counter = ref(0)
          return () => {
            return h("div", {class: "wrapper"}, [
              h("h2", null, `当前计数: ${counter.value}`),
              h("button", {
                onClick: () => counter.value++
              }, "+1"),
              h("button", {
                onClick: () => counter.value --
              }, "-1")
            ])
          }
        }
    

使用组件

父组件

<script>
import { h } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
export default {
  render() {
    // 使用组件
    // return h(HelloWorld, null)
​
    // 使用插槽
    return h(HelloWorld, null, {
      default: (props) => h("span", null, `App传到组件中的内容:${props.name}`),
    });
  },
};
</script>

子组件 helloworld(带插槽)

<script>
import { h } from "vue";
export default {
  render() {
    return h("div", null, [
      h("h2", null, "Hello World"),
      this.$slots.default
        ? this.$slots.default({ name: "插槽作用域" })
        : h("span", null, "helloworld 插槽"),
    ]);
  },
};
</script>

jsx

使用jsx实现对数字的加减:jsx语法 使用单括号模板语法,且括号内只能放置表达式

<script>
// npm install @vue/babel-plugin-jsx -D
import HelloWorld from "./HelloWorld.vue"
  export default {
    data () {
      return {
        counter: 0  
      }
    },
    render() {
      const increment = () => this.counter ++
      const decrement = () => this.counter --
      return (
        <div>
          <h2>当前计数: {this.counter}</h2>
          <button onClick={increment}>+1</button>
          <button onClick={decrement}>-1</button>
          <HelloWorld>
            {{default: () => <h2>App 传来的</h2>}}
          </HelloWorld>
        </div>
      )
    }
  }
</script>

helloworld组件

<script>
  export default {
    render() {
      return (
        <div>
          <h1>HelloWorld</h1>
          {this.$slots.default ? this.$slots.default() : <span>哈哈</span>}
        </div>
      )
    }
  }
</script>

自定义指令

vue3中自定义指令的生命周期和vue2中存在着不同(可以查阅vue2自定义指令知识

vue3自定义指令的生命周期和组件生命周期类似(示例:自动获取焦点

    directives: {
      focus: {
        created() {
          console.log("created");
        },
        beforeMount() {
          console.log("beforeMount");
        },
        beforeMount() {
          console.log("beforeMount");
        },
        mounted(el, binding, vnode, preVnode) {
          // 挂载后自动获取焦点
          el.focus()
          console.log("mounted");
          console.log(binding);// 指令后面的修饰符在modifers里面
        },
        beforeUpdate() {
          console.log("beforeUpdate");
        },
        updated() {
          console.log("updated");
        },
        beforeUnmount() {
          console.log("beforeUnmount");
        },
        unMounted() {
          console.log("unMounted");
        },
      }
    },

代码演练:规范时间戳; 完整代码

<template>
  <div>
    <h2 v-format-time>{{timestamp}}</h2>
  </div>
</template>
// npm install dayjs
import dayjs from "dayjs"
export default function(app) {
  app.directive("format-time", {
    created(el, bindings) {
      bindings.formatString = "YYYY-MM-DD HH:mm:ss"
      if (bindings.value) {
        formatString = bindings
      }
    },
    mounted(el, bindings) {
      const textContent = el.textContent
      let timeStamp = parseInt(textContent)
      if (textContent.length === 10) {
        timeStamp = timeStamp*1000
      }
      el.textContent = dayjs(timeStamp).format(bindings.formatString)
    },
  })
}

main.js文件中注册

// registerDirectives(app)
// app.use()默认会给调用的函数传入一个app对象,和上一行代码类似
app.use(registerDirectives)

teleport内置组件

teleport组件类似于传送,将该组件的内容通过属性 to指定选择器到对应的元素节点内

<template>
  <div class="container">
    <!-- 通过选择器,直接传送到对应标签内 -->
    <teleport to="#app">
      <h2>我是被传送过来的</h2>
    </teleport>
    <!-- 存在其他的传送并不会冲突,而是会被合并在一起 -->
    <teleport to="#app">
      <h2>我是第二个被传送过来的</h2>
    </teleport>
  </div>
</template>

image-20220210134012711.png

plugin——插件

并无变化,请参考Vue2的插件juejin.cn/post/703925…