Vue3 +typescript Combat project, vuE3

CreateApp (App). Component failure

Component provided template option but Runtime compilation is not supported

[Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler  to alias "vue" to "vue/dist/vue.esm-bundler.js". at <Test message=1 > at <App>Copy the code

Solution:

Scenario 1: index.html template, which registers global components with Component. (Not recommended)

/ / main. In ts
import { createApp } from 'vue'
import App from './App.vue'
app.component('Test', {
    template: '#test'.// Note this line
})
app.mount('#app')
Copy the code

There is a template with ID test available in HTML

<div id="test">   <! -->test123</div>
<div id="app"></div>
Copy the code

Solution 2: Alias

Vue. Config. js, alias, vue; I use Webpack to start vuE3. Because using Vite often hot starts will hang

module.exports={
    configureWebpack: config= >{
        config.resolve = {
            alias: {vue:"vue/dist/vue.esm-bundler.js" // Add this to the list and restart it to use it}}}}Copy the code

The main ts file

import { createApp } from 'vue'
import App from './App.vue'
// import store from './store'

const app = createApp(App)
app.component('button-counter', {
    template: `<button>You clicked me times.</button>`
})
app.mount('#app')
Copy the code

App. Vue file

<template>
   <button-counter></button-counter>
</template>
Copy the code

The principle is probably the difference between VUE3’s Compiler mode and Runtime mode. But my store doesn’t work anymore.

Plan 3: App.com Ponent

main.ts

const app = createApp(App);
import Title from './components/Title.vue'
app.component('newtitle',Title)
Copy the code

Title.vue

<template>
    <div>The content title</div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
    name: 'Title',})</script>
Copy the code

Ref,reactive for arrays

const componentList: Record<string, any> = ref([])
componentList = res.data.componentList  // Incorrect usage
componentList.value = res.data.componentList // Use.value to change its value

Copy the code

Directive [vue3 modified]

  • App. directive registration has been changed
  • Mounted is used instead of bind. Unbind corresponds to unmounted

vue2 v-clickoutside demo

/** * clickoutside of the element to close the v-clickoutside binding */
export function clickoutside(){
    return {
        // Initialize instruction
        bind(el,binding,vnode){
            function documentHandler(e){
                // Check if the clicked element is itself
                if(el.contains(e.target)){
                    return false;
                }
                // Check whether the instruction is bound to a function
                if(binding.expression){
                    // If a function is bound, that function is called, where binding.value is the handleClose methodbinding.value(e); }}// Bind a private variable to the current element so that you can unbind events
            el.__vueClickOutside__ = documentHandler;
            document.addEventListener("click",documentHandler);
        },
        update(){},
        unbind(el,binding){
            // Remove event listening
            document.removeEventListener("click",el.__vueClickOutside__);
            deleteel.__vueClickOutside__; }}}Copy the code

vue3 v-clickoutside demo

export function clickoutside() {
    return {
        // Initialize instruction
        mounted(el: any, binding: any) {
            function documentHandler(e: any) {
                // Check if the clicked element is itself
                if (el.contains(e.target)) {
                    return false;
                }
                // Check whether the instruction is bound to a function
                if (binding.value) {
                    // If a function is bound, that function is called, where binding.value is the handleClose methodbinding.value(e); }}// Bind a private variable to the current element so that you can unbind events
            el.__vueClickOutside__ = documentHandler;
            document.addEventListener("click", el.__vueClickOutside__);
        },
        unmounted(el: any) {
            // Remove event listening
            document.removeEventListener("click", el.__vueClickOutside__);
            deleteel.__vueClickOutside__; }}}// Reference mode
import { clickoutside, copy } from '@/common/directive'
const clickoutsideObj: Record<string, any> = clickoutside()
app.directive('clickoutside', clickoutsideObj)
Copy the code

$refs [vue3 modified]

<div :ref="el => { divs[i] = el }> setup(){ const allComP = ref([]) onUpdated(() => { console.log('allComP.value', allComP.value) }) return {allComP} }Copy the code

Corresponding documents v3.vuejs.org/guide/compo…

Slot [vue3 has been modified]

vue2-slot demo

/ / the parent component
<SonComponent>
    <template slot='toTop'>
        <div class="scrollWrap-toTop fixed-box"></div>
    </template>
</SonComponent>

//SonComponent
<template>
	<slot name='toTop'></slot>
</template>
Copy the code

vue3-slot demo

/ / the parent component
<SonComponent>
	<template v-slot:toTop>/ / the difference between<div class="scrollWrap-toTop fixed-box"></div>
	</template>
</SonComponent>

/ / SonComponent inside
<template>
	<slot name="toTop"></slot>
</template>

Copy the code

5C40:2834 Uncaught (in Promise) TypeError: Cannot read property ‘created’ of undefined

  • The problem I ran into was that the custom directive was not registered but was used ahead of time
  • An error is reported when attributes or binding events on the tag are not registered in advance

Module cannot display, no prompt

Suspense for solutions is good, but I ran into component V -for=”item in list” is:item

 async setup(){ // If async is added, there will be a problem. No solution is available
}
Copy the code

Error message about TS in vue3+typescript combat project

Object is possibly ‘null’.

Type of solution AS

const scrollElement = document.querySelector('body') 
scrollElement.scrollTop

// Solution
const scrollElement = document.querySelector('body') as HTMLElement
Copy the code

Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type

Solution attach type

const componentsMap = {
    title: Title,
    abstract: Abstract
}

Object.keys(componentsMap).forEach(val= > {
    app.component(val, componentsMap[val]) //componentsMap[val] error
})

// Solution
const componentsMap :any   / / plan 1
const componentsMap :Record<string, DefineComponent>  2 / / solution
Copy the code

Property ‘xxx’ does not exist on type ‘Window & typeof globalThis’

Solution Window.d. ts

interface Window {
    getAccount(): string | number | never
}

/ / use
window.getAccount()
Copy the code

The error may be because you have changed the d.ts file but vscode has not been recompiled

Global abbreviation — Record<string, any> add a

type Obj = Record<string, any>
Copy the code

An arbitrary member of an Object

interface A{
	[params: string]:any
}
Copy the code

No overload matches this call.Overload 1 of 2, ‘(… items: ConcatArray[]): never[]’, gave the following error.

type Item = {
  time: number;
};

const list = [].concat([{ time: 123 }]); // Time will report an error
Copy the code

Solution 1:

const list = ([] as Item[]).concat([{ time: 123 }]);
Copy the code

Solution 2:

const initList: Item[] = []
const list = initList.concat([{ time: 123 }]);
Copy the code

Argument of type ‘Record<string, any> & { isNew: boolean; }’ is not assignable to parameter of type ‘never’.

An error scenario

const list = ref([]);
const list.value.unshift({}) / / an error
Copy the code

The solution

const allListModule: Record<string,any>[] = []
const allList = ref(allListModule)
const allList.value.unshift({})
Copy the code

Property ‘forEach’ does not exist on type ‘HTMLCollectionOf<Element>’

The solution

const frameZones = Array.from(document.querySelectorAll('path.frame-zone'));
frameZones.forEach((.) = > {});
Copy the code

‘this’ implicitly has type ‘any’ because it does not have a type annotation.

Vue2. X and various ESLint errors summary

Most of these are ESLint errors

1:1 error Parsing error: Unexpected token <

Parsing error: Unexpected character ‘@’

Eslint projects using.eslintrc.js keep ‘plugin:vue/essential’, other comments

module.exports = {
    root: true,
    env: {
        node: true
    },
    'extends': [
        'plugin:vue/essential',  Error Parsing error: Unexpected token < // Error Parsing error: Unexpected token <
        'eslint:recommended',
        '@vue/typescript/recommended' //Parsing error: Unexpected character '@'
    ],
    parserOptions: {
        ecmaVersion: 2020
    },
    rules: {
        'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
        'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
    }
}
Copy the code

No overload matches this call.The last overload gave the following error.

export default defineComponent({
    name: 'Title'.props: {
        propData: {
            title: ' '.// Error in using the basic prop syntax}},setup() {
        console.log(`title`)}})Copy the code
  • Answer: cn.vuejs.org/v2/guide/co…

Typescript Vue Emitters. Js doesn’t work. Broadcast does not work, dispatch does not work

The case code is as follows

@Component
export default class HelloWorld extends Vue {
  componentName = 'HelloWorld333'
 
}
Copy the code

The problem is that to register a comoponentName you need to write it like this

@Component({
	componentName:'realComponentName' // This is how it works
})
export default class HelloWorld extends Vue {
  componentName = 'HelloWorld333'
 
}
Copy the code

Principle: class-component.vuejs.org/guide/class…

Vue-cli sourceMap cannot break points; The debugger cannot be located.

Unable to break points and found code blocks in webpack-internal://

  • The solution
//vue.config.js
configureWebpack: {
    devtool: 'source-map',}Copy the code

Disable WARN in ESLint. Stop exporting WARN in ESLint and set WARN to 0.

/ /. Eslintrc. Js file
module.exports = {
    rules: {
        warn: 0}};Copy the code

File global unconcern esLint

  • Add /* eslint-disable */ to the file header

Vue3. X API

There are two ways to register for computed

  1. read-only
import { defineComponent, computed,ref } from 'vue'
export default defineComponent({
	name:'Test'.setup(){
    	const count = ref(1);
        const plusOne = computed(() = > count.value + 1})
        console.log(plusOne.value)
        plusOne.value++ / / an error}})Copy the code
  1. Can read but write
const plusOne = computed({
	get:() = > count.value +1.set:(val) = >{
    	count.value = val -1}})Copy the code

Vue2. X API

Provide and Inject, vue-property-decorate

  • Follow a few rules:
  • Dojo.provide, inject
  1. The father component registers provide, and the son component obtains the corresponding attribute through Inject
/ / father components
@Provide() provide = 1 

/ / son components
@Inject({ from: 'provide'.default: 0}) provide! : numberCopy the code
  1. Parent and child components are independent memory units when they change their corresponding values. Each other
  • ProvideReactive, InjectReactive
  1. Father registers ProvideReactive, and the son component gets the property using @InjectreActive.
  2. When father changes the value, the child component can be caught using watch
  3. The child component cannot change the corresponding value
/ / father components
@ProvideReactive() provideReactive = 1

/ / son components
@InjectReactive({ from: 'provideReactive'}) provideReactive! : number @Watch('provideReactive')
onChangeProvideReactive() {
    console.log('%c special output watch provideReactive'.'color:#ff0000') // Can capture the cause
}
test() {
    this.provide = 2	/ / can be modified
    console.log(`%c change provide`.'color:#ff0000'.this.provide) 
    this.provideReactive = 2	// The modification does not take effect
    console.log(`%c change provideReactive`.'color:#ff0000'.this.provideReactive)
}
Copy the code

Vue2 + TS advanced essential library

vue-class-component

Class decorator vue-class-Component

vue-property-decorator

npm i vue-class-component vue-property-decorator -D

Class and other decorators, Base (VUe-class-Component) : vue-property-decorator

*. Vue supports ts syntax, you need to add lang=ts to script

Vue-cli3 Configuration Experience

configureWebpack

If the value is an object, it is merged into the final configuration using webpack-Merge.

That makes sense. It’s just writing something that should be in {config} into this property

chainWebpack

Allows for more fine-grained changes to the internal WebPack configuration.

Nothing more than with Vue inspect to modify the corresponding configuration;

vue.config.js

module.exports = {
  chainWebpack: config= > {
    // GraphQL Loader
    config.module
      .rule('graphql')
      .test(/\.graphql$/)
      .use('graphql-tag/loader')
        .loader('graphql-tag/loader')
        .end()
      // You can also add another loader
      .use('other-loader')
        .loader('other-loader')
        .end()
  }
}
Copy the code

Various API addresses

  • Vue2 website
  • Vue3 website
  • Vue3 Chinese
  • Character encoding summary

Summary of problems encountered in using Sketch diagrams

  • The shortcut key for switching between PX and percentage in Sketch is Alt