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("鹦鹉")
相关推荐
学不会•1 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
活宝小娜3 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点3 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow3 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o3 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic4 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā4 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
朝九晚五ฺ5 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
沉默璇年6 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder6 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript