Preface:

With the improvement of vue3.2 related ecology, new projects have to be considered directly on the new version, new grammar sugar. Companies often have active pages to implement, so this article describes a simple vue3.2 mobile example. For beginners

figure

experience

🎸 Demo Visit 🌈 Github

Rely on

  • 🚀 vue3.2 + vite + typescript + pinia + axios + vant
  • Use 💪 vue3.2<script setup>New syntactic sugar
  • Use 💪 TypeScript
  • 🍭 The JSX component is supported
  • 🍭 Integrate Vant UI and less
  • 🍭 Use the ViewPort mobile solution
  • 🍭 uses Pinia instead of Vuex, which is simpler and more efficient
  • 🍭 uses the NetEase Cloud Music Popular songs interface as the data source
  • 🍭 stay updated

Note: a free API site is recommended for ordinary mocks using the UomgAPI

Vite scaffolding is built quickly

Note: Vite requires Node.js version >= 12.0.0

  1. Create typescript-enabled templates
#Install vite
yarn create vite

#Using a Template
yarn create vite my-vue-app --template vue-ts
Copy the code

Vite currently supports fast template generation:

  • vanilla
  • vanilla-ts
  • vue
  • vue-ts
  • react
  • react-ts
  • preact
  • preact-ts
  • lit
  • lit-ts
  • svelte
  • svelte-ts

For more installation operations, see the official website

  1. After the installation, the directory is as follows

  1. Go to the directory to install dependencies
#The installation
yarn

#Start the
yarn dev
Copy the code

Constraint code specification

Install Eslint, prettier

  1. Install dependencies
yarn add --dev eslint prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-vue @typescript-eslint/parser  @typescript-eslint/eslint-pluginCopy the code
  1. Create the.eslintrc.js file in the root directory
//.eslintrc.js
module.exports = {
  root: true.env: {
    node: true
  },
  parser: 'vue-eslint-parser'.parserOptions: {
    parser: '@typescript-eslint/parser'.// Specifies the ESLint parser
    ecmaVersion: 2020.// Allows for the parsing of modern ECMAScript features
    sourceType: 'module'.// Allows for the use of imports
    ecmaFeatures: {
      jsx: true}},extends: [
    'plugin:vue/vue3-recommended'.'plugin:@typescript-eslint/recommended'.'prettier'.'plugin:prettier/recommended'].rules: {
    '@typescript-eslint/no-var-requires': 0.'@typescript-eslint/explicit-module-boundary-types': 'off'.'space-before-function-paren': 0.'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off'.'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'}}Copy the code
  1. Create the.eslintignore file in the root directory
# esLint ignores checking (added as needed for the project) node_modules distCopy the code
  1. Create the.prettierrc.js file in the root directory
module.exports = {
  printWidth: 100.// The number of characters in a line. If more than 80 characters are added to the line, the default value is 80
  tabWidth: 2.// A TAB represents several Spaces. The default is 80
  useTabs: false.// Whether to use TAB for indentation. The default value is false, indicating that Spaces are used for indentation
  singleQuote: true.// Whether to use single quotation marks for strings. The default is false. Use double quotation marks
  semi: false.// Whether to use semicolons on line bits. Default is true
  trailingComma: 'none'.Tail / / whether or not to use commas, there are three optional value "< none | es5 | all >"
  bracketSpacing: true.{foo: bar} {foo: bar}
  jsxSingleQuote: true.// JSX syntax uses single quotes
  endOfLine: 'auto'.'prettier.spaceBeforeFunctionParen': true
}
Copy the code
  1. Create the.prettierignore file in the root directory
dist/
node_modules
*.log
run
logs/
coverage/
Copy the code
  1. Use vscode development tools to automatically format when saving

    1> Install prettier-code Formatter extension inside prettier-code Formatter extension

    2> In preferences – Settings – Formatting, configure save formatting

    3> At this point, save when you modify.vue,.tsWhen waiting for the file, it will be automatically formatted if it has been configured in the project.prettierrc.jsFile, the rules in this file will be used preferentially.

The CSS preprocessor is installed

less

Vite provides built-in support for.scss,.sass,.less,.styl, and.stylus files. There is no need to install specific Vite plug-ins for them, but the appropriate preprocessor dependencies must be installed:

yarn add --dev less
Copy the code

If using a single file component, this can be automatically enabled by

Configure global Styles

Create a global.less file that defines global theme color values, etc., that can be referenced by other components

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue';

export default defineConfig ({
  plugins: [
    vue()
  ],
  css: {
    preprocessorOptions: {
      less: {
        charset: false.additionalData: '@import "./src/style/global.less"; ' // Load the global style using the less feature}}}});Copy the code

Mobile adaptation

viewport

Previously, mobile adaptation has always used lib-flexible+ PostCSS-Pxtorem solution. As viewPort unit is supported by more and more browsers, lib-flexible official has been basically abandoned. We recommend everyone to use viewPort solution.

viewport + postcss-px-to-viewport

We automatically convert px to a viewport unit vw, which is essentially a percentage unit. 100vw equals 100%, window.innerwidth

  1. Install postcss – px – to – the viewport
yarn add --dev postcss-px-to-viewport
Copy the code
  1. Create the postcss.config.js file in the project root directory
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      unitToConvert: 'px'.// The unit to convert, default is "px"
      viewportWidth: 750.// The viewport width of the design draft
      exclude: [/node_modules/].// Solve vant375, design draft 750. Ignore files under certain folders or specific files
      unitPrecision: 5.// The precision retained after the unit conversion
      propList: [The '*'].// List of attributes that can be converted to vw
      viewportUnit: 'vw'.// The viewport unit you want to use
      fontViewportUnit: 'vw'.// The viewport unit used by the font
      selectorBlackList: [].// CSS selectors that need to be ignored will not be converted to viewport units, using the original units such as PX.
      minPixelValue: 1.// Set the minimum conversion value. If it is 1, only values greater than 1 will be converted
      mediaQuery: false.// Whether the unit in the media query needs to be converted
      replace: true.// Whether to replace the attribute value directly without adding the standby attribute
      landscape: false.// Whether to add media query criteria based on landscapeWidth @media (Orientation: landscape)
      landscapeUnit: 'vw'.// The unit used in landscape
      landscapeWidth: 1125 // Width of viewport for landscape}}}Copy the code
  1. Here is the configuration, according to the size of the design draft development, configuration viewportWidth, you can be one to one px development, do not have to calculate

The introduction ofVant ui

In small projects, it is common to use third-party open source UI components to avoid excessive hand-written style components, and this example configuration relies on the Vant UI

  1. Install dependencies
# install vant yarn add vant # install vant yarn add vant # install vant yarn add vantimport@1.41. -D
Copy the code
  1. Configure the plug-in
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue';
import styleImport, { VantResolve } from 'vite-plugin-style-import';

export default defineConfig ({
  plugins: [
    vue(),
    styleImport({
      resolves: [VantResolve()],
    }),
  ],
});

Copy the code
  1. Compatible with vant team’s 375px design

We usually use a 750px design, but the Vant team is based on a 375px design, which is ideal for a 375px viewport width. So we can’t always divide 750px by 2, that would be too much trouble. So simply ignore the units dependent on the third party and just convert the local PX to VW units

Postcss.config. js file and add exclude: [/node_modules/]

module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      exclude: [/node_modules/].// Solve vant375, design draft 750. Ignore files under certain folders or specific files}}}Copy the code
  1. vant@vant/usePackages are limited to typescript versions. After typescript4.5.5, the VisibilityState state is no longer supported, so you need to change typescript version dependencies

package.json

"devDependencies": {
   // Use only the highest version of 4.5.x
   "typescript": "~ 4.5.2." ",}Copy the code

If you use the typescript high version, then build, will be submitted to the following error: node_modules / @ vant/use/dist/usePageVisibility/index which s: known – error TS2304: Cannot find name ‘VisibilityState’. 2 export declare function usePageVisibility(): Ref; Found 1 error in node_modules/@vant/use/dist/usePageVisibility/index.d.ts:2

  1. Now you can use it

Global references

import { createApp } from 'vue'
import App from './App.vue'
import { Button, Loading, Empty } from 'vant'

const app = createApp(App)
app.use(Button).use(Loading).use(Empty)
app.mount('#app')
Copy the code

Templates can be used directly

<template> <van-loading></van-loading> <van-loading>< van-button round class="retry-button"> </van-button> </template>Copy the code

Routing the router

  1. The installation
yarn add vue-router@4
Copy the code
  1. The root directory creates the router directory and the index.ts file

index.ts

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

const routes: Array<RouteRecordRaw> = [
  {
    path: '/'.name: 'home'.component: () = > import('@/views/Home.vue')}]const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

Copy the code
  1. Loading of the router

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
import { Button, Loading, Empty } from 'vant'

const app = createApp(App)
app.use(router)
app.use(Button).use(Loading).use(Empty)
app.mount('#app')
Copy the code

For more configurations, please refer to the official website

axios

  1. The installation
yarn add axios
Copy the code
  1. Create a new utils directory and a request.ts file

request.ts

import axios from 'axios'
import { CT } from '@/config/config'
import { Toast } from 'vant'

// axios.defaults.headers.common['Content-Type'] = 'application/json'
// axios.defaults.headers.common['area-code'] = 'CWHT'
// Create an axios instance
const request = axios.create({
  timeout: CT.timeout // Request timeout
})

// Exception interception handler
const errorHandler = (error: any) = > {
  if (error.response) {
    const data = error.response.data
    Toast(data.message)
  }
  return Promise.reject(error)
}

// request interceptor
request.interceptors.request.use((config) = > {
  // Customize the global header
  config.headers = config.headers ? config.headers : {}
  config.headers['Content-Type'] = 'application/json'
  return config
}, errorHandler)

// response interceptor
request.interceptors.response.use((response) = > {
  return response
}, errorHandler)

export default request

Copy the code
  1. Create a new API directory and create the service.ts file
import request from '@/utils/request'
import { URL } from '@/config/config'

// Get random music information
export const fetchRandMusic = () = > {
  return request.get(`${URL.musicUrl}/rand.music? Sort = format=json)}Copy the code
  1. Using API Examples
import { reactive, toRefs } from 'vue'
import { fetchRandMusic } from '@/api/service'
import { HomeHooksModel } from '@/model/HomeModel'

// Home page hooks module
export const HomeHooks = () = > {
  // Response value definition
  const indexRec = reactive<HomeHooksModel>({
    loading: true.noData: false.musicData: {}})// Query random music information
  const fetchMusicInfo = async() = > {const { data } = await fetchRandMusic()
    indexRec.loading = falseindexRec.noData = data.code ! = =1
    indexRec.musicData = data.data
  }
  return { ...toRefs(indexRec), fetchMusicInfo }
}

Copy the code

pinia

Vuex is a hassle to use, and in the future vUE officials will abandon vuex and use Pinia entirely

  1. The installation
yarn add pinia
Copy the code
  1. Create the directory stores and create the index.ts file

index.ts

import { defineStore } from 'pinia'

export const refreshStore = defineStore('refresh', {
  state: () = > {
    return { refreshNum: 0}},getters: {
    queryRefresh(): number {
      return this.refreshNum
    }
  },
  actions: {
    upRefresh(st: number) {
      this.refreshNum = st
    }
  }
})
Copy the code
  1. Call pinia Store to update the status value
<script setup lang="ts">
import { ref } from 'vue'
import { refreshStore } from '@/stores/index'
// Receive status values
const refresher = refreshStore()

const clickRefresh = () = > {
  // Update the status value
  refresher.$patch({ refreshNum: refresher.refreshNum + 1 })
}
</script>
Copy the code

Configuring a Path Alias

  1. Add an alias to the vite. Config. ts file
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue';
import styleImport, { VantResolve } from 'vite-plugin-style-import';

export default defineConfig ({
  plugins: [
    vue(),
    styleImport({
      resolves: [VantResolve()],
    }),
  ],
  resolve: {
    alias: {
      The '@': resolve(__dirname, 'src')}}});Copy the code
  1. The tsconfig.json file is added as follows:
{
  "compilerOptions": {
    "baseUrl": "."."paths": {
      "@ / *": ["src/*"]}}}Copy the code

The configuration supports JSX

  1. Install dependencies
npm install @vitejs/plugin-vue-jsx -D
Copy the code
  1. Configure the plug-in
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
  plugins: [vue(), vueJsx({})]
})
Copy the code
  1. In env.d.ts file, declare libraries without types to be imported as any
declare module '*.jsx';
Copy the code

Configuring Route Transition

APP.vue

<template>
  <router-view v-slot="{ Component }">
    <transition name="fade">
      <component :is="Component" />
    </transition>
  </router-view>
</template>

<style lang="less">
.fade-enter-active..fade-leave-active {
  transition: opacity 1s ease;
}
.fade-enter-from..fade-leave-to {
  opacity: 0;
}
</style>
Copy the code

At the end

Ok, that’s it for now

Source repository address: github.com/kingfront/f…

Example Visit address: freely. Vercel.app

The Demo uses free Vercel for static deployment (fast). If you want to use your partner, add comments, follow up with new tutorial 💪💪