Vue学习记录

HTML、CSS JavaScript axios vue基础语法 Element Ul

Vue基础

Vue安装与配置

基于脚手架创建前端工程,其所需要的环境如下:

  • node.js 前端项目的运行环境,其作用类似于Java中的JDK
  • npm JavaScript的包管理工具(npm包含在node.js中)
  • Vue CLl 基于Vue进行快速开发的完整系统,实现交互式的项目脚手架

nodejs的安装目录下创建node_cachenode_global两个文件夹

随后在cmd中执行下面的命令,路径改为自己的

shell 复制代码
npm config set prefix "D:\softwares\nodejs\node_global"
shell 复制代码
npm config set cache "D:\softwares\nodejs\node_cache"

随后配置环境变量

全局安装最常用的 express 模块 进行测试,命令如下:

shell 复制代码
npm install express -g

设置淘宝镜像:

shell 复制代码
npm config set registry https://registry.npmmirror.com

利用npm安装Vue CLI,执行命令:

shell 复制代码
npm i @vue/cli -g

随后使用 Vue CLl 创建前端工程:

方式一:vue create 项目名称

方式二:vue ui

我们主要是以第二种方式为主:

之后在浏览器上打开这个地址:

Vue项目创建

我们进行创建即可:

随后选择版本,我们选择最新的Vue3

最后点击创建即可,这个过程可能需要等一些时间,生成的文件如下:

前端项目启动后,服务端口默认为8080,很容易和后端tomcat端口号冲突如何修改前端服务的端口号?

vue.config.js文件中做如下配置:

js 复制代码
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    port:7070
  }
})

Vue的组件以.vue结尾,每个组件由三个部分组成:

Vue的基本用法

Vue的文本插值

作用:用来绑定 data 方法返回的对象属性,用法:{``{}}

html 复制代码
<template>
  <div class="hello">
    <h1>{{ name }}</h1>
  </div>
</template>
<script>
export default {
  name: 'HelloWorld',
  data(){
    return {name:"鹏翔"}
  }
}
</script>

Vue的属性绑定

作用:为标签的属性绑定 data 方法中返回的属性,用法:v-bind:xxx,简写为:xxx,xxx即为属性名

html 复制代码
<template>
  <div class="hello">
    <h1>{{ name }}</h1>
    <div><input type="text" v-bind:value="name"></div>
    <div><input type="text" :value="age"></div>
    <div><img :src="img"></div>
  </div>
</template>
<script>
export default {
  name: 'HelloWorld',
  data(){
    return {
      name:"鹏翔",age:18,img:"/assets/logo.png"
    }
  }
}
</script>

Vue的事件绑定

作用:为元素绑定对应的事件简写为 @xxx,用法:v-on:xxxxxx是事件,如click

html 复制代码
<template>
  <div class="hello">
    <div><button @click="save()">保存</button></div>
    <div><button v-on:click="save()">保存</button></div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return {
      name:"鹏翔",age:18,img:"/assets/logo.png"
    }
  },
  methods:{
      save(){
        alert(this.name)
      }
  }
}
</script>

Vue的双向绑定

作用:表单输入项和 data 方法中的属性进行绑定,任意一方改变都会同步给另一方

用法:v-model

html 复制代码
<template>
  <div class="hello">
    <h1>{{ age }}</h1>
    <div><input type="text" v-bind:value="name"></div>
    <div><input type="text"  v-model="age"></div>
    <div><button @click="save()">保存</button></div>
    <div><button v-on:click="change()">改变</button></div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return {
      name:"鹏翔",age:18,img:"/assets/logo.png"
    }
  },
  methods:{
      save(){
        alert(this.name)
      },
      change(){
        this.age=19
      }
  }
}
</script>

Vue的条件渲染

作用:根据表达式的值来动态渲染页面元素用法:v-if、v-else、v-else-if

