vue3.x 首次搭建 - 遇到的問題


vite2.x 初始化項目  

配置說明: https://cn.vitejs.dev/guide/#%E6%90%AD%E5%BB%BA%E7%AC%AC%E4%B8%80%E4%B8%AA-vite-%E9%A1%B9%E7%9B%AE

兼容性注意

Vite 需要 Node.js 版本 >= 12.0.0。

下面項目使用 ts, 初始化項目:

cnpm create @vitejs/app my-vue-app --template vue-ts

 

引入 vant , 實現按需加載+修改主題

需要安裝的一依賴包:cnpm install less sass vite-plugin-imp -D

關鍵代碼上圖圈住的,具體vite.config.ts配置文件如下:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vitePluginImp from 'vite-plugin-imp'
const { resolve } = require('path')

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),

    // 按需引入
    vitePluginImp({
      libList: [
        {
          libName: 'vant',
          style(name) {
            if (/CompWithoutStyleFile/i.test(name)) return false
            return `vant/es/${name}/index.less`
          }
      },
      ]
    })
  ],

  css: {
    preprocessorOptions: {
      // 重置vant的樣式變量:https://github.com/youzan/vant/blob/dev/src/style/var.less
      less: {
        modifyVars: {
          'button-primary-color': 'red',
          'button-primary-border-color': 'red'
        },
      },

      scss: {
        additionalData: `
          @import "./src/styles/_var.scss";
          @import "./src/styles/_mix.scss";
        `
      }
    }
  },
  
  base: '/ybs',

  alias: [
    { find: '/@', replacement: resolve(__dirname, 'src') },
    { find: '/@ser', replacement: resolve(__dirname, 'src/services') },
    { find: '/@comp', replacement: resolve(__dirname, 'src/components') }
  ],

  server: {
    port: 8080,
    proxy: {
      '/api': {
        target: 'http://10.9.129.13',
        changeOrigin: true,
        secure: false,
      }
    }
  }
})

附加上vant的樣式變量:https://github.com/youzan/vant/blob/dev/src/style/var.less

其他配置基本和1.x版本一樣,可以參考下面說明

 

vite1.x 初始化項目  

git地址:  https://github.com/vitejs/vite

npm init vite-app <project-name> cd <project-name> npm install npm run dev

安裝常用插件:

{
  "name": "xxx",
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  },
  "dependencies": {
    "@types/axios": "^0.14.0",
    "axios": "^0.21.0",
    "dayjs": "^1.9.7",
    "element-plus": "^v1.0.1-beta.14",
    "vue": "^3.0.4",
    "vue-router": "^4.0.1",
    "vuex": "^4.0.0-rc.2"
  },
  "devDependencies": {
    "@vue/compiler-sfc": "^3.0.4",
    "sass": "^1.30.0",
    "typescript": "^4.1.3",
    "vite": "^1.0.0-rc.13"
  }
}

添加配置文件:shims.d.ts(2.x版本會自動添加在src/shims-vue.d.ts

  使用ts開發,需要添加配置文件,不然ts不認識.vue文件
shims.d.ts
declare module '*.vue' {
  import { ComponentOptions } from 'vue'
  const componentOptions: ComponentOptions
  export default componentOptions
}

添加tsconfig.json

  參考:https://vue3js.cn/docs/zh/guide/typescript-support.html#npm-%E5%8C%85%E4%B8%AD%E7%9A%84%E5%AE%98%E6%96%B9%E5%A3%B0%E6%98%8E

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    /* 用來指定編譯時是否生成.map文件 */
    "declarationMap": false,
    "sourceMap": false,
    "paths": {
      "/@/*": ["./src/*"],
      "/@ser/*": ["./src/services/*"],
      "/@comp/*": ["./src/components/*"]
    }
  },
  "exclude": ["node_modules", "dist"]
}

引入Vue Router4

安裝: cnpm i vue-router@next -S 

使用命令行查看vue-router 所有版本號:  npm info vue-router versions

route/index.ts:

import { RouteRecordRaw, createRouter, createWebHashHistory } from 'vue-router';

const routes: RouteRecordRaw[] = [
  {
    path: '/home/:id',
    name: 'Home',
    component: () => import('../test/Home.vue'),
  },
  {
    path: '/user',
    name: 'User',
    component: () => import('../views/User.vue'),
  },
];

