vue3项目上手

Vue3 + Vite 项目起步

1.0 Vue官网

  1. Vue官方文档:快速上手 | Vue.js (vuejs.org)

2.0 淘宝镜像

查看镜像:

npm config get registry

设置淘宝镜像

npm config set registry https://registry.npm.taobao.org/

1.0 创建项目并精细化配置

1.0 创建vite

  1. 创建vite

    npm init vue@latest
    
  2. 切换该目录,然后初始化项目,然后运行

    cd 目录名
    npm install
    npm run dev
    

2.0 npm命令依赖冲突问题

--legacy-peer-deps

2.0 增加src子目录

1.0 apis文件夹

API接口文件夹 : 统一管理api接口

2.0 composables文件夹

组合函数文件夹 : 通用的逻辑函数

3.0 directives文件夹

全局指令文件夹 : 自定义指令

4.0 styles文件夹

全局样式文件夹 :存放样式的

5.0 utils文件夹

工具函数文件夹 :存放一些工具的,专门提供api方法

3.0 git管理项目

1. git init
2. git add
3. git commit -m "init"

2.0 配置别名路径联想提示

提升编写代码能力。 即编写代码过程中,输入"@/"就会联想出src下的子目录

1.0 如何在vscode下进行配置

“@/”:vue本来就提供了该功能,我们在vscode配置的目的是vscode能出现代码提示。

在项目的根目录下新增 jsconfig.json文件

{
    "compilerOptions": {
        "baseUrl": "./",
        "paths": {
            "@/*":[
                "src/*"
            ]
        }
    }
}

3.0 elementPlus

Vue3 项目中对应的是elementPlus , vue2项目对应的是element-ui

官方文档

官方文档:[快速开始 | Element Plus (gitee.io)](https://element-plus.org/zh-CN/)

1.0 按需导入

  1. 使用包管理器npm,安装包

    /* save指令 :开发和生产都需要 */

    npm install element-plus --save
    
  2. 需要安装这两款插件unplugin-vue-components 和 unplugin-auto-import

  3. 安装插件

    /* -D指令 仅开发需要 */

    npm install -D unplugin-vue-components unplugin-auto-import
    
  4. 在vite.config.js中,配置插件

    /* 1. 导入3个,2. 在plugins新增两个 */

import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})
  1. 在组件栏目下选择一个组件进行测试

    <el-button type="primary">Primary</el-button>
    

2.0 elementPlus主题定制

Q1:为什么需要主题定制?

A:elementPlus默认的主题色是蓝色的,而有些时候项目需要的配色是其他颜色的,所以要修改主题颜色

3.0 主题定制方案 —— scss变量替换方案

  1. 安装scss

    npm i sass -D
    
  2. 在styles文件夹新建element,并新建一个index.scss文件

    @forward 'element-plus/theme-chalk/src/common/var.scss' with(
        $colors:(
            'primary':(
                // 主色
                'base':#27ba9b,
            ),
            'success':(
                // 成功色
                'base':#1dc779
            ),
            'warning':(
                // 警告色
                'base':#ffb302,
            ),
            'danger':(
                // 危险色
                'base':#e26237
            ),
            'error':(
                // 错误色
                'base':#cf4444,
            ),
        )
    );
    
  3. 在vite.config.js设置配置,自动导入配置

    /* 1. 在components新增对象 2. 新增css结点 */

      plugins: [
        vue(), 
        AutoImport({
          resolvers: [ElementPlusResolver()],
        }),
        Components({
          resolvers: [
            // 1.配置ementPlus采用sass样式配色系统
            ElementPlusResolver({importStyle:"sass"})
        ],
        }),
      ],
      css:{
        preprocessorOptions:{
          scss:{
            // 2. 自动导入定制化样式文件进行样式覆盖
            additionalData:`
              @use "@/styles/element/index.scss" as *;
            `
          }
        }
      }
    

4.0 axios基础配置

官方文档

官方文档:起步 | Axios 中文文档 | Axios 中文网 (axios-http.cn)

1.0 axios的安装