html 复制代码
<div v-if="0<age<18">未成年</div>
<div v-else-if="18<age<150">成年</div>
<div v-else>妖怪</div>

Vue的Axios

Axios 是一个基于 promise 的 网络请求库,作用于浏览器和 node.js 中,发送ajax异步请求

安装命令:

html 复制代码
npm install axios

VS-Code的控制台下面安装,报错,这是没有权限导致的,博主尝试修改cacheglobal两个文件夹属性的,但依旧不行。

其实最简单的方法就是将VS-Code关闭,然后以管理员身份运行就可以。

安装成功后,在package.joon文件下会自动导入我们安装的版本

导入命令:

js 复制代码
import axios from 'axios'

然而,我们在导入axios后却发生了报错:

'axios' is defined but never used"

这是由于这个变量axios没有定义的缘故,只需要在package.json中的eslintConfig配置中的rules中加上"no-unused-vars": "off",并重启服务即可。

ur:请求路径

data:请求体数据,最常见的是JSON格式数据

config:配置对象,可以设置查询参数、请求头信息

那么在做前后端分离项目时,我们的Vue项目是在7070的端口,而我们的后端项目在8080端口,这就涉及到请求跨域问题,如下面是通过axios发送post请求去登录:

js 复制代码
send(){
        axios.post("http://localhost:8080/admin/employee/login",
        {username:"admin",password:"123456"},
      ).then(res =>{
        console.log(res.data)
      }).catch(error =>{
        console.log(error.response)
      })
      }

此时前端F12调试台可以看到报错,Access-Control-Allow-Origin即说明发生了跨域问题

html 复制代码
Access to XMLHttpRequest at 'http://localhost:8080/admin/employee/login' from origin 'http://localhost:7070' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

该如何解决呢?可以通过代理来实现,即前端发送的请求先发给代理,随后代理再去转发。

POST方式请求

js 复制代码
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    port:7070,
    proxy:{
      '/api':{//发送的请求中由api做标识,这个随便起
        target:"http://localhost:8080",//转发的端口号
        pathRewrite:{
          "^/api":""//去掉请求中的api,其实可以认为是用api代替http://localhost:8080
        }
      }
    }
  }
})

此时的请求修改:

javascript 复制代码
send(){
        axios.post("/api/admin/employee/login",
        {username:"admin",password:"123456"},
      ).then(res =>{
        console.log(res.data)
      }).catch(error =>{
        console.log(error.response)
      })
      }

修改完后需要重启一下服务,随后运行,结果如下:

GET请求,此时报了401错误,这是由于JWT令牌验证导致的

随后我们定义一个Token,初始为空,先用Post请求获取token,后将该token作为配置传入Get方法中。

javascript 复制代码
<script>
import axios from 'axios'
var token=""
export default {
  name: 'HelloWorld',
  data(){
    return {
      name:"鹏翔",age:18,img:"/assets/logo.png"
    }
  },
  methods:{
      sendPost(){
        axios.post("/api/admin/employee/login",
        {username:"admin",password:"123456"},
      ).then(res =>{
        this.token=res.data.data.token
        console.log(res.data)
      }).catch(error =>{
        console.log(error.response)
      })
      },
      sendGet(){
        axios.get("/api/admin/workspace/businessData",
        {headers:{
          token:this.token
        }}
      ).then(res =>{
        console.log(this.token)
        console.log(res.data)
      })
      }
  }
}
</script>

统一请求方式,和AJAX很像

javascript 复制代码
sendCommon(){
        axios({
          url:"/api/admin/employee/login",
          method:"post",
          data:{username:"admin",password:"123456"},}
        ).then(res =>{
          axios({
          url:"/api/admin/workspace/businessData",
          method:"get",
          headers:{
            token:res.data.data.token
          }
          }).then(res=>{
            console.log(res.data)
          })
          }).catch(error =>{
        console.log(error.response)
      })   
    }}}

Vue-Router(路由配置)