const router = createRouter({
  history: createWebHashHistory(),
  routes,
});

export default router;

添加UI插件 element-plus,main.ts 文件如下:

文檔: https://element-plus.gitee.io/#/zh-CN/component/i18n

element-ui 目前不支持vue3; 使用  element-plus,用法UI基本一樣

import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index'
import router from './router/index'
import ElementPlus from 'element-plus'
import zhLocale from 'element-plus/lib/locale/lang/zh-cn'  // 國際化
import 'element-plus/lib/theme-chalk/index.css'
import './styles/index.scss'

createApp(App)
.use(router)
.use(store)
.use(ElementPlus, { locale :zhLocale })
.mount('#app')

 配置文件:vite.config.ts(vue2的vue.config.js,2.x 版本參考上面說明

//git地址 https://github.com/vitejs/vite/blob/master/src/node/config.ts
const path = require('path');

module.exports = {
  // 配置別名
  alias: {
    '/@/': path.resolve(__dirname, './src'),
    '/@comp/': path.resolve(__dirname, './src/components'),
  },

  // 端口,默認3000
  port: '8080',

  // 是否自動在瀏覽器打開
  open: true,

  // 配置部署基礎路徑
  base: 'admin',

  // 引用全局 scss
  cssPreprocessOptions: {
    scss: {
      additionalData: `
        @import "./src/styles/_var.scss";
        @import "./src/styles/_mix.scss";
      `
    }
  },


  // 為開發服務器配置自定義代理規則
  proxy: {
    '/api': {
      target: 'http://10.110.52.28:8081',
      changeOrigin: true,
      secure: false,
    }
  }
}

 

問題1:  v-on="$listeners" 不能使用,v-bind="$attrs" 代替;

 

問題2:slot-scope="scope" 被廢棄, 使用  v-slot="scope"

 

問題3: scss  的 /deep/ 不能使用(至少在我寫這個博客時)

解決:使用  ::v-deep或者:deep(控制台會報警告,但總比不能使用好)

    

deep報錯:

 

問題4:修改全局的樣式,例如重置element樣式,保存可以立即生效,不過刷新還是原來一樣,需要重啟才生效;(2.x 版本已經解決

 

問題5:import dayjs from 'dayjs' 報錯;

解決方法1:import * as dayjs from 'dayjs';

解決方法2:tsconfig.json,添加配置文件:

"moduleResolution": "node",
"allowSyntheticDefaultImports": true,

 

問題6: element-plus 默認英文,需要使用中文如下配置:

import zhLocale from 'element-plus/lib/locale/lang/zh-cn'
createApp(App) .use(router) .use(ElementPlus, { locale :zhLocale }) .mount('#app')

 

element-plus 版本在 v1.0.1-beta.14 時,還可以使用上面方法,后面不知道什么版本開始,就不能使用了 會報錯:

 作者的解決方法:先在 node_nodules/element-plus/lib/locale/lang/zh-cn.js 找到配置,然后直接拿出來使用;

 

 

問題7:使用別名后,vetur報錯 Cannot find module

解決:tsconfig.json 文件添加路徑配置

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "sourceMap": true,
    "strict": true,
    "jsx": "preserve",
    "moduleResolution": "node",
    "paths": { "/@/*": ["./src/*"] }
  }
}

 

問題8:import echarts from 'echarts' 報錯

 解決:import * as echarts from 'echarts';

 

路由相關:

獲取當前路由:const route = useRoute(); 或者:

 路由跳轉(之前一致):

監聽路由變化:

路由鈎子:

home頁面的鈎子:

404路由配置:

  {
    path: '/404',
    name: '404',
    component: () => import('/@/views/404.vue')
  },
  {
    path: '/:pathMatch(.*)*',
    redirect: '/404'
  }

別名:

表示訪問url時自由命名,不受約束,router會自動進行別名匹配,就像我們設置/的別名為/home,相當於訪問/

const routes = [{ path: '/', component: Homepage, alias: '/home' }]  // alias是別名的key

重定向:

// 路徑寫法
const routes = [{ path: '/home', redirect: '/' }]

// 命名寫法
const routes = [{ path: '/home', redirect: { name: 'homepage' } }]

