Modularity combined with typescript-generic transformation

/ / add a generic function to function useURLLoader < T > (url: string) {const result = ref < T | null > (null)Copy the code
Interface DogResult {message: string; status: string; } interface CatResult { id: string; url: string; width: number; height: number; } / / free cat API https://api.thecatapi.com/v1/images/search?limit=1 const {result, loading, loaded } = useURLLoader<CatResult[]>('https://api.thecatapi.com/v1/images/search?limit=1')Copy the code

Wrap components using defineComponent

DefineComponent Document address

Teleport – Teleport part one

Vue3 adds a new default component called Teleport, which we can use directly. It has a to attribute, which takes a CSS Query Selector as an argument, which represents which DOM element to render the component into

<template>
  <teleport to="#modal">
    <div id="center">
      <h1>this is a modal</h1>
    </div>
  </teleport>
</template>
<style>
  #center {
    width: 200px;
    height: 200px;
    border: 2px solid black;
    background: white;
    position: fixed;
    left: 50%;
    top: 50%;
    margin-left: -100px;
    margin-top: -100px;
  }
</style>
Copy the code

Teleport – Teleport Part 2

Modal components

<template>
<teleport to="#modal">
  <div id="center" v-if="isOpen">
    <h2><slot>this is a modal</slot></h2>
    <button @click="buttonClick">Close</button>
  </div>
</teleport>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  props: {
    isOpen: Boolean,
  },
  emits: {
    'close-modal': null
  },
  setup(props, context) {
    const buttonClick = () => {
      context.emit('close-modal')
    }
    return {
      buttonClick
    }
  }
})
</script>
<style>
  #center {
    width: 200px;
    height: 200px;
    border: 2px solid black;
    background: white;
    position: fixed;
    left: 50%;
    top: 50%;
    margin-left: -100px;
    margin-top: -100px;
  }
</style>
Copy the code

Use in App components

const modalIsOpen = ref(false) const openModal = () => { modalIsOpen.value = true } const onModalClose = () => { modalIsOpen.value = false } <button @click="openModal">Open Modal</button><br/> <modal :isOpen="modalIsOpen" @close-modal="onModalClose"> My Modal !!!! </modal>Copy the code

Suspense – Asynchronous Requests for Good Help Part 2

Modify the asynchronous request with async await and create a dogshow.vue component

<template>
  <img :src="result && result.message">
</template>

<script lang="ts">
import axios from 'axios'
import { defineComponent } from 'vue'
export default defineComponent({
  async setup() {
    const rawData = await axios.get('https://dog.ceo/api/breeds/image')
    return {
      result: rawData.data
    }
  }
})
</script>
Copy the code

Multiple asynchronous components can be added in Suspense

<Suspense>
  <template #default>
    <async-show />
    <dog-show />
  </template>
  <template #fallback>
    <h1>Loading !...</h1>
  </template>
</Suspense>
Copy the code

Global API changes

  • Global configuration of Vue2
import Vue from 'vue'
import App from './App.vue'

Vue.config.ignoredElements = [/^app-/]
Vue.use(/* ... */)
Vue.mixin(/* ... */)
Vue.component(/* ... */)
Vue.directive(/* ... */)

Vue.prototype.customProperty = () => {}

new Vue({
  render: h => h(App)
}).$mount('#app')
Copy the code

Writing Vue2 this way modifies the global state of Vue objects to some extent.

  • First, in unit testing, global configuration is very easy to pollute the global environment, and users need to save and restore the configuration between each case. Some > apis (Vue use vue mixin) don’t even have a way to restore configuration, which makes testing some plug-ins very difficult.

  • Second, it becomes very difficult to share a vUE object with different configurations between different apps.

  • The modification of Vue3
Import {createApp} from 'vue' import App from './ app. vue' const App = createApp(App) Now any configuration Settings are on different app instances and will not cause any conflicts like vue2. app.config.isCustomElement = tag => tag.startsWith('app-') app.use(/* ... */) app.mixin(/* ... */) app.component(/* ... */) app.directive(/* ... * /) app. Config. GlobalProperties. CustomProperty = () = > {} / / when after the configuration, we put the app using the mount mount to fixed DOM node. app.mount(App, '#app')Copy the code

At the end

Do weigh in hand wrap up work, have don’t understand although ask, I am free will reply of

Big guys, interested can pay attention to my public number duck, now or single digit, wronged…

Lazy people, do not want to map, hope to help you

Public number: small he growth, the Buddha department more text, are their own once stepped on the pit or is learned things

Interested little partners welcome to pay attention to me oh, I was: he Small Life. Everybody progress duck together