zoukankan      html  css  js  c++  java
  • 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

     

     

     

     

  • 相关阅读:
    2016-12-7
    使用netty4.x客户端接收较大数据量报文时发生的读取不完整bug修复记录
    AngularJS
    使用Netty收发二进制报文问题记
    如何在Linux中查看所有正在运行的进程
    面试连环炮系列(十四): HTTP状态码302的跳转逻辑
    算法天天练1:计算最长子串
    面试连环炮系列(十三):实现一个线程有几种方法
    面试连环炮系列(十二):说说Atomiclnteger的使用场景
    面试连环炮系列(十一):说说你们的分布式ID设计方案
  • 原文地址:https://www.cnblogs.com/vs1435/p/14151651.html
Copyright © 2011-2022 走看看