// 函數寫法
const routes = [ 
{ 
    path: '/search/:searchText',
    redirect: to => { 
        return { path: '/search', query: { q: to.params.searchText } }
    } 
}    

路由插槽:

append、event、tag、exact上面列舉的4個屬性已經不再使用,改為作用域插槽:

<router-link to="/" v-slot="{ href, navigate, isActive }">
  <li :class="{ 'active': isActive }">
    <a :href="href" @click="navigate">
      <span>Home</span>
    </a>
  </li>
</router-link>

<router-view> <keep-alive> <transition>現在必須通過v-slot API在router-view內部使用transitionkeep-alive

<router-view v-slot="{ Component }">
  <transition>
    <keep-alive>
      <component :is="Component" />
    </keep-alive>
  </transition>
</router-view>

動態路由:router.addRoute()router.removeRoute()

// addRoute 添加路由
router.addRoute({ name: 'about', path: '/about', component: About })

// removeRoute是刪除路由,刪除后對應的子路由和別名都會刪掉
router.removeRoute('about')

// 路由嵌套
router.addRoute('about', { path: 'profile', component: Profile})

//等價於
router.addRoute({
  name: 'about',
  path: '/about',
  component: About,
  children: [{ path: 'profile', component: Profile}],
})

 

vuex 相關:

const store = useStore();
// state
const list = computed(() => store.state.foodList);
// getters
const userInfo = store.getters.userInfo;

// 觸發mutations,改變值:
store.commit('setFoodList', resList);

// 觸發actions異步操作,改變值:
store.dispatch(`login`)

對於復雜的業務可以封裝一個hook,例子:

function useContentData(store: Store<IGlobalState>) {
  let cityList = computed(() => store.state.home.cityList)
  let accessControlList = computed(() => store.state.home.accessControlList)
  onMounted(() => {
    if (cityList.value.length === 0) store.dispatch(`xxx`)
    if (accessControlList.value.length === 0) store.dispatch(`xxxx`, { communityId: 13 })
  })
  return {
    cityList,
    accessControlList
  }
}

 

vue3使用說明:

拋棄data, 使用 setup

數組,字符串,數字,布爾使用 ref

const name = ref<string>('0');

計算屬性:

const nameComputed = computed(() => name.value + '  computed');

復雜對象使用reactive

const msg = reactive<any>({ obj: 123 });

 

Teleport 傳送門

組件可以任意地丟到html中的任一個DOM下。在react中也有相同功能的組件——Portal;

子組件:

 <teleport to="#endofbody">
    <div v-if="modalOpen">
      teleport content
    </div>
 </teleport>

 上層組件:

<div id="endofbody"></div>

 使用后,子組件的內容,會填充到上層組件中;

 

Suspense異步組件

方便地控制異步組件的一個掛起和完成狀態,簡單來說:

1.  Suspense將異步組件包起來;

2. template #default中展示加載完成的異步組件;

3. template #fallback中則展示異步組件掛起狀態時需要顯示的內容;

例子:

// AsyncComponent.vue
<template>
  <h2>AsyncComponent</h2>
</template>
<script lang="ts">
import {defineComponent} from "vue"
export default defineComponent({
  async setup(props) {
    const sleep = (timeout: number) => {
      return new Promise(resolve => {
        setTimeout(resolve, timeout)
      })
    }
    await sleep(5000)
  }
})
</script>

// Suspense.vue    
<template>
  <h1>Suspense</h1>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <p class="loading">loading</p>
    </template>
  </Suspense>
</template>
<script lang="ts">
import {defineComponent} from "vue"
import AsyncComponent from "./AsyncComponent.vue"
export default defineComponent({
  components: {
    AsyncComponent
  }
})
</script>

 

script setup 語法糖

vue3.0.3 推出了setup 語法糖,下面是例子

      

 

樣式使用變量v-bind語法糖 

 

 

其他

目前第三方庫都是測試版本,附帶各個版本的說明:

 

參考:

vue: https://vue3js.cn/docs/zh/guide/introduction.html

vuex: https://next.vuex.vuejs.org/

vue-router: https://next.router.vuejs.org/api/

element-plus: https://github.com/element-plus   https://element-plus.org/#/zh-CN/component/installation

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM