vue
- vue是一个前端框架,是在前后端分离这样的业务场景诞生的。vue是基于node.js来运行的。vue有2.0、3.0版本。vue它的底层是html、css、js,它是一套构建用户界面的渐进式(javascript)框架。并提供了⼀套声明式的、组件化的编程模型,帮助你⾼效地开 发⽤户界⾯。⽆论是简单还是复杂的界⾯,Vue 都可以胜任。
- 渐进式:没有太多的限制的一个js框架。就是一开始使用这个框架,你不需要完全的掌握它的全部的功能或者特性。
- 前后端分离介绍: 前后端分离属于开发模式中的⼀种,其核⼼思想是前端项⽬采⽤(node.js实现)和后端项⽬能够 独⽴运⾏,前端采⽤ajax 向服务器发送请求,服务器只需要提供请求的地址(api)即可协作开 发。这样的项⽬ 称做前后端分离项⽬。
安装node.js
1、双击安装包,⼀直点击下⼀步。
2、点击change按钮,更换到⾃⼰的指定安装位置,点击下⼀步(不修改默认位置也是可以的 )。
3、⼀直点击下⼀步,最后安装成功即可。
安装完成后:控制台输入 node -v ---- 查看是否安裝成功
构建⼀个vue项⽬
控制台输⼊指令:
npm init vue@latest
这⼀指令将会安装并执⾏ create-vue,它是 Vue 官⽅的项⽬脚⼿架⼯具
如果不确定是否要开启某个功能,你可以直接按下回⻋键选择 No。在项⽬被创建后,通过以下步骤安装依赖并启动开发服务器:
cd <your-project-name>
命令自动下载这些依赖。
npm install
运行vue项目
npm run dev
当你准备将应⽤发布到⽣产环境时,请运⾏:
npm run build
1、VUE工程结构
- node_model:项目依赖文件夹,存放的是一些vue功能依赖的模块。
- public:存放的是一些公共的静态资源文件。
- *src:程序员自己存放的源代码(自己编写的代码)
- assets:存放静态资源文件。js.css等
- components:组件:存放的是一些公共的组件(非路由组件)
- App.vue:vue的页面文件,默认vue项目启动后访问的页面。
- *main.js:程序的入口文件。vue项目启动最先执行的文件。
- package.json:包管理工具,记录项目引用的第三方资源库
- package-lock.json:记录第三方资源库的来源。
2、vue页面组成
主要由三个部分组成
<script></script> ————编写逻辑代码、js代码 <template></template>————编写页面代码。html代码 <style></style>————编写样式代码,css代码块
3、VUE生命周期
指的是vue界面从创建到销毁的一个过程。(vue实例创建、初始化、运行、销毁)
生命周期的八个阶段:每触发一个生命周期事件,会自动执行一个生命周期方法,这些生命周期方法也被称为钩子方法(钩子函数)。
状态 | 阶段周期 |
---|---|
beforeCreate | 创建前 |
created | 创建(创建vue实例) |
beforeMount | 载入前 |
mounted | 挂载完成(将数据渲染到界面上) |
beforeUpdate | 更新前 |
updated | 更新后(更新页面数据) |
beforeDestroy | 销毁前 |
destroyed | 销毁后(销毁vue实例) |
4、VUE基础语法
声明数据、声明函数(方法)
<!--具体的页面相关元素--> <template> <!--在template标签里定义内容的时候一定需要先写一个标签,不要直接写内容--> <div> <h1>这是我的第一个vue页面</h1> <!--数值调用:{{}}:插值表达式。一般在页面里动态产生数据时使用--> <span>姓名:{{name}}</span><br> <span>年龄:{{age}}</span><br> <span>备注:{{desc}}</span><br> <!--在vue里,以v-...开头的一般都是vue的指令--> <span v-html="sex"></span><br> <!--判断指令--> <p v-if="age<18">这是一个未成年的程序员</p> <p v-else-if="age<30">这是一个成年的程序员</p> <p v-else>年到中年,小心被裁员</p> <p v-if="status==0">未支付订单</p> <p v-else-if="status==1">已发货订单</p> <p v-else>已完成订单</p> <!--v-for表示循环--> <!--:key后面跟的是一个唯一标识--> <!-- key可以提高渲染效率 --> <p v-for="c in color" :key="c">{{c}}</p> <p v-for="user in userList" :key="user.id"> {{user.name}}今年{{user.age}}岁,他/她是一位{{user.sex}}性 </p> <!--事件处理--> <!--添加事件(执行表达式),每点击一下,点击次数count++ --> <button v-on:click="count++">点击count次数改变</button> <p>count点击次数:{{count}}</p> <!--添加事件(调用函数),每点击一下,total每次加五 --> <button v-on:click="clickTotal1(5)">点击total1+number</button> <p>total计数器:{{total}}</p> <button v-on:click="clickTotal2('哈撒给!!')">点击text</button> <p>text:{{text}}</p> </div> </template> <!--js代码块--> <script> //声明数据————这是一个固定格式 export default { //data() : 一般设置一些页面上常用的参数 data(){ return{ name:'2Eua', age:23, desc:'菜狗子Java程序员一枚', sex:'<h1>男</h1>', status:0, color:['白色','蓝色','紫色','黑色','橘色'], userList:[ {'id':1,'name':'Bit','age':22,'sex':'男'}, {'id':2,'name':'Simple','age':25,'sex':'男'}, {'id':3,'name':'Niko','age':28,'sex':'男'} ], count:0, total:0, text:'' } }, methods:{ //第一种方法的声明 //每点击一次按钮,total加五 //函数传递参数和js写法是一样的。 //数字参数直接传递, clickTotal1:function (number){ this.total+=number }, //第二种方法的声明 //字符串类型的参数需要添加单引号'' clickTotal2(text){ this.text = text } } } </script> <!--样式--> <style> </style>
5、组件
组件其实就是一个vue页面,它与vue普通页面是完全相同的。
唯一区别:组件可以被多个地方进行调用。普通页面只能调用一次。
组件提高import进行导入。import时只需要指明组件的名称和路径即可。
为了区分组件和普通界面,在vue项目里组件一般放在components文件夹下。而普通页面一般放在view或者是pages文件夹下。
写一个组件vue界面
<template> <h1>{{msg}}</h1> </template> <script> export default { //组件名称 name: "TestComponent", //定义组件的参数 //props组件里的一个属性(字段),期望参数从调用方传递过来 props:{ msg:'' }, data(){ return{ } }, methods:{ } } } </script> <style scoped> </style>
导入组件
<!--具体的页面相关元素--> <template> <!--在template标签里定义内容的时候一定需要先写一个标签,不要直接写内容--> <div> <h1>这是我的第一个vue页面</h1> <!--使用组件--> <TestComponent msg="这是一个测试组件"></TestComponent> </div> </template> <!--js代码块--> <script> //导入组件 // TestComponent:组件名称 //from "./components/TestComponent.vue":组件的路径 import TestComponent from "./components/TestComponent.vue"; //声明数据————这是一个固定格式 export default { //表示引入组件 components: {TestComponent}, </script> <!--样式--> <style> </style>
6、路由
路由指的是在vue项目里具体呈现给用户的是哪一个页面,那么这个时候就是通过路由来进行控制的。注意:在vue项目里,很多时候路由都是嵌套在App.vue页面的,然后只需要更新app.vue里具体显示页面的部分即可。路由也是一种局部刷新,达到页面的跳转效果。
安装路由
命令:
cnpm install --save vue-router(所谓的渐进式)
save表示把路由的依赖添加到package.json里。
"dependencies": { "vue": "^3.2.45", "vue-router": "^4.1.6" },
7、npm和cnpm命令的区别和联系
两者都是用于node插件的,安装、卸载、以及依赖管理nmp这个命令安装插件时都是从国外的服务器进行下载的,经常受网络影响,可能会出现异常,所以很多时候我们也是用cnpm来进行下载。cnpm是由淘宝团队提供的镜像地址进行下载的。国内的淘宝镜像称为cnpm。两者语法类似。在国内使用cnpm下载效率高于npm。
8、路由的代码书写
在app.vue中通过显示路由内容。
简单来说就是通过url显示⻚⾯的功能。
1、新建pages包,在这个包里新建两个vue界面(Login.vue和Register.vue)路由传参
<template> <div> <h2>用户登录</h2> 账号:<input type="text"><br> 密码:<input type="password"><br> <span>id:{{id}}名称:{{name}}年龄:{{age}}性别:{{sex}}</span> <input type="button" value="登录"> </div> </template> <script> export default { name: "Login", //页面创建时调用 //常常再打开一个新页面时通过该方法来渲染页面,动态改变页面的数据 created() { //通过路由得到请求参数 this.id = this.$route.query.id; this.name = this.$route.query.name; this.age = this.$route.query.age; this.sex = this.$route.query.sex; }, data(){ return{ id:0, name:'', age:0, sex:'' } } } </script> <style scoped> </style> <template> <div> <h2>用户注册</h2> 邮箱:<input type="email"><br> 性别:<input type="radio">男 <input type="radio">女<br> 生日:<input type="date"><br> 密码:<input type="password"><br> 确认密码:<input type="password"><br> <input type="button" value="注册"> </div> </template> <script> export default { name: "Register" } </script> <style scoped> </style>
2、新建一个router路由目录(包),在这个目录下新建index.js和routes.js文件
配置index.js
//用来配置路由管理器 //导入路由管理器——路由里自带的 import{createRouter,createWebHistory} from "vue-router"; //导入自己写的路由 //import后跟的是文件中的元素,如果是vue页面,那么就是页面的别名 // from跟的是文件的路径 //调用时该文件里的元素需要导出export default '元素' import routes from "./routes"; //配置路由管理器 const router = createRouter({ //配置路由不需要带用#号 history:createWebHistory(), routes }); //导出后其它组件可以调用 export default router; //用来配置路由信息的 const routes = [ { //给当前路由起别名 name: "Login", //配置访问路径 path: "/login", //配置当前页面的具体路径 component: () => import('../pages/Login.vue') }, { //给当前路由起别名 name: "Register", //配置访问路径 path: "/register", //配置当前页面的具体路径 component: () => import('../pages/Register.vue') } ] // const text = [{ // name:'xxx',age:10 // }] //导出后其它组件可以调用 export default routes; //如果需要多个导出,使用括号拼成数组格式 // export default {routes,text};
3、main.js 前端的配置文件。在main.js配置路由
import { createApp } from 'vue' import App from './App.vue' import './assets/main.css' //启用路由 //导入路由管理器的配置 import router from "./router/index"; //导入axios import axios from "axios"; //当前主页面里启动/使用路由配置:createApp(App).use(router) //createApp //create 表示创建一个实例 //App是application这个单词的缩写,表示应用这个实例 //mount('#app'):表示将一个id为app的节点挂载到vue上 createApp(App).use(router).use(axios).mount('#app')
4、接下来写主界面App.vue
<!--具体的页面相关元素--> <template> <div> <button @click="loginPage()">登录</button> <button v-on:click="register()">注册</button> </div> <div> <router-view></router-view> </div> <!-- 路由跳转页面的其它两种方式--> <div> <router-link :to="{ name:'Login',query:{id:2,name:'坤坤',age:28,sex:'男'}}"> 修改 </router-link> <a href="/login">跳转</a> </div> </template> <!--js代码块--> <script> //导入组件 // TestComponent:组件名称 //from "./components/TestComponent.vue":组件的路径 import TestComponent from "./components/TestComponent.vue"; import axios from "axios"; //声明数据————这是一个固定格式 export default { //表示引入组件 components: {TestComponent}, created() { axios.post('http://localhost:8080/user/login',null).then(res=>{ }) }, //data() : 一般设置一些页面上常用的参数 data(){ return{ } }, methods:{ //跳转到登录页面 loginPage(){ //跳转到指定的页面 //直接跳转到某个页面 // this.$router.push("/login") //跳转页面并且向目标页面传递参数 this.$router.push({ //name 表示当前页面的别名 // 跳转到名字叫做Login的页面 name:'Login', //query是传递的参数。可以是多个 query:{ id: 1, name: "chw", age: 23, sex: "男" }}) }, register(){ this.$router.push("/register") } } } </script> <!--样式--> <style> </style>
9、在vue路由里$router和$route的区别
$router对象它是全局路由对象的实例。是router构造方法的实例。是它可以控制整个路由的页面跳转。
$route对象表示当前的路由对象信息,包含了当前 URL 解析得到的信息。包含当前的路径,参数,query对象等。这个对象一般用来获取当前跳转路由的相关参数。
10、axios
Vue里,通常使用axios向服务器发出AJAX请求。
Axios,可以工作于浏览器里,也可以在node.js使用。
主要功能有:
1、发送ajax请求到服务器端,服务器端响应数据到浏览器端
2、自动转换JSON
在vue中使⽤axios
vue中使⽤axios需要安装:npm install axios
11、跨域问题
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。
跨域是指客户端浏览器发送http请求时,由于浏览器自身存在的安全机制(同源策略),浏览器会检查请求中的(协议,域名(ip),端口号)。判断当前请求的(协议,域名(ip),端口号)和当前页面的(协议,域名(ip),端口号)是否相同。如果不相同,浏览器会对当前的请求进行限制。这个限制叫做跨域。
只要协议、域名、端口里有一种不一样那么都会存在跨域。
一般跨域问题常出现在前后端分离的系统里。而且服务器之间不存在跨域问题。
axios解决跨域问题
1、使用配置代理的方式解决。
因为浏览器同源策略机制,前后端分离后客户端请求服务端的数据时,会存在跨域问题。而服务器和服务器之间是可以相互请求数据的,是没有跨域的概念的,也就是说我们可以配置一个代理的服务器,由这个代理服务器收到客户端请求,将请求转发给另一个服务器,然后把请求出来的数据返回到代理服务器里,再由代理服务器返回数据给我们的客户端。这样就实现了跨域访问数据。
Vue3.0解决⽅案:vite.config.js中进⾏配置一个代理服务器:
import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, //配置服务和代理 server:{ //配置本地端口 port:8000, //配置代理信息 proxy:{ //配置请求映射路径:只要是以/api开头的请求都使用下面得配置信息 '/api':{ //配置目标服务器地址 target:'http://localhost:8088', // 允许跨域 changeOrigin: true, //url重写 rewrite:(path)=>path.replace(/^\/api/,'') } } } }) /* rewrite 叫做请求url重写:配置代理之后客户端向服务器发送请求 (地址:目标服务器+映射地址)http:localhost:8088/api/user/login 代理服务器最终请求得地址为:http:localhost:8088/user/login */
2、注解@CrossOrigin解决跨域问题
服务端通过在controller控制器的class类上配置注解@CrossOrigin来解决跨域问题。
组件和页面的区别:
1、组件其实就是一个vue的页面,它跟vue普通页面是完全相同的。
2、唯一区别是,组件可以被多个地方进行调用。而普通页面只能调用一次。
3、在vue项目里,组件一般放在components文件夹下。而普通页面一般放在pages文件夹下,或者view文件夹下。
4、页面是直接和URL对应,或者说是和“大”URL对应的,里面不做具体的功能,而是放各种组件,负责组件之间的关联关系。
5、组件负责实现具体的功能。页面包括组件。
12、VUE双向绑定
基于MVVM(Model-View-ViewModel)思想,实现数据的双向绑定,将编程的关注点放在数据上。
双向绑定是指当数据模型数据发生变化时,页面展示的数据会随之发生变化,而如果页面中的数据发生变化时,绑定的模型数据也随之发生变化。
Element-UI
Element-Ul是饿了么前端团队推出的⼀款基于Vue.js 的桌⾯端UI框架。⼿机端有对应框架是Mint UI Vue框架:它是对js的封装,Element-UI 它是基于Vue的框架,它封装了css样式,我们使⽤Vue需要样 式的时候就使⽤它。 丰富的组件,⾃定义主题,国际化。 提供友好的⽂档和 demo,维护成本⼩ ⽀持 npm ⽅式
安装使用
官⽹: 一个 Vue 3 UI 框架 | Element Plus
下载:
Vue使⽤element-ui 需要使⽤element-plus
npm install element-plus --save
cnpm install element-plus --save
配置: 在main.js里导入,并且use,挂载
//引入elementui-plus import elementUI from 'element-plus' //引入elementui-plus得样式 import 'element-plus/dist/index.css' // 样式依赖 //引入elementui-plus里的图标 import * as ElIcons from '@element-plus/icons-vue' // 引⼊图标 const app = createApp(NewApp); // createApp(App).use(router).use(elementUI).mount('#app') //遍历添加图标组件 for (const icon in ElIcons){ app.component(icon,ElIcons[icon]) } //挂载 app.use(router).use(elementUI).mount('#app')
elementUI的布局
<!-- element-ui得24分栏布局 --> <!-- span"4":比例--> <!-- el-row行--> <!-- el-col列--> <el-row style="background-color: aquamarine"> <el-col :span="24"> <h2>这是布局得头部</h2> </el-col> </el-row> <el-row> <el-col :span="4" style="background-color: sienna"> <h2>导航栏</h2> </el-col> <!-- 24分栏得内部嵌套--> <el-col :span="20" style="background-color: pink"> <el-row> <el-col :span="12" style="background-color: blueviolet"><h2>嵌套1</h2></el-col> <el-col :span="12" style="background-color: olivedrab"><h2>嵌套2</h2></el-col> </el-row> </el-col> </el-row>
<!-- 常见得按钮--> <el-button type="primary">主要按钮</el-button> <el-button type="success">成功按钮</el-button> <el-button type="info">信息按钮</el-button> <el-button type="warning">警告按钮</el-button> <el-button type="danger">危险按钮</el-button>
<!-- 带图标的按钮--> <el-button type="primary" icon="Edit" /> <el-button type="primary" icon="Share" /> <el-button type="primary" icon="Delete" /> <el-button type="primary" icon="Search">Search</el-button> <el-button type="primary"> Upload<el-icon class="el-icon--right"><Upload /></el-icon> </el-button>
<!-- 单选框--> <el-radio-group v-model="sex"> <el-radio label="1">男</el-radio> <el-radio label="0">女</el-radio> </el-radio-group>
<!-- 复选框--> <el-checkbox-group v-model="likeArray"> <el-checkbox label="1">打篮球</el-checkbox> <el-checkbox label="2">踢足球</el-checkbox> <el-checkbox label="3">玩游戏</el-checkbox> <el-checkbox label="4">敲代码</el-checkbox> </el-checkbox-group> <el-button type="success" icon="Upload">增加按钮</el-button> <el-button type="danger" icon="Delete">删除按钮</el-button> <el-button type="info" icon="Search">查询按钮</el-button> <el-button type="warning" icon="Edit">修改按钮</el-button>
复选框的动态产生
<!-- 如果需要动态产生复选框,需要复选框绑定的数组,不要和我们生成复选框的数组一样。 因为绑定的数据,默认是发送给服务器的,很多时候用户在选择某个值的时候会将选中的值加入到 绑定的数组里。--> <el-checkbox-group v-model="studyArray"> <el-checkbox :label=lesson.id v-for="lesson in lessonArray" :key="lesson.id" >{{lesson.lessonName}}</el-checkbox> </el-checkbox-group> studyArray: [], lessonArray: [ {id:1,lessonName:'JavaWeb'}, {id:2,lessonName:'SpringBoot'}, {id:3,lessonName:'Mybatis'} ]
下拉列表
<!-- 下拉列表--> <!-- placeholder:提示信息--> <el-select v-model="edu" placeholder="请选择学历" @change="eduChange()"> <!-- label:指的是显示的值 value:代表要提交给服务器的值 --> <el-option label="高中" value="1"></el-option> <el-option label="大专" value="2"></el-option> <el-option label="本科" value="3"></el-option> <el-option label="研究生" value="4"></el-option> </el-select>
日期选择框
<!-- 日期选择框--> <!-- type表示当前日期的类型--> <!-- value-format ——日期格式--> <!-- placeholder——提示信息--> <!-- type:date 表示时间是一个日期,年月日--> <!-- type:datetime 表示时间是一个日期时间,年月日时分秒--> <el-date-picker v-model="startTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择开始时间" @change="timeChange()"> </el-date-picker> {{this.startTime}} <!-- 第二种 选择日期和时间--> <el-date-picker v-model="endTime" type="datetime" value-format="YYYY-MM-DD hh:mm:ss" placeholder="请选择结束时间" @change="endTimeChange()"> </el-date-picker> {{this.endTime}}
表格
<!-- 表格--> <!-- :data 给当前表格绑定一个叫做userList得数据--> <!-- stripe样式:奇偶行都会有渐变色--> <el-table :data="userList" stripe> <!-- prop:表示绑定得是哪一个属性(列)--> <!-- label:表示表头的名称--> <el-table-column prop="id" label="ID"></el-table-column> <el-table-column prop="name" label="名称"></el-table-column> <el-table-column prop="sex" label="性别"></el-table-column> <el-table-column prop="address" label="家庭地址"></el-table-column> </el-table>
表格数据从后台获取
1、页面:
<el-table :data="bookList" stripe> <el-table-column prop="id" label="ID"></el-table-column> <el-table-column prop="name" label="书名"></el-table-column> <el-table-column prop="author" label="作者"></el-table-column> <el-table-column prop="desc" label="描述"></el-table-column> <el-table-column prop="price" label="价格"></el-table-column> <!-- 动态计算数据--> <el-table-column label="数量"> <template #default="priceTemp"> <el-input v-model="priceTemp.row.number"></el-input> </template> </el-table-column> <el-table-column label="总价"> <template #default="sumTemp"> {{sumTemp.row.price * sumTemp.row.number}} </template> </el-table-column> <el-table-column prop="status" label="状态"> <template #default="scope"> <!--三元表达式--> {{ scope.row.status==1?'可售':'不可售'}} </template> </el-table-column> <el-table-column prop="createTime" label="创建时间"></el-table-column> <el-table-column label="操作"> <!-- scope得到表单某一行的整个对象(包括数据对象,以及页面的标签对象等等)--> <!-- scope.row得到当前这一行的对象--> <!-- scope.row.id 得到当前这一行这条数据的id--> <template #default="scope"> <el-button type="primary" @click="deleteBook(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table>
2、ajax请求
<script> import axios from "axios"; export default { name: "NewApp", created() { axios.post('/chw/book/bookList',null).then(resp=>{ this.bookList = resp.data; }) }, data(){ return{ bookList: [] } }, methods:{ deleteBook(id){ alert(id); } } } </script>
3、bean
@Data @NoArgsConstructor @AllArgsConstructor public class BookBean { private int id; private String name; private String author; private String desc; private String createTime; private int status;//0:代表禁用,1:代表开放 private double price; private int number; }
4、控制器
@RestController @RequestMapping("/book") public class BookController { @RequestMapping("/bookList") public List<BookBean> getBookList(){ BookBean bookBean = new BookBean(1,"JavaWeb","张三","javaweb应用","2022-12-09",1,77.5,3); BookBean bookBean1 = new BookBean(2,"MySQL","李四","MySQL","2022-12-08",0,60.5,10); BookBean bookBean2 = new BookBean(3,"Oracle","王五","Oracle","2022-12-05",1,89.5,9); BookBean bookBean3 = new BookBean(4,"SpringBoot","赵六","SpringBoot","2022-12-11",0,48.5,5); BookBean bookBean4 = new BookBean(5,"SpringMVC","孙七","SpringMVC","2022-12-22",0,66.5,6); List<BookBean> bookBeanList = new ArrayList<>(); bookBeanList.add(bookBean); bookBeanList.add(bookBean1); bookBeanList.add(bookBean2); bookBeanList.add(bookBean3); bookBeanList.add(bookBean4); return bookBeanList; } }
对话框
<!--el-dialog:对话框--> <!--title标题、width宽度--> <!-- dialogVisible:对话框绑定model时,一般绑定的是一个布尔值,该值表示当前对话框是否显示--> <el-dialog v-model="dialogVisible" title="添加用户" width="30%"> <span>这是一个添加用户操作</span> <!-- footer代表当前template里的内容当前对话框的脚部(页脚)--> <template #footer> <span class="dialog-footer"> <el-button type="primary" @click="dialogVisible = false">取消</el-button> <el-button type="primary">确定</el-button> </span> </template> </el-dialog> <el-button type="primary" @click="dialogVisible=true">打开对话框</el-button>
导航栏、分页、验证规则、对话框
<template> <el-row style="background-color: pink"> <el-col :span="24"><h1>这是首页标题</h1></el-col> </el-row> <el-row> <el-col :span="6" style="background-color: aqua"> <!--导航菜单--> <!--class="el-menu--vertical-demo":默认样式--> <el-menu class="el-menu--vertical-demo" text-color="#3014ADFF" default-active="2-1" background-color="#5EE069FF"> <!--index="1":当前菜单的位置--> <!--el-sub-menu:一级菜单--> <el-sub-menu index="1"> <template #title> <el-icon> <User/> </el-icon> <span>用户管理</span> </template> <!--el-menu-item:二级菜单--> <el-menu-item index="1-1">注册用户</el-menu-item> <el-menu-item index="1-2">用户列表</el-menu-item> </el-sub-menu> <el-sub-menu index="2"> <template #title> <el-icon> <View/> </el-icon> <span>角色管理</span> </template> <!--el-menu-item:二级菜单--> <el-menu-item index="2-1">角色列表</el-menu-item> <el-menu-item index="2-2">角色修改</el-menu-item> </el-sub-menu> </el-menu> </el-col> <el-col :span="18" style="background-color: blueviolet"> <h2>内容</h2> </el-col> </el-row> <!-- 对话框--> <el-dialog v-model="dialogVisible" title="添加用户" width="30%"> <!--表单元素的基本使用--> <!--el-form form表单--> <!--userForm双向绑定--> <!--userForm.userName 双重双向绑定--> <!--ref:别名--> <el-form :model="userForm" :rules="rules" ref="userForm" class="demo-ruleForm"> <!--el-form-item 表单中的每一行。由框架底层提供样式布局--> <!--label 表单的描述--> <el-form-item label="姓名" prop="userName"> <el-input v-model="userForm.userName"></el-input> </el-form-item> <el-form-item label="密码" prop="passWord"> <el-input type="password" v-model="userForm.passWord"></el-input> </el-form-item> <el-form-item label="性别" prop="sex"> <el-radio-group v-model="userForm.sex"> <el-radio :label="1">男</el-radio> <el-radio :label="2">女</el-radio> </el-radio-group> </el-form-item> <el-form-item label="电话号码" prop="tel"> <el-input v-model="userForm.tel"></el-input> </el-form-item> <el-form-item label="生日" prop="birthday"> <el-date-picker type="date" value-format="YYYY-MM-DD" v-model="userForm.birthday" placeholder="请选择生日"> </el-date-picker> </el-form-item> </el-form> <template #footer> <span class="dialog-footer"> <el-button type="primary" @click="cancel()">取消</el-button> <el-button type="primary" @click="addUser()">确定</el-button> </span> </template> </el-dialog> <el-button type="primary" @click="dialogVisible=true">打开添加用户对话框</el-button> <!-- v-model:current-page:绑定当前页码--> <!-- v-model:page-size:绑定每页显示多少条--> <!-- background:分页标签带背景颜色--> <!-- total="total"绑定总条数--> <!-- @current-change:当前页码改变时可进行调用,每次得到的是当前页码值--> <el-pagination @size-change="changeSize" @current-change="changeCurPage" :current-page="curPage" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination> </template> <script> import axios from "axios"; import {ElMessage} from "element-plus"; export default { name: "App1206", data() { return { curPage: 1, pageSize: 10, total: 100, userForm: { userName: '', passWord: '', birthday: '', sex: 0, tel: '' }, dialogVisible: false, //验证规则 //1:给表单加上rules——属性——规则 //2:给表单的每行元素el-form-item加上prop属性,注意prop属性名称和表单标签的v-model里的名称要一致。 //3:声明验证的规则,也就是声明的rules变量 // required:是否必须,message:提示消息,trigger:blur:失去焦点时触发 rules: { userName: [ {required: true, message: '请输入用户名', trigger: 'blur'}, {min: 2, max: 8, message: '用户名长度为2-8位', trigger: 'blur'}], tel: [ {required: true, message: '请输入电话号码', trigger: 'blur'}, {pattern: /^1[3578]\d{9}$/, message: '电话必须是13、15、17、18开始的十一位数', trigger: 'blur'}] } } }, methods: { changeCurPage(curPage) { alert(curPage); }, changeSize(pageSize){ alert(pageSize); }, cancel() { this.dialogVisible = false; //重置表单 this.$refs.userForm.resetFields(); }, addUser() { //最常用方法第二种----传递表单 axios.post('/chw/user/addUser', this.userForm).then(response => { if ("success" == response.data) { ElMessage({ message: '用户添加成功。', type: 'success', }) //关闭弹窗 this.dialogVisible = false; //清空表单 //第一种方式(清空表单) /*this.userForm = { userName: '', passWord: '', birthday: '', sex: 0 }*/ //第二种方式(重置表单) //第一步,给当前form表单新增一个ref属性 //第二步,给需要清空的表单标签el-form-item加上prop参数 //第三步,重置表单 //设置一个名叫userForm的表单元素,重置所有的表单,重置不是清空 //重置是重置回声明表单时的值 this.$refs.userForm.resetFields(); } else { ElMessage({ message: '用户添加失败。', type: 'failed', }) } }); /* //传递对象。formData对象_扩展 let param = new FormData(); param.append("userName",this.userForm.userName) param.append("sex",this.userForm.sex) param.append("birthday",this.userForm.birthday) param.append("passWord",this.userForm.passWord) axios.post('/chw/user/addUser',param).then(resp=>{ if ("success" == resp.data){ ElMessage({ message: '用户添加成功。', type: 'success', }) } });*/ /*// 第三种 let param = JSON.stringify(this.userForm); // 设置当前请求数据内容的类型为json字符串 let config = { headers: { 'Content-Type': 'application/json' } } axios.post('/chw/user/addUser',param,config).then(resp => { if ("success" == resp.data) { ElMessage({ message: '用户添加成功。', type: 'success', }) } });*/ }, } } </script> <style scoped> </style>