vue 属于单页面应用,所谓的路由,就是根据浏览器路径不同,用不同的视图组件替换这个页面内容,即整个Vue中只有一个页面,切换不同路径就是调用不同组件来实现视觉上多个页面。

路由组成

路由组成:
VueRouter:路由器,根据路由请求在路由视图中动态渲染对应的视图组件
<router-link>:路由链接组件,浏览器会解析成
<router-view>:路由视图组件,用来展示与路由路径匹配的视图组件

路由表:

标签式视图

路由链接组件与占位组件

当我们将<router-view>删除后,他就找不到要渲染的位置:

编程式视图

那么要实现路由跳转,只能通过<router-link>的方式吗,事实上,这种方式称为标签式,而我们接下来介绍一种使用编程式跳转视图的方法,即通过js代码:

通过this.$router获得路由对象,通过push实现跳转

javascript 复制代码
<script>
export default{
  methods:{
    jump(){
        this.$router.push('/about')//这个路径不能瞎写,得是路由表里面配置的
    }
  }
}
</script>

点击按钮,即可实现跳转

重定向

404设置

那么该如何做呢?我们需要配置路由表

javascript 复制代码
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  },
  {
    path: '/404',
    component: () => import('../views/404View.vue')
  },
  {path:'/:pathMatch(.*)',redirect:'/404'}//表示上面的都匹配不上时执行这个,并重定向到404
]

嵌套路由

嵌套路由:组件内要切换内容,就需要用到嵌套路由(子路由)

实现步骤:

安装并导入 elementui,实现页面布局(Container布局容器)---ContainerView.vue

提供子视图组件,用于效果展示---P1View.vue、P2View.vue、P3View.vue

src/router/index.js 中配置路由映射规则(嵌套路由配置)

在布局容器视图中添加<router-view>,实现子视图组件展示

在布局容器视图中添加<router-link>,实现路由请求

接下来是具体实现:

安装并导入 elementui,实现页面布局(Container布局容器)---ContainerView.vue
Element-UI文档

博主按照要求使用下面的命令,却安装失败

shell 复制代码
npm i element-ui -S

报错,这个错误似乎是由于npm版本过高导致的

javascript 复制代码
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: skyrouter@0.1.0
npm ERR! Found: vue@3.4.23
npm ERR! node_modules/vue
npm ERR!   vue@"^3.2.13" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer vue@"^2.5.17" from element-ui@2.15.14
npm ERR! node_modules/element-ui
npm ERR!   element-ui@"*" from the root project

因此可以使用下面的命令来安装

shell 复制代码
npm install --legacy-peer-deps element-ui --save

随后在main.js中分别引入其jscss,同时使用Vue.use(ElementUI)告诉Vue要全局使用组件

javascript 复制代码
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

注意:

在使用vue的时候,使用一个全局变量,ESLint的语法会出现ESLint: 'vue' is not defined.

(no-undef),说变量未定义,这时我们可以添加配置,取消这个校验。在.eslintrc.js文件中添加一个配置,位置如下图所示,我的全局变量就是vue

需要注意的是,Vue3所使用的应该是Element-PLUS,其不支持Element-ui,因此需要使用:

javascript 复制代码
npm install element-plus --save

导入并使用的写法:

javascript 复制代码
import { createApp } from 'vue'
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(router),
app.use(ElementPlus),
app.mount('#app')

提供子视图组件,用于效果展示---userView.vue、orderView.vue、dishView.vue

src/router/index.js 中配置路由映射规则(嵌套路由配置)

javascript 复制代码
{
    path: '/main',
    name: 'main',
    component: () => import(/* webpackChunkName: "about" */ '../views/mainView.vue'),
    //嵌套路由(子路由),对应的组件会展示在当前组件内部
    redirect:"/main/user",
    children:[
      {
        path: '/main/order',
        component: () => import(/* webpackChunkName: "about" */ '../views/orderView.vue')
      },
      {
        path: '/main/user',
        component: () => import(/* webpackChunkName: "about" */ '../views/userView.vue')
      },
      {
        path: '/main/dish',
        component: () => import(/* webpackChunkName: "about" */ '../views/dishView.vue')
      },

    ]
  },

