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

 

 

 

 

 

 

 

 

posted @ 2020-12-17 20:18  vs1435  阅读(15783)  评论(0编辑  收藏  举报