Bootstrap

Java小记-Vue/ElementUI/Axios(超级无敌认真好用,万字收藏篇!!!!)

Vue/ElementUI/Axios

前言

  • 由于本人所学的是后端开发,因此该笔记所涉及到的内容很基础,很浅,后续学习过程中,该笔记会持续更新…

1 Vue简介

VUE是一款渐进式前端框架:易学易用,性能出色,适用场景丰富的 Web 前端框架。

  • 易学易用:基于标准 HTML、CSS 和 JavaScript 构建,提供容易上手的 API 和一流的文档。
  • 性能出色:经过编译器优化、完全响应式的渲染系统,几乎不需要手动优化。
  • 灵活多变:丰富的、可渐进式集成的生态系统,可以根据应用规模在库和框架间切换自如。

  • VUE是一款由数据驱动视图的前端框架,它基于MVVM(Model View View Model)模式,实现数据与

    视图的双向绑定。

  • MVVM(Model View View Model):Model表示数据模型,View表示视图,指由数据驱动视图

    简单来说,就是数据变化的时候, 页面会自动刷新, 页面变化的时候,数据也会自动变化.

  • VUE是渐进式框架,VUE提供了一个核心库,用于渲染视图,它占空间小,能完成VUE中的常规基

    础操作。同样VUE根据需求不同还提供多个插件,以方便实现不同的功能。这种在核心库基础上可

    以根据需要递增使用不同的插件这种方式称为渐进式。

  • VUE在内存中构建DOM结构,并一次性进行渲染,在效率上要比jQuery这类操作DOM的库高很

    多,另外VUE让开发人员减少了DOM操作,使用起来要比jQuery类的库方便很多

2 Vue的安装

  • 三种方式:

    ①使用CDN方式(不推荐)

    基于互联网在线应用,本地无需下载vue的js文件,直接使用线上的

    使用 script 标签直接通过 CDN 来使用 Vue:

    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    

    这里我们使用了 unpkg,但你也可以使用任何提供 npm 包服务的 CDN,例如 jsdelivrcdnjs

    ②使用vue.js方式

    同上述方法,只是把的vue.js下载到本地使用

    ③使用npm方式安装(推荐)

    标准前端项目构建方式,需要搭建node环境

3 Vue的简单使用

  1. 下载vue.js文件

  2. 在HTML页面中引入 vue.js 文件

    <script src="../js/vue.js"></script>
    
  3. 创建Vue对象并设置相关属性

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="app">{{msg}}
    <button @click="test()">测试</button>
    </div>
    
    <!--引入vue.js文件-->
    <script src="../js/vue.global.js"></script>
    <script>
        const {createApp} =Vue;
        createApp({
            data() {//数据指定区,在该区域的数据vue可直接使用,等同于Java中属性
                return {
                    msg: 'hello vue'
                }
            },
            methods:{//其中存放各种方法
                //声明一个方法
                test(){
                    alert("你好")
                }
            }
            // template: "<h2>{{msg}}</h2>"
        }).mount("#app")//指定要渲染的元素,在指定的元素中才能使用vue
    
    </script>
    </body>
    </html>
    

4 Vue的指令

4.1 什么是Vue的指令

  • 在Vue的页面上提供一套便于页面和数据交互操作,这些操作叫指令,Vue所有指令都是以"v-xxx"表示
  • 每个vue完成一个功能,vue封装了一些DOM行为,不会经常使用DOM

4.2 Vue常用指令

  • v-text:等同于DOM中的innerText,向标签中写入文本,该指令和{{}}功能一样,使用较少

        <span v-text="msg"></span>
    
  • v-html:等同于DOM中的innerHTML,向标签中写入文本,该指令会对HTML进行解析执行

        <span v-html="msg"></span>
    
  • v-if:等同于JS中的if判断,当条件为true时显示页面内容,为false不显示

    • 条件可以为一个数据属性
        <span v-if="showMsg">v-if-test</span>
    
  • v-show:等同于v-if,但底层实现不同

        <span v-show="showMsg">v-show-test</span></br>
    

    v-if是"真正"的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁

    和重建。

    v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始

    渲染条件块

    相比之下,v-show就简单多了,它不管初始条件是什么,元素总是会被渲染,并且只是简单地基于

    CSS进行切换(通过修改display样式来进行显示或隐藏)

    一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要非常频繁地切

    换,则使用v-show较好;如果在运行时条件很少改变,则使用v-if较好

  • v-if-else:等同于JS中的elseif判断,当条件为true时显示条件块中的内容,v-else-if一般和v-if搭配使

        <span v-if="true">v-if</span>
        <span v-else-if="true">v-else-if</span>
    
  • v-else:等同于JS中else判断,当if条件不成立时自动显示else中的元素,v-else和v-if|或v-if-else搭配

    使用

        <span v-else>v-else</span>
    
  • v-on:事件绑定指令,如v-on:click=“方法”,一般使用简写方式@click=“方法”

    <button v-on:click="test">V-on</button>
    <button @click="test">V-on简写</button>
    
  • v-bind:绑定事件,将属性与事件绑定到一起,简写为:(单向绑定)

    	<input type="text" name="name" v-bind:value="url">
        <!--简写-->
        <input type="text" name="name" :value="url">
    
  • v-model:绑定事件,将属性与事件绑定到一起,,v-model只能在带有value属性的HTML元素中使用

        <input type="text" name="name" v-model="name">
        <input type="text" name="name" :value="name">
    
    • 客户端改变v-model的值,下面:value的值跟着改变

    • 客户端改变:value的值,上面v-model的值不变

  • v-for:遍历指令

    <!--
      遍历集合
      每次循环会将集合中的一个元素赋给str对象
     index表示循环的索引下标
    -->
    <ul>
          <li v-for="(str,index) in list">{{index}}--->{{str}}</li>
    </ul>
    

5 ElementUI

5.1 什么是ElementUI

  • ElementUI是一个UI框架,专门做界面视图
  • 内部使用(HTML+CSS+JS)进行界面封装

5.2 ElementUI的安装

  1. 基于npm的安装

    npm i element-ui -S
    
  2. 基于CDN的安装

    目前可以通过 unpkg.com/element-ui 获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用。

    <!-- 引入样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <!-- 引入组件库 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    

    不建议使用本地下载的方式,因为他不只是靠css写出来的,可能需要用到网上某些资源,因此建议使用在线的方式

5.3 ElementUI的基本使用

  1. Element是基于Vue的所以先引入Vue的JS文件
<!--引入vue的js文件-->
<script src="../js/vue.global.js"></script>
  1. 引入ElementUI
  • unpkg
<head>
  <!-- Import style -->
  <link rel="stylesheet" href="//unpkg.com/element-plus/dist/index.css" />
  <!-- Import Vue 3 -->
  <script src="//unpkg.com/vue@3"></script>
  <!-- Import component library -->
  <script src="//unpkg.com/element-plus"></script>
</head
  • jsDelivr
<head>
  <!-- Import style -->
  <link
    rel="stylesheet"
    href="//cdn.jsdelivr.net/npm/element-plus/dist/index.css"
  />
  <!-- Import Vue 3 -->
  <script src="//cdn.jsdelivr.net/npm/vue@3"></script>
  <!-- Import component library -->
  <script src="//cdn.jsdelivr.net/npm/element-plus"></script>
</head>
  1. 测试使用
<!DOCTYPE html>
<html lang="en">
<head>

    <meta charset="UTF-8">
    <title>Title</title>
    <!--引入vue的js文件-->
    <script src="../js/vue.global.js"></script>
    <!-- Import style -->
    <link rel="stylesheet" href="//unpkg.com/element-plus/dist/index.css"/>
    <!-- Import Vue 3 -->
    <script src="//unpkg.com/vue@3"></script>
    <!-- Import component library -->
    <script src="//unpkg.com/element-plus"></script>
</head>
<body>
<div id="app">
    <el-button type="success">Success</el-button>
</div>
<script>
    const App = {
        data() {

        }
    }
    const app = Vue.createApp(App);
    app.use(ElementPlus);
    app.mount("#app")
</script>
</body>
</html>

6 Axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

6.1 Axios特色

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

6.2 Axios的安装

  1. 基于npm的安装

    npm install axios
    
  2. 基于CDN的安装

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    
  3. 使用axios.js方式

    下载到本地使用

    <script src="../js/axios.min.js"></script>
    

6.3 Axios的简单使用

  1. 发送get请求

    • 前端代码如下
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <!--引入vue的js文件-->
        <script src="../js/vue.min.js"></script>
        <!-- 引入样式 -->
        <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
        <!-- 引入组件库 -->
        <script src="https://unpkg.com/element-ui/lib/index.js"></script>
        <script src="../js/axios.min.js"></script>
    </head>
    <body>
    <div id="app">
        <el-button type="primary" @click="demo01">访问服务端</el-button>
        <br/>
        <span>{{txt}}</span>
    </div>
    <script>
    
        new Vue({
            el: "#app",
            data() {
                return {
                    txt:'',
                }
            },
            methods: {
                demo01() {
                    axios.get('/axiosDemo/demo01')//向服务端发送get请求,参数为服务端地址
                        .then((response) => {//请求及响应成功执行的函数
                            //response表示服务端回传的响应信息,包含以下数据
                            //  1.服务器响应数据data
                            //  2.响应状态码:status=200
                            //  3.响应状态文本:statusText=ok
                            //  4.响应头信息:headers
                            //  5.相关配置:config
    
                            //    获得服务器回传数据
                            this.txt = response.data;
                        })
                        .catch((error) => {//请求或响应失败后执行的函数
                            //参数error表示的错误信息
                        })
                }
            }
    
        })
    </script>
    </body>
    </html>
    
    • controller层代码如下
    @RestController
    @RequestMapping("/axiosDemo")
    public class AxiosDemoController {
        @RequestMapping("/demo01")
          public String demo01(){
              return "demo01";
          }
    }
    

7 Vue+ElementUI+Axios综合应用小Demo

本案例是继承上一章节Java小记-SpringBoot(超级无敌认真好用,万字收藏篇!!!)的第三节小案例。。。

7.1 查看用户列表及页面规划

  1. 搭建VUE,ElementUI,Axios环境

        <!--引入vue的js文件-->
        <script src="./js/vue.min.js"></script>
        <!-- 引入样式 -->
        <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
        <!-- 引入组件库 -->
        <script src="https://unpkg.com/element-ui/lib/index.js"></script>
        <script src="./js/axios.min.js"></script>
    </head>
    
  2. 创建Vue对象并使用ElementUI做一个表格

    • slot-scop
    1. 在组件模板中书写所需slot插槽,并将当前组件的数据通过v-bind绑定在slot标签上。
    2. 在组件使用时,通过slot-scope=“scope”,接收组件中slot标签上绑定的数据。
    3. 通过scope.xxx就可以使用绑定数据了
    <div id="user_container">
        <div id="user_list">
            <el-table
                    :data="userList"
                    border
                    style="width: 100%">
                <el-table-column
                        align="center"
                        prop="userId"
                        label="用户编号"
                        width="180">
                </el-table-column>
                <el-table-column
                        align="center"
                        prop="username"
                        label="姓名"
                        width="180">
                </el-table-column>
                <el-table-column
                        align="center"
                        prop="sex"
                        label="性别"
                        width="180">
                    <template slot-scope="scope">
                    <span v-if="scope.row.sex==0"></span>
                    <span v-if="scope.row.sex==1"></span>
                    </template>
                </el-table-column>
                <el-table-column
                        align="center"
                        prop="date"
                        label="出生日期"
                        width="180">
                </el-table-column>
                <el-table-column
                        align="center"
                        prop="age"
                        label="年龄"
                        width="180">
                </el-table-column>
                <el-table-column
                        align="center"
                        prop="address"
                        label="地址">
                </el-table-column>
            </el-table>
        </div>
    </div>
    
  3. 定义如下数据类型

        new Vue({
            el: "#user_container",
            data() {
                return {
                    userList: [{
                        userId: '',
                        username: '',
                        sex: '',
                        date: '',
                        age: '',
                        address: ''
                    }],
                }
            },
            methods: {
            }
        })
    
  4. 响应客户端数据并在页面上展示

    钩子函数:页面展示之前执行

    Vue函数创建后自动执行的函数,可以在该函数中调用ajax请求Vue函数创建后自动执行的函数,可以在该函数中调用ajax请求

    mounted(): 在模板渲染成html前调用,即通常初始化某些属性值,例如data中的数据,然后再渲染成视图。

    created(): 在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

    <script>
            methods: {
                loadUserList() {//加载商品列表
                    axios.get("/user/selectUser")
                        .then(response => {
                            //赋值
                            this.userList = response.data;
                        })
                        .catch(error => {
                               alter(error)
                        })
                }
            },
            created() {//Vue函数创建后自动执行的函数,可以在该函数中调用ajax请求
                this.loadUserList();
            }
    </script>
    

7.2 添加用户信息

在数据库中存储数据为数字,而前端显示界面需要进行字符串类型展示
如在编辑页面需要回显数据,该如何进行转换呢?

  1. from表单如下 :
<div class="addUser">
    <el-dialog title="注册用户" :visible.sync="dialogFormVisible">
      <el-form :model="user">
        <el-form-item label="用户姓名:" :label-width="formLabelWidth">
           <el-input v-model="user.name" autocomplete="off"></el-input>
        </el-form-item>
      <el-form-item label="用户性别:" :label-width="formLabelWidth">
         <el-select v-model="user.sex" placeholder="请选择性别">
           <el-option v-for="(item,key) in sexs" :key="key" :label="item.label" :value="key">
           </el-option>
         </el-select>
      </el-form-item>
      <el-form-item label="用户出生日期:" :label-width="formLabelWidth">
         <el-date-picker v-model="user.date"  type="datetime" placeholder="选择日期时间">
         </el-date-picker>
      </el-form-item>
      <el-form-item label="用户年龄:" :label-width="formLabelWidth">
         <el-input v-model="user.age" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="用户地址:" :label-width="formLabelWidth">
         <el-input v-model="user.address" autocomplete="off"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible = false">取 消</el-button>
      <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
     </div>
  </el-dialog>
</div>
  1. 继续定义如下数据类型
 data() {
      return {
        dialogFormVisible: false,
        dialogTableVisible: false,
        user: {
            userId: '',
            username: '',
            sex: '',
            date: '',
            age: '',
            address: '',                         
        sexs: [{
          value: '1',
          label: '男'
        }, {
          value: '0',
          label: '女'
        }],
}
}
  1. 客户端请求到服务端

payload:请求体里的附加信息,一般都用json处理

@RequestBody可接受payload消息

addUser(){
     axios.post("user/addUser", this.user)
          .then(response => {
               if (response.data.success) {
                  //弹出消息提示成功
                  this.open2()
                } else {
                  //失败
                  this.open4()
                }
           })
           .catch(err => {
                  alert(err)
           })
},
open2() {
      this.$message({
         message: '恭喜你,这是一条成功消息',
         type: 'success',
         duration: 1000,//设置自动关闭延迟时间
         onClose: () => {
            this.dialogFormVisible = false//设置弹出框关闭
            this.user = {}//情况对象中的数据
            this.loadUserList();
         }
       });
},
open4() {
      this.$message.error('错了哦,这是一条错误消息');
        }
}
  1. 服务端处理
  • controller层处理

        @RequestMapping("/addUser")
        public Result addUser(@RequestBody User user) {
            try {
                userService.addUser(user);
                return Result.success("用户添加成功");
            } catch (Exception e) {
                e.printStackTrace();
                return Result.success(500,"商品添加失败");
            }
        }
    
  • commons里的结果处理类

    @Getter
    /**
     * 结果处理类
     */
    public class Result {
    
        private Boolean success;//成功(true),失败(false)
        private Integer statusCode;//状态码
        private String message;//消息
        private Object data;//附加数据
    
        /**
         * 成功
         * @return
         */
        public static Result success() {
           return new Result(true,200,null,null);
        }
        /**
         * 成功-带有消息
         * @return
         */
        public static Result success(String message) {
            return new Result(true,200,message,null);
        }
        /**
         * 成功-带有消息和附加数据
         * @return
         */
        public static Result success(String message,Object data) {
            return new Result(true,200,message,data);
        }
        /**
         * 成功-带有附加数据
         * @return
         */
        public static Result success(Object data) {
            return new Result(true,200,null,data);
        }
    
        /**
         * 成功
         * @return
         */
        public static Result success(int statusCode) {
            return new Result(false,statusCode,null,null);
        }
        /**
         * 成功-带有消息
         * @return
         */
        public static Result success(int statusCode,String message) {
            return new Result(false,statusCode,message,null);
        }
        /**
         * 成功-带有消息和附加数据
         * @return
         */
        public static Result success(int statusCode,String message,Object data) {
            return new Result(false,statusCode,message,data);
        }
        /**
         * 成功-带有消息和附加数据
         * @return
         */
        public static Result success(int statusCode,Object data) {
            return new Result(false,statusCode,null,data);
        }
    
        private Result(Boolean success, Integer statusCode, String message, Object data) {
            this.success = success;
            this.statusCode = statusCode;
            this.message=message;
            this.data=data;
        }
    }
    

7.3 修改用户信息

  1. 修改商品使用原来的表单使用的按钮和加入的信息需要选择
<span v-if="addUserStatus"></span>
<span v-else>
  <el-form-item label="用户编号:" :label-width="formLabelWidth">
    <el-input v-model="user.userId" autocomplete="off" :disabled="true"></el-input>
  </el-form-item>
</span>
<el-button type="primary" @click="addUser" v-if="addUserStatus">确 定</el-button>
<el-button type="primary" @click="updateUser" v-else>确 定</el-button>
  1. 继续定义如下数据
data() {
    return {
        titleText: "",
        addUserStatus: false,
         }
     } 
  1. 增加和修改功能所使用的方法

resfull:

  • 从服务端获取数据,get请求
  • 从服务端推送数据,post请求
  • 修改服务端数据,put请求
  • 从服务端删除数据,delete请求
           clear() {
                this.user.userId = null,
                this.user.username = null,
                this.user.sex = null,
                this.user.date = null,
                this.user.age = null,
                this.user.address = null
            },
            /**
             * 展示增加表单
             */
            showAddUser() {
                this.clear();//清空对象中的数据
                this.titleText = "用户注册";
                this.addUserStatus = true;
                this.dialogFormVisible = true;
            },
            /**
             * 更新用户
             */
            updateUser() {
                axios.put("user/updateUserById", this.user)
                    .then(response => {
                        if (response.data) {//如果修改成功
                            this.open2();
                        } else {
                            this.open4();
                        }
                    })
                    .catch(err => {
                        alert(err)
                    })
            },
            /**
             * 展示当前行数据
             * @param row :当前行数据对象
             */
            showUpdate(row) {
                this.clear();//清空对象中的数据
                this.addUserStatus = false;
                this.titleText = "修改信息";
                this.fillUser(row)
                this.dialogFormVisible = true
            },
            /**
             * 填充修改框中的数据
             * @param row
             */
            fillUser(row) {
                this.user.userId = row.userId;
                this.user.username = row.username;
                this.user.sex = row.sex;
                this.user.date = row.date;
                this.user.age = row.age;
                this.user.address = row.address
            }
        }

7.4 删除用户

  1. 增加多删和单删按钮
<!--单删按钮-->
<el-button type="danger" size="mini" plain icon="el-icon-edit-outline"
            @click="aloneDelete(scope.row.userId,scope.row.username)">删除
</el-button>
<!--多删按钮-->
<el-button type="danger" @click="batchDelete">批量删除</el-button>
  1. 继续定义如下数据
data() {
      return {
			userIds: []//要删除商品的编号
      }
  1. 删除功能所使用的方法

如果参数为数组,则使用Qs.stringify(jsonObj,{indices:false})去掉数组参数名后的[]

  • 引入qs.js库

    qs是一个url参数转化(parse和stringify)的js库。

    <script src="./js/qs.js"></script>
  • 使用qs.js去掉数组后的[]
axios.delete("user/deleteUserById", {
                    params: {
                        userIds: this.userIds
                    },
                    paramsSerializer: {
                        serialize: params => {
                            return Qs.stringify(params, {indices:false})
                        }
                    }
                })
  • 删除使用的方法
            /**
             * 复选框改变函数
             * @param selection:复选框选中的行元素数组
             */
            selectHandler(selection) {
                //每次加之前清除userIds中的内容
                this.userIds = [];
                //获得selection选中行的商品编号,并转存到userIds中
                for (user of selection) {
                    this.userIds.push(user.userId)
                }
            },
            /**
             * 批量删除用户
             */
            batchDelete(userId) {
                //是否存在要删除的数据
                if (this.userIds == 0) {
                    this.$message.error('请选择要删除的用户');
                    return;
                }
                //确认删除
                this.$confirm('请确认删除选定用户? 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.deleteUser()
                })
            },
            /**
             * 单独删除用户
             */
            aloneDelete(userId, username) {
                this.userIds = [];
                this.$confirm('请确认删除用户:<' + username + ',> 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.userIds.push(userId);
                    this.deleteUser()
                })
            },
            deleteUser() {
                axios.delete("user/deleteUserById", {
                    params: {
                        userIds: this.userIds
                    },
                    paramsSerializer: {
                        serialize: params => {
                            return Qs.stringify(params, {indices:false})
                        }
                    }
                }).then(response => {
                    if (response.data) {
                        this.$message({
                            message: '恭喜你,这是一条成功消息',
                            type: 'success',
                            duration: 1000,//设置自动关闭延迟时间
                            onClose: () => {
                                this.loadUserList();
                                this.userIds=[];
                            }
                        })
                    } else {
                        this.open4()
                    }
                }).catch(error => {
                    alert(error)
                })
            },

8 VUE-CLI

ps:之前我们的项目虽然是前端写在html里后端在java里,看似实现了前后端分离但严格来讲并不是前后端分离,Vue-CLI是一个构建独立前端应用的脚手架,Vite也是一个基于Vue构建独立前端应用的脚手架,2022年后半年推出。。。

  • 服务端项目:

    ①接受前端传入的数据(请求)

    ②功能处理

    ③将处理结果回传给前端应用

  • 前端项目:

    ①向服务端发送请求

    ②获取服务端传入的数据

    ③构建页面

    ④少部分业务

8.1 使用Vue-cli构建前端应用

Vue-CLI:Vue脚手架

基于Vue-CLI构建前端项目

Vue-CLI基于node环境构建,下载node.js

node安装后,会自动将npm装入系统中

npm:前端库,他和maven类似,在npm中存放了大量前端开发所需要的库

npm在外国,为了方便使用我们可以使用国内镜像,需要安装cnpm

cnpm安装命令npm install -g cnpm --registry=https://registry.npm.taobao.org