在布局容器视图中添加<router-view>,实现子视图组件展示

在布局容器视图中添加<router-link>,实现路由请求

html 复制代码
<template>
    <el-container>
  <el-header>Header</el-header>
  <el-container>
    <el-aside width="200px">
      <router-link to="/user">用户管理</router-link> <br>
      <router-link to="/dish">菜品管理</router-link> <br>
      <router-link to="/order">订单管理</router-link> <br>
    </el-aside>
    <el-main><router-view/></el-main>
  </el-container>
</el-container>
</template>

最终的实现效果

VueX状态管理

  1. vuex 是一个专为 Vue.js 应用程序开发的状态管理库
  2. vuex 可以在多个组件之间共享数据,并且共享的数据是响应式的,即数据的变更能及时渲染到模板
  3. vuex 采用集中式存储管理所有组件的状态
shell 复制代码
npm install vuex@next --save

核心概念

state:状态对象,集中定义各个组件共享的数据

mutations:类似于一个事件,用于修改共享数据,要求必须是同步函数

actions:类似于mutation,可以包含异步操作,通过调用mutation来改变共享数据

要想使用VueX功能,就需要创建具有VueX功能的脚手架。

创建完成后,我们发现多了一个store文件夹


那么如何使用 vuex?

state管理共享数据

store 对象的 state 属性中定义共享数据

javascript 复制代码
state: {
    name:"游客"
  },

全局调用:

javascript 复制代码
<h1>{{ $store.state.name }}</h1>

mutations 修改数据

store 对象的 mutations 属性中定义修改共享数据的函数(这个函数只能是同步的)

javascript 复制代码
//修改数据必须通过mutations
  mutations: {
    setName(state,name){
      state.name=name
    }
  }

随后调用时只能通过store对象的commit 方法调用:

javascript 复制代码
update(){
      this.$store.commit("setName","李四")//通过commit方法指定要执行的方法名和传入的参数
    },

actions 异步修改数据

store 对象的 actions 属性中定义调用 mutation 的函数,可以进行异步操作mutations 中的函数

javascript 复制代码
 actions: {
    sendAJAX(context){
      axios({
          url:"api/admin/employee/login",
          data:{
            username:"admin",
            password:"123456"
          },
          method:"post"
      }).then(res=>{
        if(res.data.code==1){
            context.commit("setName",res.data.data.name)
        }
      })
    }
  },

actions 中定义的函数不能直接调用,只能通过 store 对象的 dispatch方法调用:

javascript 复制代码
updateByAction(){
      this.$store.dispatch("sendAJAX")//通过dispatch方法指定要执行的action中方法
    }

TypeScript

TypeScript介绍

  • TypeScript(简称:TS)是微软推出的开源语言
  • TypeScript 是JavaScript 的超集(JS 有的 TS 都有)
  • TypeScript = Type +JavaScript(在JS 基础上增加了类型支持)
  • TypeScript 文件扩展名为 ts
  • TypeScript 可编译成标准的 JavaScript,并且在编译时进行类型检查


TS 为什么要增加类型支持 ?

  • TS 属于静态类型编程语言,JS 属于动态类型编程语言
  • 静态类型在编译期做类型检查,动态类型在执行期做类型检查
  • 对于 JS 来说,需要等到代码执行的时候才能发现错误(晚)
  • 对于 TS 来说,在代码编译的时候就可以发现错误(早)
  • 配合 VSCode 开发工具,TS 可以提前到在编写代码的同时就发现代码中的错误,减少找 Bug、改 Bug 的时间