npm install axios

2.0 axios的基础配置

  • 接口基地址 : baseUrl
  • 接口超时时间 : timeout
  • 请求拦截器 :interceptors.request
  • 响应拦截器 :interceptors.response
  1. 在utils下创建http.js文件,用于配置axios基础封装(全部项目都有这一步)

    /* 该文件是产生axios实例的 ,默认导出不需要解构赋值的方式接收 */

    import axios from 'axios'
    
    // axios基础封装
    const $http = axios.create({
        baseURL:"http://localhost:5173/api",
        timeout:5000  //五秒
    })
    
    //拦截器
    // 请求拦截器
    $http.interceptors.request.use(config =>{
        return config
    },e => Promise.reject(e))
    
    // 响应式拦截器
    $http.interceptors.response.use(res => res.data, e => {
        return Promise.reject(e)
    })
    
    // 默认导出
    export default $http
    

    2.在apis文件夹下创建 testAPI.js,用于封装请求接口具体路径等配置

    /* 用export导出,导入的时候要用解构赋值的形式接收 */

    import $http from '@/utils/http'
    
    export function getCategory(){
        return $http({
            url:'/jieyyds/selectAllMenu'
        })
    }
    

    3.组件中发送API请求测试

    <script setup>
    import { getCategory } from '@/apis/testAPI.js'
    import { onMounted } from 'vue'
    
    onMounted(async () => {
        const {data} = await getCategory();
        console.log(data);
    });
    </script>
    

3.0 axios跨域配置

  1. axios基础配置的baseURL中额外添加 ‘/api’ 路径,供代理拦截

    const $http = axios.create({
        baseURL:"http://localhost:5173/api", //后面额外添加api路径
        timeout:5000  //五秒
    })
    
  2. 在vite.config.js中添加代理配置,添加server结点

      server: {
        proxy: {
          // 请求路径含有'/api'就会触发代理
          '/api': {
            target: 'http://localhost:8080',
            changeOrigin: true,
            // 把路径中的/api更换成''
            rewrite: (path) => path.replace(/^\/api/, '') // 不可以省略rewrite
          }
        }
      }
    
  3. 在api中添加具体路径

    import $http from '@/utils/http'
    
    export function getCategory(){
        return $http({
            url:'/jieyyds/selectAllMenu'
        })
    }
    
  4. 组件就能正常发送请求了

    <script setup>
    import { getCategory } from '@/apis/testAPI.js'
    import { onMounted } from 'vue'
    
    onMounted(async () => {
        const {data} = await getCategory();
        console.log(data);
    });
    </script>
    

5.0 路由的基础配置

1.0 用npm安装路由

npm install vue-router

2.0 路由的基础配置

在router文件夹下的index.js中

// createRouter : 创建路由实例
// createWebHistory : 创建history模式的路由
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  //路由规则:路径 映射 组件,即path和component对应关系
  routes: [
    
  ]
})

export default router

3.0 将路由插件添加到Vue中

在main.js中添加路由插件

import router from '@/router/index'

const app = createApp(App)
app.use(router)
app.mount('#app')

4.0 设置路由出口

即组件占位符,html标签的形式

<RouterView />

5.0 区分一级路由与二级路由

一级路由:如果要页面整体切换,那么这个路由就是一级路由

二级路由:如果页面是局部切换,那么该路由是二级路由

6.0 快速上手 - 一级路由与二级路由

小案例:路由切换首页和登录页

  1. 新建一级路由组件: 登录页Login.vue 和 首页 index.vue

  2. 新建二级路由组件:家页home.vue 和 分类页 category.vue

  3. 添加一级路由和二级路由: 路径 和 组件的对应关系

    import { createRouter, createWebHistory } from 'vue-router'
    
    import Login from '@/views/Login/index.vue'
    import Layout from '@/views/Layout/index.vue'
    
    import Home from '@/views/Home/index.vue'
    import Category from '@/views/Category/index.vue'
    
    
    const router = createRouter({
      history: createWebHistory(import.meta.env.BASE_URL),
      routes: [
        {
          path:'/',
          component:Layout,
          // 二级路由
          children:[
            {
              // 默认就会显示该二级路由
              path:'',
              component:Home
            },
            {
              path:'category',
              component:Category
            }
          ]
        },
        {
          path:'/login',
          component:Login,
        },
      ]
    })
    
    export default router
    
  4. 添加一级路由出口 与 二级路由出口

    <RouterView />
    