安装VUE-CLI :npm install -g @vue/cli

  • 使用Vue-cli创建前端应用

    ① 基于DOS创建(推荐)

    1. 创建项目

    vue create

    运行vue create hello-world命令

    进入如下页面,选择Manually select features(手动选择项目)---->上下键控制,回车确定

    ? Please pick a preset: (Use arrow keys)
      Default ([Vue 3] babel, eslint)
    > Default ([Vue 2] babel, eslint)
      Manually select features
    

    选择组件------->上下键控制,空格选择

    • Bable:如果浏览器不支持ES6,Bable会使浏览器编译成ES5
    • Router:路由,不用路由页面无法跳转,类似超链接
    • VueX:路由管理
    • Linter / Formatter:设置代码检测方式及代码格式化
    ? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection, and
    <enter> to proceed)
    >(*) Babel
     ( ) TypeScript
     ( ) Progressive Web App (PWA) Support
     (*) Router
     ( ) Vuex
     ( ) CSS Pre-processors
     (*) Linter / Formatter
     ( ) Unit Testing
     ( ) E2E Testing
    
    

    选择Vue版本

    Vue CLI v5.0.8
    ? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
       3.x
    >  2.x
    

    是否使用基于历史的路由模式,我们默认基于哈希

    ? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)    n
    

    代码格式化风格配置

    ? Pick a linter / formatter config: (Use arrow keys)
      ESLint with error prevention only
      ESLint + Airbnb config
      ESLint + Standard config
    > ESLint + Prettier
    

    选择何时进入语法检测(保存时/提交时)

    ? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to
    proceed)
    >(*) Lint on save
     ( ) Lint and fix on commit
    

    组件是独立摆放还是分开放

    • In dedicated config files:各个独立组件用单独的配置文件来存储组件
    • In package.json:都放在该包下
    ? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
    > In dedicated config files
      In package.json
    

    上面设置是否保存为预设

    Save this as a preset for future projects? (y/N) n
    
    1. 进入启动项目

    进入项目:cd hello-world

    启动项目:npm run serve

    访问路径:http://localhost:8080/

    启动成功

    在这里插入图片描述

    ②基于GUI创建

    1. 创建项目

    vue ui

    1. 进入如下界面, 图形化界面将你引导至项目创建的流程

    在这里插入图片描述

8.2 Vue-cli前端项目文件结构

在这里插入图片描述

Vue单页面开发,整个应用只有一个html页面,此页面就是index.html

VUE通过视图组件(xxx.vue)来替换页面显示

  • node_modules:该目录存放项目中所需要的前端库

  • public:用于存放公共资源

    • index.html:项目中核心html页面,也是唯一一个html页面,其他视图组件都是通过该页面展示 ,在运行时会动态注入到index.html中展示
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="icon" href="<%= BASE_URL %>favicon.ico">
        <title><%= htmlWebpackPlugin.options.title %></title>
      </head>
      <body>
        <noscript>
          <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
        </noscript>
        <div id="app"></div>
        <!-- built files will be auto injected (试图组件动态的注入到此处)-->
      </body>
    
  • src:Vue项目源码目录,源码存放的目录

    • assets:用于存放项目资源(图片,音频,视频)

    • components:组件目录,该目录下用于存放自定的组件

    • router:路由目录,其中用于存放路由配置文件

      • index.js:该文件是应用的路由配置文件
      /**
       * 导入组件
       */
      import Vue from "vue";//导入Vue组件
      import VueRouter from "vue-router";//导入Vue路由组件
      import HomeView from "../views/HomeView.vue";//导入Vue的视图组件
      
      //设置当前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"),
        },
      ];
      //创建vue路由对象并设置路由哦诶之
      const router = new VueRouter({
        routes,
      });
      //声明当前文件导出的组件名
      export default router;
      
    • views:vue的视图组件目录,其中存放vue的视图组件

    • App.vue:改文件是vue主视图组件,其他视图组件都依赖于该组件展示

       <!-- 
            路由视图,他会自动在路由配置中查找跟路由,并将跟路由展示 
            渲染跟路由
           -->
          <router-view  />
      
    • main.js:该项目核心配置文件

      import Vue from "vue";
      import App from "./App.vue";
      import router from "./router";
      //在控制台中是否显示提示
      Vue.config.productionTip = false;
      
      new Vue({
        router,
        render: (h) => h(App),
      }).$mount("#app");
      

8.3 Vue-cli整合其他前端框架

Vue单页面开发,整个应用只有一个html页面,此页面就是index.html

