Vue脚手架搭建项目+基础知识

1. 使用脚手架创建项目

1.1 准备工作

  •         win+R,在弹出的数据框中输入cmd,数据命令查看node以及npm版本 

  •         下载vue cli

1.2 创建项目

1.2.1 创建一个英文目录文件夹,cmd打开命令命令提示符

1.2.2 vue ui命令打开控制台

1.2.3 创建项目

        创建成功

 1.3 项目结构

1.4 将项目在VSCode打开,终端运行页面

         使用命令npm run serve命令打开

1.5 修改服务端口号

        在vue.config.js中修改服务端口号,防止与后端tomcat端口冲突

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

         保存文件,重启项目端口号修改完毕

2. vue基础回顾

2.1 文本插值

<template>
  <div class="hello">
    {{ name }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: 'I LOVE YOU'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.2 属性绑定

        为标签的属性绑定data方法中返回的属性

<template>
  <div class="hello">
    {{ name }}
    <input type="name" :value="age">
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: 'I LOVE YOU',
      age: 18
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.3 事件绑定

<template>
  <div class="hello">
    {{ name }}
    <input type="name" :value="age">

    <!-- 点击事件 -->
     <button @click="dianji()">点击</button>

  </div>
</template>

<script>
export default {
  data() {
    return {
      name: 'I LOVE YOU',
      age: 18
    }
  },
  methods: {
    dianji() {
      alert('点击了')
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.4 双向绑定

        通过v-model将数据区的数据与输入框数据双向绑定

<template>
  <div class="hello">
    {{ name }}
    <input type="name" :value="age">

    <!-- 点击事件 -->
     <button @click="dianji()">点击</button>
     <input type="text" v-model="name">

  </div>
</template>

<script>
export default {
  data() {
    return {
      name: 'I LOVE YOU',
      age: 18
    }
  },
  methods: {
    dianji() {
      alert('点击了')
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.5 条件渲染

<template>
  <div class="hello">
    <div v-if="sex==1">
      男
    </div>
    <div v-else-if="sex==2">
      女
    </div>
    <div v-else>
      未知
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      sex:2
    }
  },
  methods: {

  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.6 axios

        Axios是一个基于promise的网络请求库,作用于浏览器和node.js中,用于发ajax异步请求,实现前后端交互

2.6.1 下载axios

npm install axios

2.6.2 在项目中使用axios

2.6.3 axios的API

  • url:请求路径
  • data:请求体数据,最常见的是JSON格式
  • config:配置对象,可以设置查询参数,请求头信息

 2.6.4 axios请求的跨域问题

        正常情况下,前端数据一个服务,后端属于一个服务,在不同的域里,所以会出现跨域问题,解决方法就是在vue.config.js文件中配置代理

<template>

    <button @click="request11()"></button>

  </div>
</template>

<script>
// 导入axios
import axios from 'axios'

export default {
  data() {
    return {
      sex:2
    }
  },
  methods: {
    request11(){
      axios.post('http://localhost:8080/user/login',{
        username:'admin', // json数据
        password:'123456'
      }).then(res=>{ // 成功回调
        console.log(res.data)
      }).catch(err=>{ // 错误回调
        console.log(err)
      })
    }
  }
}
</script>
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    port: 7070,
    proxy:{
      // 配置请求代理,用于将特定请求转发到后端服务器,解决跨域问题
      '/api':{
        // 将请求转发到的目标服务器地址
        target:'http://localhost:8080',
        changeOrigin:true, // 是否更改请求的来源,通常用于处理虚拟主机的情况
        pathRewrite:{
          '^/api':'' // 移除请求路径中的 '/api' 前缀,以便目标服务器正确处理请求
        }
      }
    }
  }
})

2.6.5 发送请求

  • 方式一
<template>
  <div class="hello">
    <div v-if="sex==1">
      男
    </div>
    <div v-else-if="sex==2">
      女
    </div>
    <div v-else>
      未知
    </div>

    <button @click="request11()">按钮</button>

  </div>
</template>

<script>
// 导入axios
import axios from 'axios'

export default {
  data() {
    return {
      sex:2
    }
  },
  methods: {
    request11(){  
      axios.post('http://localhost:8080/user/login',{
        username:'admin', // json数据
        password:'123456'
      }).then(res=>{ // 成功回调
        console.log(res.data)
      }).catch(err=>{ // 错误回调
        console.log(err)
      })
    },
    req(){
      axios.get('http://localhost:8080/user/getUserById',{
        // 携带请求头
        headers:{
          token:'xxxxxxxxxxxxxxxxxxxxxxxxxx'
        }
      }).then(res=>{
        console.log(res.data)
      }).catch(err=>{
        console.log(err)
      })
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
  • 方式二
<button @click="handleSend()"></button>

handleSend(){
      axios({
        url:'http://localhost:8080/user/login',
        method:'post',
        data:{
          username:'admin',
          password:'<PASSWORD>'
        }
      }).then(res=>{
        console.log(res.data)
        axios({
          url:'http://localhost:8080/user/info',
          method:'get',
          headers:{
            token:res.data.data.token
          }
        })

      }).catch(err=>{
        console.log(err)
      })
    }

3. 路由Vue-Router

        vue属于单页面应用,路由的作用就是根据浏览器路径不同,用不同的视图组件替换掉这个页面内容。实现不同的路径,对应不同的页面展示

3.1 创建带有路由的项目

        创建好之后,package.json中有vue-router的依赖

        main.js中引入了router,说明这个项目具备了路由功能

3.2 路由配置

路由组成:

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

  • index.js中维护路由

  •  App.vue,<router-link>标签生成超链接

  • <router-view>:路由视图组件不能删掉!!!

       路由视图组件起到的是占位符的作用

3.3 路由跳转

有两种方式:

  • 标签式
  • 编程式

标签式就是上面演示的那种,编程式如下:

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>

      <input type="button" value="编程式跳转" @click="jump()">

    </nav>
    <!-- <router-view>:路由视图组件 -->
    <router-view/>
  </div>
</template>

<script>
export default {
  methods: {
    jump() {
      this.$router.push('/about')
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

        当用户输入的路径不对时,都会重定向到404页面,一张图告诉你如何重定向到不存在的页面:

4. 嵌套路由

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

4.1 案例

        以以下这个案例给大家分析:

实现步骤:

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

  • 下载

使用命令下载elementui:npm i element-ui -S

  • 在main.js中导入elementui
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 导入elementui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.config.productionTip = false
// 全局使用elementui
Vue.use(ElementUI);

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
  •  创建视图组件
<template>
    <el-container>
  <el-header>Header</el-header>
  <el-container>
    <el-aside width="200px">Aside</el-aside>
    <el-main>Main</el-main>
  </el-container>
</el-container>
</template>

<script>
export default {
  
}
</script>

<style>
  .el-header, .el-footer {
    background-color: #B3C0D1;
    color: #333;
    text-align: center;
    line-height: 60px;
  }
  
  .el-aside {
    background-color: #D3DCE6;
    color: #333;
    text-align: center;
    line-height: 200px;
  }
  
  .el-main {
    background-color: #E9EEF3;
    color: #333;
    text-align: center;
    line-height: 160px;
  }
  
  body > .el-container {
    margin-bottom: 40px;
  }
  
  .el-container:nth-child(5) .el-aside,
  .el-container:nth-child(6) .el-aside {
    line-height: 260px;
  }
  
  .el-container:nth-child(7) .el-aside {
    line-height: 320px;
  }
</style>
  • 在main.js中配置路由跳转

2)提供子视图组件,用于效果展示

  • P1View.vue
<template>
  <div>
    这是P1View
  </div>
</template>

<script>
export default {
  
}
</script>

<style>
</style>
  •  P2View.vue
<template>
  <div>
    这是P2View
  </div>
</template>

<script>
export default {
  
}
</script>

<style>
</style>
  •  P3View.vue
<template>
  <div>
    这是P3View
  </div>
</template>

<script>
export default {
  
}
</script>

<style>
</style>

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

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

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: '/test',
    component: () => import( '../views/404View.vue')
  },
  {
    path: '/c',
    component: () => import( '../views/container/containerView.vue'),
    // 重定向到p1
    redirect: '/c/p1',
    children:[
      {
        path: '/c/p1',
        component: () => import( '../views/container/P1View.vue')
      },
      {
        path: '/c/p2',
        component: () => import( '../views/container/P2View.vue')
      },
      {
        path: '/c/p3',
        component: () => import( '../views/container/P3View.vue')
      }
    ]
  },
  {
    path:"*",
    redirect: '/404'
  }
]

const router = new VueRouter({
  routes
})

export default router

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

<template>
    <el-container>
  <el-header>Header</el-header>
  <el-container>
    <el-aside width="200px">Aside</el-aside>
    <el-main>
      <!-- 占位符 -->
      <router-view/>
    </el-main>
  </el-container>
</el-container>
</template>

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

<template>
    <el-container>
  <el-header>Header</el-header>
  <el-container>
    <el-aside width="200px">
      <!-- 路由请求:生成超链接 -->
      <router-link to="/c/p1">P1</router-link><br>
      <router-link to="/c/p2">P2</router-link><br>
      <router-link to="/c/p3">P3</router-link>
    </el-aside>
    <el-main>
      <!-- 占位符 -->
      <router-view/>
    </el-main>
  </el-container>
</el-container>
</template>

<script>
export default {
  
}
</script>

<style>
  .el-header, .el-footer {
    background-color: #B3C0D1;
    color: #333;
    text-align: center;
    line-height: 60px;
  }
  
  .el-aside {
    background-color: #D3DCE6;
    color: #333;
    text-align: center;
    line-height: 200px;
  }
  
  .el-main {
    background-color: #E9EEF3;
    color: #333;
    text-align: center;
    line-height: 160px;
  }
  
  body > .el-container {
    margin-bottom: 40px;
  }
  
  .el-container:nth-child(5) .el-aside,
  .el-container:nth-child(6) .el-aside {
    line-height: 260px;
  }
  
  .el-container:nth-child(7) .el-aside {
    line-height: 320px;
  }
</style>

5. 状态管理vuex

5.1 介绍

  • vuex是一个专门为Vue.js应用程序开发的状态管理库
  • vuex可以在多个组件之间共享数据,并且共享的数据是响应式的,即数据的变更能即使渲染到模板
  • vuex采用集中式存储管理所有组件的状态

5.2 vuex核心概念

5.3 使用方式

5.3.1 创建携带vuex的项目

  • index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 集中管理多个组件共享的数据
export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})
  • main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store, // 创建vuex实例
  render: h => h(App)
}).$mount('#app')

5.3.2 定义展示共享数据

5.3.3 在mutations中定义函数,修改共享数据

5.3.4 在actions中定义函数,用于调用mutation

// import { set } from 'core-js/core/dict'
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

// 集中管理多个组件共享的数据
export default new Vuex.Store({
  // 共享数据
  state: {
    name:'未登录游客'
  },
  getters: {
  },
  // 修改共享数据只能通过mutation实现,必须是同步操作
  mutations: {
    setName(state, name){
      state.name = name
    }
  },
  // 封装异步操作,不能直接修改共享数据,只能通过mutation来实现
  actions: {
    setNameByAxios(context){
      axios({
        url:"/api/getUserInfo",
        method:"POST",
        data:{
          username:"admin",
          password:"123456"
        }
      }).then(res=>{
        if(res.data.code == 1){
          // 异步请求后,需要修改共享数据,只能通过mutation来实现
          // 在action中调用mutation中定义的setName方法
        context.commit("setName",res.data.username)
        }
      })
    }

  },
  modules: {
  }
})

       在vue.config.js 配置重定向

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 8081,
    proxy: {
      // 将含有/api的字段重定向成 http://localhost:8080
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        pathRewrite: {
          // 重写路径,将含有/api的字段替换成 (空)
          '^/api': ''
        }
      }
    }
  }
})

6. TypeScript

6.1 TypeScript介绍

  • TypeScript是微软推出的开源语言

  • TypeScript是JavaScript的超集(js有的ts都有)

  • TypeScript在js基础上做了类型支持

  • TypeScript文件扩展名为ts

  • TypeScript可编译成标准的JavaScript,并且在编译时进行类型检查

6.2 TypeScript常用类型

6.2.1 创建携带TypeScripe的项目

        类型标注的位置:

  • 标注变量
  • 标注参数
  • 标注返回值

6.2.2 字符串类型、数据类型、布尔类型

// 字符串类型
let str: string = 'I LOVE YOU 1314';

// 数字类型
let num: number = 1314;

// 布尔类型
let bool: boolean = true;

console.log(str, num, bool);

console.log("-------------------------");

// 字面量类型
function printTest(s:string,alignment:'left'|'center'|'right'){
    console.log(s,alignment)
}
// 调用函数
printTest('I LOVE YOU 1314','left');

console.log("-------------------------");


// interface 接口类型
interface Cat{
    name:string;
    // ? 可选属性
    age?:number;
}
// 定义变量,并且指定为Cat类型
const c1:Cat = {name:'Tom',age:10}
const c2:Cat = {name:'Tom'}

console.log("-------------------------");


// class类 - 基本使用
class User{
    name:string;
    constructor(name:string){
        this.name = name;
    }
    study(){
        console.log('I am '+this.name);
    }
}
// 使用User类型
const user = new User('Tom');

// 输出类中的属性
console.log(user.name);

// 调用类中的方法
user.study();

console.log("-------------------------");

// class类 - 实现接口
interface Animal{
    name:string;
    eat():void;
}

// 定义一个类实现Animal接口
class Bird implements Animal{
    name:string;
    constructor(name:string){
        this.name = name;
    }
    eat():void{
        console.log('I am eating');
    }
}
//  创建类型为Bird的对象
const bird = new Bird('小鸟');
console.log(bird.name);
bird.eat();


// class类 - 继承Bird类
class Parrot extends Bird{
    say(){
        console.log(this.name+' can say');
        
    }
}
const parrot = new Parrot('鹦鹉');
console.log(parrot.name);
parrot.eat();
parrot.say();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值