6.0 静态资源的引入

静态资源:图片资源和样式资源

  • 图片资源:images文件夹放到 assets目录下
  • 样式资源:common.scss文件放到styles目录下

往往样式资源是需要样式重置的,可以使用开源的normalize.css库,或者手写。比如a的默认跳转,margin和padding的默认样式

引入初始化样式文件

  1. common.scss文件

    // 页面的整体公共样式
    //重置样式
    * {
        box-sizing: border-box;
      }
      
      html {
        height: 100%;
        font-size: 14px;
      }
      body {
        height: 100%;
        color: #333;
        min-width: 1240px;
        font: 1em/1.4 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI',
          'Hiragino Sans GB', 'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei',
          sans-serif;
      }
      body,
      ul,
      h1,
      h3,
      h4,
      p,
      dl,
      dd {
        padding: 0;
        margin: 0;
      }
      a {
        text-decoration: none;
        color: #333;
        outline: none;
      }
      i {
        font-style: normal;
      }
      input[type='text'],
      input[type='search'],
      input[type='password'],
      input[type='checkbox'] {
        padding: 0;
        outline: none;
        border: none;
        -webkit-appearance: none;
        &::placeholder {
          color: #ccc;
        }
      }
      img {
        max-width: 100%;
        max-height: 100%;
        vertical-align: middle;
        background: #ebebeb url('@/assets/images/200.png') no-repeat center / contain;
      }
      ul {
        list-style: none;
      }
      
      #app {
        // background: #f5f5f5;
        user-select: none;
      }
      
      .container {
        width: 1240px;
        margin: 0 auto;
        position: relative;
      }
      .ellipsis {
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
      }
      
      .ellipsis-2 {
        word-break: break-all;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        overflow: hidden;
      }
      
      .fl {
        float: left;
      }
      
      .fr {
        float: right;
      }
      
      .clearfix:after {
        content: '.';
        display: block;
        visibility: hidden;
        height: 0;
        line-height: 0;
        clear: both;
      }
      
      // reset element
      .el-breadcrumb__inner.is-link {
        font-weight: 400 !important;
      }
    

    2.在main.js中引入

    // 1.将默认导入的css注释掉
    // import './assets/main.css'
    
    // 2.更换我们的scss样式文件
    import '@/styles/common.scss'
    

7.0 scss文件的自动导入

首先在styles目录下创建样式文件,var.scss

$xtxColor: #27ba9b;
$helpColor: #e26237;
$sucColor: #1dc779;
$warnColor: #ffb302;
$priceColor: #cf4444;

1.0 自动导入的配置

在vite.config.js中添加自动导入scss文件的配置

  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `
          @use "@/styles/element/index.scss" as *;
          // 自动导入scss的文件
          @use "@/styles/var.scss" as *;
        `,
      }
    }
  }

2.0 组件中使用样式

scss相比css来说,是可以使用变量的

/* 自动导入的好处,就是免去了我们自己手动导入 var.scss文件*/

<template>
  <div class="text">text</div>
</template>

<style lang="scss">
  .text {
     color: $xtxColor;
  }
</style>

8.0 Pinia的基础配置

官方文档

官方文档:定义 Store | Pinia (vuejs.org)

概念

pinia是Vuex的代替品,是状态管理模式,是集中状态管理工具

在vue项目中,对应的文件夹是stores

1.0 pinia安装

npm install pinia

2.0 vue使用pinia插件

在main.js中

import { createPinia } from 'pinia'

const app = createApp(App)
app.use(createPinia())
app.mount('#app')

3.0 pinia的使用