VUE通过视图组件(xxx.vue)来替换页面显示,主视图组件为App.vue,其他组件都依赖于该组件展示。。。

  • ①可在index.html设置页面整体架构
  • ②在App.vue设置主视图组件整体架构
  • ③在组件Index.vue编写html代码,该组件依赖于App.vue

<template>中编写html代码

<template>
</template>

注:为避免样式重叠,使用scoped属性,限定当前样式作用域范围仅在当前组件

<style scoped>
</style>

<script>中编写JS代码

<!-- 
    在script标签中编写JS代码
 -->
<script>
    export default {//此处编写JS代码
    data() {
        return {
            text: "Vue组件的使用"
        }
    },
    methods: {
        test() {
            this.text = "您点击了按钮1"
        }
    }
}
</script>
  • ④配置路由
 {//配置一个视图组件的路由
    path: "/",//路由路径
    name: "index",//路由名
    component: Index,//指定该路径对应的组件名,根据组件名可以找到对应文件
  },
  • ⑤整合elementUI

    • (1)在终端使用npm引入
    npm i element-ui -S
    
    • (2) 在 main.js 中写入以下内容:
    import ElementUI from 'element-ui';//导入elementUI组件
    import 'element-ui/lib/theme-chalk/index.css';//导入element样式组件
    //引入组件
    Vue.use(ElementUI)
    
    • 在Index.vue组件测试使用
        <div>
            <el-button type="primary" @click="test">按钮</el-button>
        </div>
    
  • ⑤整合axios

    • (1)在终端使用npm引入
    npm install axios
    
    • (2)在main.js中写入一下内容
    
    //在axios设置Vue的一个原型属性prototype
    //设置后在vue中使用的方式this.$axios
    Vue.prototype.$axios = axios.create({
      baseURL: "http://localhost",//配置axios访问的基础路径
    headers: { 'X-Requested-With': 'XMLHttpRequest' },//是即将被发送的自定义请求头 
      withCredentials: true, // 表示跨域请求时是否需要使用凭证
    });
    
    • (3)在Index.vue组件测试使用
      test() {
                this.$axios.get("/user/selectUser")
                    .then()
                    .catch()
            }
    

8.4 跨域配置

前端项目向服务端项目发送请求,服务端项目接受后,不反馈给前端项目(爆cors跨域错误)

  1. 跨域:

    ① 不在同一个IP的多个项目之间访问属于跨域

    ② 同一个IP下不同端口之间的访问也属于跨域

    为了项目安全,项目之间不可随意访问,跨域请求默认是不允许的,可以请求,但无法返回资源

  2. 多个项目间要想互相访问交互,则需要进行跨域配置,允许其他项目访问当前应用

    跨域配置方式有多种,可以使用前端配置,也可以服务端配置

    前端配置:是基于代理实现的(前端项目访问服务端项目时,做一个代理,将两个项目整合)

    服务端配置:不使用代理,而是在服务端设置当前应用中哪些资源可以被外部调用

    • 当前应用中哪些资源可以被外部调用
    • 允许哪些外部应用可以访问本应用

    在springboot核心配置类里面配置

    PS:OPTIONS:预检请求,自动先预检请求,通过预检请求检查服务器地址是否存在,若存在,才发送请求

        @Bean
        public WebMvcConfigurer webMvcConfigurer(){
           return new WebMvcConfigurer() {
               /**
                * 进行配置
                * @param registry:跨域构造器
                */
               @Override
               public void addCorsMappings(CorsRegistry registry) {
                  registry
                          .addMapping("/**")//当前应用所有资源允许被跨域访问
                          .allowedOrigins("http://localhost:8080")//设置允许访问当前应用的项目
                          .allowedMethods("GET","POST","DELETE","PUT","HEAD","OPTIONS") //设置允许哪些请求方式进行跨域访问,默认情况只允许简单请求(get,post,head)
                          .allowCredentials(true);//是否允许使用凭证,是否允许使用session后cookie存储凭证信息
               }
           };
        }
    }
    

    • 学习西安加中实训

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;