如何理解 TypeScript ?

  • 是 JavaScript 的超集,兼容 JavaScript扩展了 JavaScript 的语法,文件扩展名为 ts可以编译成标准的
    JavaScript,并且可以在编译时进行类型检查
  • 全局安装npminstall- g typescript
  • 使用 tsc 命令将 ts 文件编译成 js 文件

TypeScript项目创建

重新手动配置一下,可以看到只是开发依赖中有TypeScript,这是由于我们在最终运行时都是编译为JS代码的,即运行时是不需要TypeScript依赖的

可以看到加入了TypeScript的代码以ts结尾


TypeScript入门案例

VS-Code下的命令窗口执行tsc命令报下面的错误

javascript 复制代码
tsc : 无法加载文件 D:\softwares\nodejs\node_global\tsc.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=
135170 中的 about_Execution_Policies。
所在位置 行:1 字符: 1
+ tsc .\test1.ts
+ ~~~
    + CategoryInfo          : SecurityError: (:) [],PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

解决方法,win+x打开管理员shell,然后执行命令set-ExecutionPolicy RemoteSigned,随后再在VS-Code的控制台运行就不报错了

编写的ts代码

javascript 复制代码
let username:string="李白"
let age:number=18
let isTrue:boolean=true
console.log(username)
console.log(age)
console.log(isTrue)

编译后的js代码

javascript 复制代码
var username = "李白";
var age = 18;
var isTrue = true;
console.log(username);
console.log(age);
console.log(isTrue);

字面量类型

指定参数只能取哪些值,作用类似于java中的枚举

因为我们设定参数只能接收字符类型的left或right,所以其他的会报错

利用node运行jsnode相当于Java中的JDK

接口类型

javascript 复制代码
//定义接口
interface Cat{
    name:string,
    age:number
}
//定义变量类型为Cat
const cat1:Cat={name:"小花",age:2}

编译后的js文件中是没有interface的,被擦除了

小技巧:

如果我们向要让接口中的参数有时需要传入,有时不需要传入呢,我们可以在变量后加一个即可

Class类

javascript 复制代码
class User{
    username:string;
    constructor(name:string){
        this.username=name
    }
    study(){
        console.log(this.username)
    }
}
let user:User=new User("鹏翔")//const代表必须在生成时就给定值,不能修改,let则可以修改
user.study()

编译后的js,将原本的类变为了方法,同时,无论是声明常量类型const还是变量类型let,编译为js后都是var

javascript 复制代码
var User = /** @class */ (function () {
    function User(name) {
        this.username = name;
    }
    User.prototype.study = function () {
        console.log(this.username);
    };
    return User;
}());
var user = new User("鹏翔");
user.study();

实现接口:

javascript 复制代码
interface Animal{
    name:string
    eat():void
}
class Bird implements Animal{
    name:string
    constructor(name:string){
        this.name=name
    }
    eat(){
        console.log(this.name+"在吃东西")
    }
}
const bird=new Bird("燕子")
bird.eat()

class的继承

javascript 复制代码
interface Animal{
    name:string
    eat():void
}
class Bird implements Animal{
    name:string
    constructor(name:string){
        this.name=name
    }
    eat(){
        console.log(this.name+"在吃东西")
    }
}
const bird=new Bird("燕子")
bird.eat()
class Parrot extends Bird{
    say(name:string):void{
        console.log(name+"说你好")
    }
}
const parrot=new Parrot("鹦鹉")
parrot.say("鹦鹉")
相关推荐
阿珊和她的猫26 分钟前
v-scale-scree: 根据屏幕尺寸缩放内容
开发语言·前端·javascript
_Kayo_2 小时前
node.js 学习笔记3 HTTP
笔记·学习
加班是不可能的,除非双倍日工资5 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi5 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
CCCC13101635 小时前
嵌入式学习(day 28)线程
jvm·学习
gnip6 小时前
vite和webpack打包结构控制
前端·javascript
excel6 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
星星火柴9366 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
小狗爱吃黄桃罐头6 小时前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
阿华的代码王国6 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端