pinia添加action和state

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
   // 类似vuex的state结点,负责存储全局数据的
  const count = ref(0)

  //定义getter 类似计算属性
  const doubleCount = computed(() => count.value * 2)

  // 类似vuex的action函数,负责修改store中的数据
  // 与vuex不同的是,pinia的action可执行同步和异步
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})

组件使用store

<script setup>
// 1. 导入获取实例的方法
import { useCounterStore } from "./stores/counter";

// 2. 获得counterStore实例对象
const counterStore = useCounterStore();
</script>

<template>
    <button @click="counterStore.increment">{{ counterStore.count }}</button>
</template>

4.0 pinia数据的响应式解构 storeToRefs函数

如果直接解构pinia的store数据,该数据的响应式就会丢失,函数action解构就没事,所以需要使用storeToRefs函数进行响应式解构。

/* 解构赋值:提高代码开发效率 */

import { storeToRefs } from "pinia";
import { useCounterStore } from "@/stores/counter";

// 实例化store
const counterStore = useCounterStore();
// 解构变量
const { count,doubleCount } = storeToRefs(counterStore)
// 解构函数
const { increment } = counterStore

<template>
   // 解构好处:无需通过counterStore.count
   {{count}}:{{doubleCount}}
</template>

9.0 基础篇

1.0 消息弹框的配置

  1. 获取弹框实例的函数 与 引入css

    import { ElMessage } from "element-plus";
    import "element-plus/theme-chalk/el-message.css";
    
  2. 使用弹框

    ElMessage({type:"success",message:"挂载成功"})
    

2.0 响应式函数ref与reactive

ref底层是reactive,他们两个底层是Proxy实现的。
一般ref是声明基本数据类型,reactive是声明对象或者数组的。
ref(1) => reactive({ value : 1 }),所以用ref声明的时候要加.value才能获取该数值。

import { reactive, ref } from "vue";

// 1. 响应式函数ref
const num = ref(0);
const obj = reactive({
  "name":"gjj",
  "age":18
})
const addNum = () => {
  num.value++;
};

3.0 计算属性

函数形式声明,但本质是属性。
属性的值是动态的,是随逻辑变化的,那么就定义在计算属性里

import { computed } from "vue";

const arr = ref([1,2,3,4,5,6])
const filterArr = computed(()=>{
  // 筛选数组,筛选后每一项都大于2
  return arr.value.filter(item => item > 2)
})

4.0 watch侦听器

侦听器:侦听属性的变化,只要属性发生了变化就会执行的一种函数

import { watch } from "vue";

const obj = ref({ count:0})
// 1. watch 监听一个属性,即obj
watch(obj,(newValue,oldValue)=>{
  console.log(`新的值${newValue};旧的值${oldValue}`);
},{
  //立即执行监听器,一进到页面就会先触发一次
  immediate:true,
  // 深度监听对象里面的属性
  // 深度监听deep,会造成性能损耗,一般用精度监听
  deep:true
}
)

const num = ref(0);
const  computedNum = computed(() => {
  return num.value + 2;
});

// 2. watch 监听多个属性,即num和computedNum
watch([num,computedNum],([newNum,newcomputedNum],[oldNum,oldcomputedNum])=>{
  console.log(`新的count${newNum}和新的计算属性${newcomputedNum}`); 
})

// 3. watch 精度监听
//    watch两个回调,一个是监听的属性,一个是处理函数
const obj1 = ref({ count:0,name:"gjj"})
watch(
  // 精度监听name属性(回调函数形式)
  ()=>{
  obj.value.name
},(newValue)=>{
  console.log('数据发生了变化');
})

5.0 组合式API生命函数

没有created和beforeCreate,新增setup,全部加前缀on,即onXXX
生命函数( 钩子函数 )的好处:1. 在指定的时机会自动调用 2. 可多次执行,代码是依次执行的

import { onMounted } from 'vue'

// 两句都会被执行,onMounted一般用于发送ajax请求
onMounted(()=>{
  console.log('onMounted被调用');
})
onMounted(()=>{
  console.log('onMounted被调用第二次');
})
  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值