课程地址:Vue3.0项目实战2021|Vue差异化对比+实操公司后台管理系统|零基础入门前端开发教程(C#/.Net/Vue基础/Vue3技术入门讲解/Vue实战)_哔哩哔哩_bilibili  https://www.bilibili.com/video/BV17V411j76p?p=1

ElementUI从入门到实战【升职加薪,只争朝夕】-学习视频教程-腾讯课堂  https://ke.qq.com/course/3547529

零.开篇介绍

Vue3  vs Vue2

Vue-cli构建Vue3项目

初尝Vue3 compositon Api

实战Element-plus + Axios +Vue3

一.Vue运行环境安装,为什么需要安装运行环境

预装环境 :node v8+

为什么需要运行环境   VUE项目==文件类型是.vue他是需要被编译成.js文件,才可以被浏览器识别 安装复杂度      一键安装 会不会增加学习成本       我们只是运用node环境,不需要单独学习

安装node环境 下载 | Node.js 中文网  http://nodejs.cn/download/

查看node版本: node –v  

此次课程Vue3需要node 版本8以上

二.npm镜像安装

 npm 是node内置的资源管理器  

查看npm版本: npm -v  npm

镜像:   淘宝npm镜像     registry地址:http://registry.npm.taobao.org/

               cnpmjs镜像       registry地址:http://registry.cnpmjs.org/

设置镜像源:npm config set registry  地址

查看镜像源: npm config get registry

三.VueCli脚手架安装

安装Vue-cli   npm install -g @vue/cli  

-g全局

 四.使用Vue-Cli构建Vue3项目

Vue CLI 和 Vue的区别

脚手架是一个基于 Vue.js 进行快速开发的完整系统,通过@vue/cli 实现快速搭建标准化项目的脚手架  

Vue的版本和VueCLI的版本的关系

Vue版本不受脚手架版本的影响 使用VueCLI构建项目过程,可以根据需求选择相应版本的Vue

查看VueCLI版本号:  vue -v

五.使用Vue-Cli构建Vue3项目

在项目文件下下运行命令:  vue creatre 项目名

 

 六.Vue3与Vue2 main.js对比

七.Vue3生命周期变化以及setup函数

 与 2.x 版本生命周期相对应的组合式 API

1.beforeCreate -> 使用 setup()

2.created -> 使用 setup()

3.beforeMount -> onBeforeMount

4.mounted -> onMounted

5.beforeUpdate -> onBeforeUpdate

6.updated -> onUpdated

7.beforeDestroy -> onBeforeUnmount

8.destroyed -> onUnmounted

9.errorCaptured -> onErrorCaptured

onRenderTracked  检查依赖被追踪。当render函数被调用时,会检查哪个响应式数据被收集依赖 onRenderTriggered 当执行update操作时,会检查哪个响应式数据导致组件重新渲染。

setup是compositon Api在Vue3中的入口

beforeCreate和created会在setup中执行

无法使用this拿到当前组件的相关数据 setup只能同步执行,不可以异步

 八.ref,reactive响应式api

reactive与ref

被响应式api标记过的数据才可以成为响应式数据

ref--用来标记简单类型数据

reactive—标记复杂类型数据(深度响应式)

如果用ref对象/数组, 会自动将对象/数组转换为reactive的代理对象

ref的数据操作: 在js中要.value, 在模板中不需要(内部解析会自动添加.value)

 九.Element-plus引入

使用cli安装 vue add element-plus

Element Plus - The world's most popular Vue 3 UI framework
 https://element-plus.gitee.io/#/zh-CN

 组件 | Element  https://element-plus.gitee.io/#/zh-CN/component/installation

十.引入http请求框架axios

安装 axios http请求框架 npm install axios

 axios基本使用:

 十一.封装axios

1.axios基础使用

axios基础使用方法:

axios.create({config})   //创建axios实例

axios.get(url,{config})   //get请求

axios.post(url, data,{config})           //post请求

axios.interceptors.request.use()     // 请求拦截器

axios.interceptors.response.use()  // 请求拦截器

具体看下面文档

axios中文文档|axios中文网 | axios  http://www.axios-js.com/zh-cn/docs/

http/index.js

import axios from 'axios'
//axios.create 创建一个axios实例  我们给这个实例编写配置,后续所有通过实例发送的请求,都受当前配置约束
const $http = axios.create({
    baseURL: '',
    timeout: 1000,
    // headers: {'X-Custom-Header': 'foobar'}
  });

  // 添加请求拦截器
  $http.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    config.headers.token='123123123'
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
$http.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    let data=response.data;
    
    return data;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

  export default $http

http/api.js

import $http from './index.js'

export const getCourseList= (data)=>{
    return $http.get('http://jsonplaceholder.typicode.com/posts',data)
}

export const login=(data)=>{
    return $http.get('http://jsonplaceholder.typicode.com/posts',data)
}

 //views/login.vue 调用

<template>
  <div class="login">
    <h4>朝夕后台管理系统</h4>
    <el-form
      label-width="80px"
      :model="loginData"
    >
      <el-form-item label="账号">
        <el-input placeholder="请输入账号" v-model="loginData.name"></el-input>
      </el-form-item>
      <el-form-item label="密码">
        <el-input placeholder="请输入密码" v-model="loginData.password" show-password></el-input>
      </el-form-item>
       <el-form-item>
          <el-button @click="subFun" class="sub-btn" type="primary">登录</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
import {reactive } from 'vue'
 import { ElMessage } from 'element-plus'
 import {login} from '../http/api.js'
 import router from '../router/index.js'
export default {
  name: "Login",
  setup() {
      let loginData=reactive({
        name:'',
        password:''
      })

      let subFun =()=>{
        //先判断账号密码是否已经填写
          if(!loginData.name||!loginData.password){
              ElMessage.error('请先填写账号和密码');
              return
          }

          login(loginData).then(res=>{
            console.log(res)
            router.push('/Home')
          })

      }
      return{
        loginData,
        subFun
      }
  },
};
</script>
<style scoped>
.login{
  width: 500px;
  margin: 150px auto;
  border:1px solid #efefef;
  border-radius: 10px;
  padding:20px
}
h4{
  text-align: center;
}
.sub-btn{
  width: 100%;
}
</style>

 2.axios跨域处理

什么是跨域

 配置跨域请求

①项目根目录创建vue.config.js

②写入devServe配置

③解析devServe配置

十二.Vue路由

1.1 前端路由

路由是SPA(单页应用)的路径管理器   是建立起url和页面之间的映射关系

前端路由模式

① Hash模式    通过 URL 的 hash 来模拟一个完整的 URL于是当 URL 改变时,页面不会重新加载 ② History模式 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 修改浏览器的历史记录栈

 1.2 Vue-router路由配置

 1.3 子路由

import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Login from '../views/login.vue'

const routes = [
  {
    path: '/Home',
    name: 'Home',
    component: Home,
    meta:{
      isShow:false,
    },
    children:[
      {
        path: '/courseList',
        name: 'CourseListin',
        meta:{
          isShow:true,
          title:'课程列表'
        },
        component: () => import(/* webpackChunkName: "login" */ '../views/courseList.vue')
      },
      {
        path: '/teacherList',
        name: 'TeacherList',
        meta:{
          isShow:true,
          title:'讲师列表'
        },
        component: () => import(/* webpackChunkName: "login" */ '../views/teacherList.vue')
      },
      {
        path: '/personal',
        name: 'Personal',
        meta:{
          isShow:true,
          title:'个人中心'
        },
        component: () => import(/* webpackChunkName: "login" */ '../views/personal.vue')
      }
    ]
  },
  {
    path: '/',
    name: 'Login',
    component: Login,
    meta:{
      isShow:false,
    }
  },
 
]

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

export default router

1.4路由调优

路由调优方案

①路由拆分        项目体积变大,路由臃肿,可读性差,按业务剥离降低耦合,提升可维护性

②路由懒加载     编译体积变小,增加页面运行速度     

 路由拆分    

1.  按业务拆分路由    

2.  根据拆分创建多个路由数据源  

3.  在index.js页面进行路由整合

 路由懒加载的意义          

         Vue项目编译最后是一个html空白页面和若干个js文件,路由拆分把开发环境的js文件拆成多个js文件, 懒加载则是把编译后的路由文件拆成多个,按需加载。

①更改路由配置方式

②解析配置

 1.5 路由传参

通过<router-link> 标签  

  <router-link :to="{name:xxx,params:{key:value}}">valueString</router-link> //$route.params.key 

url传参

   path:'/params/:newsId/:newsTitle',  //$route.params.newsId  

query传参

   { name:'xxx',query: { queryId:  status }} //$route.query.queryId

十三.Vuex全局状态

Vuex

 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化

状态管理的意义

  • 单一数据源确保数据对象独立
  • 数据保持和Vue一样的响应式
  • 数据操作隔离确保数据安全
  • 全局数据共享确保数据可传播性

 Vuex 数据操作流程

1.state     应用层级的状态应该集中到单个 store 对象中

2. mutation     更改状态的唯一方法,并且这个过程是同步的

3. action      异步逻辑都应该封装到 action 里面

 十四.Vue3 vs Vue2

  1. 速度更快 1.5-2倍    1.1、编译速度         1.2、运行速度         1.3、计算(效率)速度
  2. 体积减少  体积减少    tree-shaking  webpack插件 vue2 130.01k vue3 113.37k
  3. 更易维护  compositon Api (增加)
  4. 原生支持度更高             使用Proxy(对象拦截)代替Object.defineProperty(数据劫持)                                                      Proxy:ES6原生语法

 

十五.首页布局实现

参考Element官网

<template>
  <div class="home">
    <el-container>
      <el-header class="top-box">
          <el-row :gutter="24">
          <el-col :span="18">
              <img class="logo" src="../assets/logo.png" alt="">
          </el-col>
          <el-col :span="6">
            <div class="info-box">
              <span>Tina</span>
              <el-button class="out-btn" type="text">退出</el-button>
            </div>
          </el-col>
        </el-row>
        </el-header>
      <el-container>
        <el-aside width="200px">
            <el-menu
             router='true'
              class="el-menu-vertical-demo">
              <el-menu-item :route="i.path" v-for="i in tabList" :key="i.name" :index="i.name">
                <!-- <i class="el-icon-document"></i> -->
                <template #title>{{i.meta.title}}</template>
              </el-menu-item>
              
            </el-menu>
        </el-aside>
        <el-main>
          <div class="content-box">
            <router-view/>
          </div>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
// @ is an alias to /src
// import {reactive} from "vue";
import router from "../router/index";
export default {
  name: "Home",
  setup() {
    let tabList = router.options.routes[0].children;
    return {
      tabList,
    };
  },
};
</script>
<style lang="scss" scoped>
.top-box {
  background: #efefef;
  padding: 5px;
  .logo {
    width: 50px;
  }
  .info-box {
    text-align: right;
  }
  .out-btn {
    margin-left: 10px;
  }
}
.content-box{
  padding:20px;
}
</style>

十六.课程列表及分页

<template>
  <div class="select-box">
    <div>
      <span>id:</span>
      <el-select v-model="option.id" placeholder="请选择id">
        <el-option
          v-for="item in [1,2,3,4,5,6,7]"
          :key="item"
          :label="item"
          :value="item"
        >
        </el-option>
      </el-select>
    </div>
    <div>
      <span>标题:</span>
     <el-input v-model="option.title" placeholder="请输入标题"></el-input>
    </div>
     <div>
    <el-button @click="getTabList" type="primary">查询</el-button>
  </div>
  </div>
 
  <el-table border :data="data.table[option.page]" style="width: 100%">
    <el-table-column prop="title" label="标题"> </el-table-column>
    <el-table-column prop="body" label="内容"> </el-table-column>
    <el-table-column prop="id" label="id"> </el-table-column>
  </el-table>
  <el-pagination
    @current-change="handleCurrentChange"
    :current-page="data.page"
    layout="total, prev, pager, next, jumper"
    :total="data.total"
  >
  </el-pagination>
</template>

<script>
import { reactive } from "vue";
import { getCourseList } from "../http/api";
export default {
  name: "CourseList",
  setup() {
    let data = reactive({
      table: [],
      psages: 0,
      total: 0,
    });

  let option=reactive({
    id:'',
    title:'',
    page: 0,

  })

    let getCourseListFun = async (obj) => {
      let arr = await getCourseList(obj),
        newArr = [];
      data.total = arr.length;
      //   [1,2,3,4,5,6,7]   [10,11,12----100]
      //   [[1,2],[3,4],[5,6],[7]]
      //split(index,10)==[0-10]
      for (let index = 0; index < arr.length; index++) {
        let obj = arr.splice(index, 10);
        newArr.push(obj);
        index += 10;
      }
      data.table = newArr;
    };
    getCourseListFun();

    let handleCurrentChange = (index) => {
      option.page = index;
      // getCourseListFun({page:data.page})
    };

    let getTabList=()=>{
         console.log(option) 
    }

    return {
      data,
      handleCurrentChange,
      getTabList,
      option
    };
  },
};
</script>
<style lang="scss" scoped>
  .select-box{
       display: flex;
      align-items: center;
      width: 100%;
      margin-bottom: 10px;
    >div{
      margin-right: 10px;
      width: 30%;
      display: flex;
      align-items: center;
      span{
        width: 50px;
      }

    }
  }
</style>

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