首页 > 其他分享 >Vue基础

Vue基础

时间:2024-09-02 10:55:32浏览次数:10  
标签:Vue const data 基础 vue 组件 import ref

目录

Vue介绍

入门案例

Vue指令

页面赋值(v-html)

双向绑定(v-model)

属性绑定(v-bind)

列表遍历(v-for)

条件判断(v-if/v-show)

事件绑定(v-on)

axios

前端工程化

安装NodeJS

创建项目

项目介绍

API风格

选项式API

组合式API

组件化

局部注册组件

全局注册组件

ElementPlus

快速入门

容器布局

水平导航栏

垂直导航栏

表格组件

分页组件

对话框

表单组件

综合案例


Vue介绍

原生的JS在程序开发的过程中书写起来是十分麻烦的,因此很多的前端的框架(半成品)就应运而生了,目前比较知名的是下面三个

Vue是一个用于构建用户界面的渐进式框架,目前企业中流行的版本有两个

入门案例

 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>快速入门</title>
 </head>
 ​
 <body>
     <!--
         3. 使用vue声明一个变量username, 并把它的值显示在div中
     -->
     <div id="app">
         {{username}}
     </div>
 ​
     <script type="module">
         // 1. 导入vue的js文件
         import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
 ​
         //2. 创建vue对象
         createApp({
             //数据
             data() {
                 return {
                     username: "张三"
                 }
             }
         }).mount('#app')
 ​
     </script>
 ​
 </body>
 ​
 </html>

插值表达式是一种Vue的模板语法,用于给页面进行赋值,注意点:

  1. {{}}除了基本的赋值外,还可以进行简单的方法调用、数学运算、三元运算等等

  2. {{}}中仅仅支持表达式,不支持语句,比如:if、for

  3. {{}}中使用的数据必须在data中存在

  4. {{}}不能为标签的属性进行赋值

Vue指令

Vue的指令就类似于Java的关键字,是Vue内置好一些有特点含义的语法标签,一般格式都是v-xxxx

页面赋值(v-html)

v-html用于将指定变量的值渲染到页面上,如果变量值中有html语法,会进行解析

此标签跟插值表达式功能相似,区别在于插值表达式不会进行html语法的解析

 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>快速入门</title>
 </head>
 ​
 <body>
     <!-- 
         v-html用于将指定变量的值渲染到页面上,如果变量值中有html语法,会进行解析
         此标签跟插值表达式功能相似,区别在于插值表达式不会进行html语法的解析
     -->
     <div id="app">
         使用插值表达式的效果: {{str}} <br>
         使用插值v-html的效果: <span v-html="str">好孩子</span>
     </div>
     
     <script type="module">
         /* 1. 导入vueJS的主入口类 */
         import {createApp} from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
         //import {createApp} from './js/vue.esm-browser.js';
 ​
         /* 2. 创建Vue对象 */
         createApp({
             data(){
                 return {
                      str:"我是一个<b>好学生</b>"
                 }
             }
         }).mount('#app');
     </script>
 </body>
 ​
 </html>

双向绑定(v-model)

v-model是双向绑定,视图(View)和模型(Model)之间会互相影响

目前v-model的可使用元素有:input、select、textarea

 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>双向绑定</title>
 </head>
 ​
 <body>
     <!-- 
         v-model是双向绑定,视图(View)和模型(Model)之间会互相影响
         目前v-model的可使用元素有:input、select、textarea
     -->
     <div id="app">
         <h3>姓名:</h3>
         <input type="text" v-model="username">
         <div>您写的姓名是:{{username}}</div>
 ​
 ​
         <h3>性别:</h3>
         <input type="radio" value="男" v-model="gender"> 男 <br>
         <input type="radio" value="女" v-model="gender"> 女 <br>
         <div>您选择的性别是:{{gender}}</div>
 ​
 ​
         <h3>爱好:</h3>
         <input type="checkbox" value="抽烟" v-model="hobby">抽烟<br>
         <input type="checkbox" value="喝酒" v-model="hobby">喝酒<br>
         <input type="checkbox" value="烫头" v-model="hobby">烫头<br>
         <div>您选择的爱好是:{{hobby}}</div>
 ​
 ​
         <h3>段位:</h3>
         <select v-model="level">
             <option value="">请选择</option>
             <option value="青铜">青铜</option>
             <option value="白银">白银</option>
             <option value="王者">王者</option>
         </select>
         <div>您选择的段位是:{{level}}</div>
     </div>
 ​
     <script type="module">
         import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
 ​
         createApp({
             data() {
                 return {
                     "username": "张三",
                     "gender": "男",
                     "hobby": ["喝酒"],
                     "level": "青铜"
                 }
             }
         }).mount('#app');
     </script>
 </body>
 ​
 </html>

属性绑定(v-bind)

对于HTML标签属性,如果想要动态传值,不能使用{{}},而应该使用专门的属性绑定语法

标准语法:v-bind:属性名="Vue中的变量"

简写语法: :属性名="Vue中的变量"

 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>属性绑定</title>
 </head>
 ​
 <body>
     <!-- 
         对于HTML标签属性,如果想要动态传值,不能使用{{}},而应该使用专门的属性绑定语法
         标准语法:v-bind:属性名="Vue中的变量"
         简写语法:      :属性名="Vue中的变量"
     -->
     <div id="app">
         <h3>属性绑定基本使用</h3>
         有两个图片地址分别是:./img/vue.png 和 ./img/mn.jpg,请在下面输入地址,改变图片:<br>
         图片地址: <input type="text" v-model="imgSrc">
         图片宽度: <input type="text" v-model="imgWidth">
         <br>
         <img v-bind:src="imgSrc" :width="imgWidth">
     </div>
     
     <script type="module">
         import {createApp} from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
 ​
         createApp({
             data(){
                 return {
                     imgSrc: "./img/vue.png",
                     imgWidth: "100px"
                 }
             }
         }).mount('#app');
     </script>
 </body>
 ​
 </html>

列表遍历(v-for)

v-for="(临时变量,索引) in 数组"

遍历哪个标签,就要将这个指令当成属性写在谁哪个标签上

 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>列表遍历</title>
 </head>
 ​
 <body>
     <!-- 
         v-for="(临时变量,索引) in 数组"
         注意:遍历哪个标签,就要将这个指令当成属性写在谁哪个标签上
     -->
     <div id="app">
         <table border="1" cellspacing="0" cellpadding="0" width="500px">
             <tr>
                 <th>id</th>
                 <th>name</th>
                 <th>address</th>
             </tr>
             <tr v-for="(user,item) in users" :key="user.id">
                 <td>{{user.id}}</td>
                 <td>{{user.name}}</td>
                 <td>{{user.address}}</td>
             </tr>
         </table>
     </div>
 ​
     <script type="module">
         import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
 ​
         createApp({
             data() {
                 return {
                     users: [
                         { id: 1, name: 'jack', address: '北京顺义' },
                         { id: 2, name: 'lucy', address: '上海虹桥' },
                         { id: 3, name: 'jerry', address: '天津宝坻' }
                     ]
                 }
             }
         }).mount('#app');
     </script>
 </body>
 ​
 </html>

条件判断(v-if/v-show)

语法:

v-if=布尔值 条件性的创建或者移除某些元素,判定为true时创建,判定为false移除

v-show=布尔值 条件性的显示或者隐藏某些元素,判定为true时显示,判定为false隐藏

注意:

1) v-if 一般用于要么显示,要么隐藏的场景;v-show用于频繁切换显示和隐藏的场景

2) v-if还可以配合v-else以及v-else-if实现多分支条件判断,此时要注意三个标签中间不能有其它内容

 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>条件判断</title>
 </head>
 ​
 <body>
     <!-- 
         语法:    
             v-if 条件性的创建或者移除某些元素,判定为true时创建,判定为false移除
             v-show 条件性的显示或者隐藏某些元素,判定为true时显示,判定为false隐藏
         注意:    
             1) v-if 一般用于要么显示,要么隐藏的场景;v-show用于频繁切换显示和隐藏的场景
             2) v-if还可以配合v-else以及v-else-if实现多分支条件判断,此时要注意三个标签中间不能有其它内容
      -->
     <div id="app">
         <!--从文本框输入成绩, 然后判断成绩是否及格  >=60:及格    <60:不及格-->
         请输入成绩:<input type="text" v-model="score"><br>
         <h3>v-if判断考试结果</h3>
         您本次开始成绩:
         <span v-if="score >= 60">及格</span>
         <span v-else-if="score < 60">不及格</span>
         <span v-else>成绩无效</span>
         <!--         
                 <span v-if="score >= 60">及格</span>
                 <span v-if="score < 60">不及格</span> 
             -->
 ​
         <h3>v-show判断考试结果</h3>
         您本次开始成绩:
         <span v-show="score >= 60">及格</span>
         <span v-show="score < 60">不及格</span>
     </div>
 ​
     <script type="module">
         import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
 ​
         createApp({
             data() {
                 return {
                     score: "0",
                 }
             }
         }).mount('#app');
     </script>
 </body>
 ​
 </html>

事件绑定(v-on)

事件绑定用于给页面元素添加事件,js支持的事件vue都支持

标准语法 v-on:事件名="函数名"

简化语法 @事件名="函数名"

 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>事件绑定</title>
 </head>
 ​
 <body>
     <!-- 
         事件绑定用于给页面元素添加事件,js支持的事件vue都支持
         标准语法   v-on:事件名="函数名"
         简化语法   @事件名="函数名"
      -->
     <div id="app">
         <b>数量:</b>
         <button @click="diff()">-</button>
         <input type="text" v-model="num" style="width: 30px;">
         <button v-on:click="add()">+</button>
     </div>
 ​
     <script type="module">
         import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
 ​
         createApp({
             data() {
                 return {
                     num: 1
                 }
             },
             methods: {
                 add() {
                     this.num++
                 },
 ​
                 diff() {
                     this.num--
                 }
             }
         }).mount('#app');
     </script>
 </body>
 ​
 </html>

axios

axios是一个可以从前端向后端发送ajax请求的小框架,为Vue官方所推荐

 
//axios 发送get请求 
 axios.get("url?username=zhangsan&password=123").then(resp=>{
     resp.data;//返回结果
 })
 ​
 // axios发送post请求
 axios.post("url",{"username":"zhangsan","password":"123"}).then(resp=>{
     resp.data;//返回结果
 })
 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <title>vue表格制作</title>
     <!--
         使用Axios向指定后台发送请求,将拉取的数据使用vue技术渲染成HTML表格
         后台的数据地址是:https://mock.apifox.cn/m1/3128855-0-default/emp/list
     -->
 </head>
 ​
 <body>
     <div id="app">
         <table border="1" cellspacing="0" width="60%">
             <tr id="head">
                 <th>编号</th>
                 <th>姓名</th>
                 <th>图像</th>
                 <th>性别</th>
                 <th>职位</th>
                 <th>入职日期</th>
                 <th>最后操作时间</th>
             </tr>
             
             <tr v-for="(emp,index) in empList" :key="emp.id">
                 <td>{{emp.id}}</td>
                 <td>{{emp.name}}</td>
                 <td><img :src="emp.image" width="50px"> </td>
                 <td>{{emp.gender == 1 ? "男" : "女"}}</td>
                 <td>{{emp.job}}</td>
                 <td>{{emp.entrydate}}</td>
                 <td>{{emp.updateTime}}</td>
             </tr>
         </table>
     </div>
 ​
     <script src="./js/axios.js"></script>
     <script type="module">
         import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
 ​
         createApp({
             data() {
                 return {
                     empList: []
                 }
             },
             methods: {
                 findList() {
                     axios.get("https://mock.apifox.cn/m1/3128855-0-default/emp/list").then(resp => {
                         this.empList = resp.data.data;
                     })
                 }
             },
             created() { // 页面加载完毕后调用findList方法
                 this.findList();
             }
         }).mount('#app');
     </script>
 </body>
 ​
 </html>

前端工程化

前端工程化就是在企业级的前端项目开发中,把前端开发所需要的工具、技术、流程、经验进行规范化和标准化

安装NodeJS

在开发项目之前,我们需要安装下NodeJS,它是前端开发的基础环境,相当于Java的JDK

① 双击资料中提供的安装包,启动安装程序

② 选择安装到一个没有中文没有空格的目录下,新建一个文件夹nodejs

③ 安装完毕后,通过node -v验证一下是否安装成功

\

④ 使用管理员身份运行命令行,执行如下指令配置npm的全局安装路径

 npm config set prefix "D:\node.js"

注意:D:\soft\nodejs\这个目录是NodeJS的安装目录

⑤ 使用管理员身份运行命令行,执行如下指令切换镜像源

 npm config set strict-ssl false
 npm config set registry https://registry.npm.taobao.org

创建项目

接下来使用npm init vue@latest安装一个vue3的项目,这个过程中它会自动安装脚手架并初始化工程

安装的过程中会提示一些选项如下:

为了接下来的开发,我们还需要安装几个vscode的插件:

  • Vue-Official 语法高亮,智能提示,emmet,错误提示,格式化,自动补全

  • Vue VSCode Snippets: 快捷键

  • Vetur

  • VueHelper

启动项目

项目介绍

打开项目会发现很多目录,下面了解下每个目录的作用

我们以main.js作为文件的主入口,此文件会引入我们开发的根组件App.vue

我们可以在根组件中编写代码,也可以在其它自定义组件中开发,再引入到根组件中

组件:我们开发代码的主战场,一般包含三部分:script(定义js)、template(定义HTML)、style(定义css)

修改App.Vue,自定义首页

 <!-- 注意: 先删掉script标签的setup属性 -->
 <script>
 export default {
     data() {
         return {
             message: "Hello"
         }
     }
 }
 </script>
 ​
 <template>
     <div>
         <span class="msg">{{ message }}</span>
     </div>
 </template>
 ​
 <style scoped>
 .msg {
     color: red;
 }
 </style>

API风格

在Vue中,有两种不同的风格:选项式API和组合式API

选项式API

选项式API允许导出多个对象(data、methods、mounted)来描述数据、方法、钩子函数

 <!-- 注意: 先删掉script标签的setup属性 -->
 <script>
 export default {
     //数据
     data() {
         return {
             count: 1
         }
     },
     //方法
     methods:{
         increment(){
             this.count++;
         },
         decrement(){
             this.count--;
         }
     }
 }
 </script>
 ​
 <template>
     <div>
         <button @click="decrement()">-</button>
         <span class="msg">{{ count }}</span>
         <button @click="increment()">+</button>
     </div>
 </template>
 ​
 <style scoped>
 .msg {
     color: red;
     display: inline-block;
     width: 20px;
     text-align: center;
 }
 </style>

组合式API

组合式API用起来更加的简便

 <!-- 
     1. 在script标签上添加setup属性
     2. 变量直接使用ref声明
     3. 方法直接定义
     4. 构造函数 直接写
 -->
 <script setup>
 import { onMounted, ref } from 'vue';
 ​
 //变量(这样声明出来的count是个对象 使用.value属性可以访问它的值)
 const count = ref(1);
 ​
 //方法
 const increment = function () {
     count.value++;
 }
 const decrement = () => {
     count.value--;
 }
 ​
 //钩子函数
 onMounted(() => {
     count.value = 10;
 })
 ​
 </script>
 ​
 <template>
     <div>
         <button @click="decrement()">-</button>
         <span class="msg">{{ count }}</span>
         <button @click="increment()">+</button>
     </div>
 </template>
 ​
 <style scoped>
 .msg {
     color: red;
     display: inline-block;
     width: 20px;
     text-align: center;
 }
 </style>

组件化

组件就是将一个页面可以拆分成一个个小部分,每个小部分有着自己独立的结构、样式、行为,这一个小部分就称为组件,组件便于维护,利于复用 。

组件分为两类:根组件和普通组件,根组件就一个--App.vue,它用来装载普通组件,普通组件可以有很多个,普通组件也可以装载其它普通组件

局部注册组件

局部注册:只能在注册的组件内使用

① 创建header组件

 <script setup>
 ​
 </script>
 ​
 <template>
     <div class="header">
         我是hm-header
     </div>
 </template>
 ​
 <style scoped>
     .header{
         width: 500px;
         height: 100px;
         background-color: blueviolet;
         text-align: center;
         font-size: 20px;
         color: aliceblue;
     }
 </style>

② 创建main组件

 <script setup>
 ​
 </script>
 ​
 <template>
     <div class="header">
         我是hm-main
     </div>
 </template>
 ​
 <style scoped>
     .header{
         width: 500px;
         height: 400px;
         background-color:orange;
         text-align: center;
         font-size: 20px;
         color: aliceblue;
     }
 </style>

③ 创建footer组件

 <script setup>
 ​
 </script>
 ​
 <template>
     <div class="footer">
         我是hm-footer
     </div>
 </template>
 ​
 <style scoped>
     .footer{
         width: 500px;
         height: 100px;
         background-color:cornflowerblue;
         text-align: center;
         font-size: 20px;
         color: aliceblue;
     }
 </style>

④ 在根组件中导入上面的三个组件并注册使用

<script setup>
//1. 将组件文件导入进来
import HmHeader from './components/HmHeader.vue'
import HmMain from './components/HmMain.vue'
import HmFooter from './components/HmFooter.vue'

components: {
    /* 标签:组件变量名 */
    HmHeader,
    HmMain,
    HmFooter
}
</script>

<template>
    <div>
        <!-- 3. 将组件等价标签写在html中 -->
        <hm-header></hm-header>
        <hm-main></hm-main>
        <hm-footer></hm-footer>
    </div>
</template>

<style scoped>

</style>

全局注册组件

全局注册:在所有组件中都能使用

全局注册跟局部注册的开发步骤很相近,不一样的地方在于注册的时候需要在main.js中注册,这样就可以在任意一个其它组件中使用了

① 创建button组件

<script setup>

</script>

<template>
    <div>
        <button>按钮</button>
    </div>
</template>

<style scoped>
    button{
        width: 100px;
        height: 40px;
        background-color: darkturquoise;
        color: white;
    }
</style>

② 注册全局组件

③ 在任何需要使用组件的时候直接使用标签名调用

ElementPlus

Element是饿了么公司前端开发团队提供的一套基于Vue的网站组件库,作用是帮助开发人员快速搭建网站

Element提供了大量的写好的页面组件,例如按钮、图片、表格、导航条、表单等等,开发人员可以直接复制使用

参考网站:https://element-plus.org/zh-CN/

我们自己编写的按钮

Element提供的按钮

快速入门

  1. 使用npm install element-plus --save命令安装element-plus的包

  2. 在main.js中导入并创建ElementPlus的实例

    import { createApp } from 'vue'
    import ElementPlus from 'element-plus'
    import 'element-plus/dist/index.css'
    import App from './App.vue'
    
    const app = createApp(App)
    
    app.use(ElementPlus)
    app.mount('#app')

  3. 从ElementPlus官方复制代码到App.vue中,查看效果

    https://element-plus.org/zh-CN/component/button.html

    <script lang="ts" setup>
    </script>
    
    <template>
        <div class="mb-4">
            <el-button>Default</el-button>
            <el-button type="primary">Primary</el-button>
            <el-button type="success">Success</el-button>
            <el-button type="info">Info</el-button>
            <el-button type="warning">Warning</el-button>
            <el-button type="danger">Danger</el-button>
        </div>
    </template>

容器布局

Element的容器布局将页面分成头部区域、侧边栏区域、主区域、底部区域。

https://element-plus.org/zh-CN/component/container.html

<template>
	<div class="common-layout">
		<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>
	</div>
</template>

水平导航栏

https://element-plus.org/zh-CN/component/menu.html

<template>
	<!-- 
		el-menu: 导航栏
			default-active="activeIndex" 默认选中项(值是最终节点索引)
			mode="vertical(垂直)|horizontal(水平)" 
			@select="handleSelect"  选择其中一项时时间
		el-menu-item 没有下一层
			index 索引
		el-sub-menu 有下一层
	-->
	<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" :ellipsis="false"
		@select="handleSelect">
		<el-menu-item index="0">
			xxxx
		</el-menu-item>
		<el-menu-item index="1">Processing Center</el-menu-item>
		<el-sub-menu index="2">
			<template #title>Workspace</template>
			<el-menu-item index="2-1">item one</el-menu-item>
			<el-menu-item index="2-2">item two</el-menu-item>
			<el-menu-item index="2-3">item three</el-menu-item>
			<el-sub-menu index="2-4">
				<template #title>item four</template>
				<el-menu-item index="2-4-1">item one</el-menu-item>
				<el-menu-item index="2-4-2">item two</el-menu-item>
				<el-menu-item index="2-4-3">item three</el-menu-item>
			</el-sub-menu>
		</el-sub-menu>
	</el-menu>
</template>

<script lang="ts" setup>
import { ref } from 'vue'

const activeIndex = ref('2-4-2')

//key 选中项目的索引
const handleSelect = (key: string, keyPath: string[]) => {
	console.log(key, keyPath)
}
</script>

<style>
.el-menu--horizontal>.el-menu-item:nth-child(1) {
	margin-right: auto;
}
</style>

垂直导航栏

垂直菜单,可内嵌子菜单。

https://element-plus.org/zh-CN/component/menu.html

<template>
	<el-row class="tac">
		<!--
			el-menu: 主导航
				class="css样式"
				mode="horizontal|vertical"  导航模式
				background-color="背景色"
				text-color="文字颜色"
				active-text-color="激活文字颜色"
				default-active="3" 激活哪一项 , 激活必须定位到最末级
				@select="选择事件"
			el-menu-item: 子导航(无下级)
				index="2"  索引
			el-submenu: 子导航(有下级)
			@open="handleOpen" @close="handleClose"  开关事件
		-->
		<el-menu active-text-color="#ffd04b" background-color="#545c64" class="el-menu-vertical-demo" default-active="2"
			text-color="#fff" @open="handleOpen" @close="handleClose">
			<el-sub-menu index="1">
				<template #title>
					<el-icon>
						<location />
					</el-icon>
					<span>Navigator One</span>
				</template>
				<el-menu-item-group title="Group One">
					<el-menu-item index="1-1">item one</el-menu-item>
					<el-menu-item index="1-2">item two</el-menu-item>
				</el-menu-item-group>
				<el-menu-item-group title="Group Two">
					<el-menu-item index="1-3">item three</el-menu-item>
				</el-menu-item-group>
				<el-sub-menu index="1-4">
					<template #title>item four</template>
					<el-menu-item index="1-4-1">item one</el-menu-item>
				</el-sub-menu>
			</el-sub-menu>
			<el-menu-item index="2">
				<el-icon><icon-menu /></el-icon>
				<span>Navigator Two</span>
			</el-menu-item>
			<el-menu-item index="3" disabled>
				<el-icon>
					<document />
				</el-icon>
				<span>Navigator Three</span>
			</el-menu-item>
			<el-menu-item index="4">
				<el-icon>
					<setting />
				</el-icon>
				<span>Navigator Four</span>
			</el-menu-item>
		</el-menu>
	</el-row>
</template>

<script lang="ts" setup>
import {
	Document,
	Menu as IconMenu,
	Location,
	Setting,
} from '@element-plus/icons-vue'
const handleOpen = (key: string, keyPath: string[]) => {
	console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
	console.log(key, keyPath)
}
</script>

表格组件

表格组件用于展示多条结构类似的数据,可对数据进行编辑、删除或其他自定义操作

https://element-plus.org/zh-CN/component/table.html

<template>

	<!-- 
		el-table 表格
			data: 表格数据
		el-table-column  列
			prop="从data提供数组的对象中取哪个属性值" 
			label="表头文字"	
	-->
	<el-table :data="tableData" border style="width: 100%">
		<el-table-column prop="date" label="日期" width="180" />
		<el-table-column prop="name" label="Name" width="180" />
		<el-table-column prop="address" label="Address" />
	</el-table>
</template>

<script lang="ts" setup>
const tableData = [
	{
		date: '2016-05-03',
		name: 'Tom',
		address: 'No. 189, Grove St, Los Angeles',
	},
	{
		date: '2016-05-02',
		name: 'Tom',
		address: 'No. 189, Grove St, Los Angeles',
	},
	{
		date: '2016-05-04',
		name: 'Tom',
		address: 'No. 189, Grove St, Los Angeles',
	},
	{
		date: '2016-05-01',
		name: 'Tom',
		address: 'No. 189, Grove St, Los Angeles',
	},
]
</script>

分页组件

当数据量过多时,使用分页分解数据。

https://element-plus.org/zh-CN/component/pagination.html

<template>

	<!-- 
		layout 控制显示哪些内容
		disabled 是否禁用
		background 是否加背景
		total 总记录数
		page-size 每页大小
		current-page 当期页码
		:size="size"  总页数
		:page-sizes="[100, 200, 300, 400]" 前端用的每页大小选择框

		@size-change="handleSizeChange"   每页大小改变时触发事件
		@current-change="handleCurrentChange"  页码改变时触发事件
	-->
	<el-pagination 
		layout="total, sizes, prev, pager, next, jumper"
		:disabled="disabled" 
		:background="background" 
		:total="400"
		:page-sizes="[100, 200, 300, 400]"
		:size="size" 
		v-model:current-page="currentPage4" 
		v-model:page-size="pageSize4" 
			
		@size-change="handleSizeChange" 
		@current-change="handleCurrentChange"
	/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import type { ComponentSize } from 'element-plus'
const currentPage1 = ref(5)
const currentPage2 = ref(5)
const currentPage3 = ref(5)
const currentPage4 = ref(4)
const pageSize2 = ref(100)
const pageSize3 = ref(100)
const pageSize4 = ref(100)
const size = ref<ComponentSize>('default')
const background = ref(false)
const disabled = ref(false)

const handleSizeChange = (val: number) => {
	console.log(`${val} items per page`)
}
const handleCurrentChange = (val: number) => {
	console.log(`current page: ${val}`)
}
</script>

<style scoped>
.demo-pagination-block+.demo-pagination-block {
	margin-top: 10px;
}

.demo-pagination-block .demonstration {
	margin-bottom: 16px;
}
</style>

设置中文: Vue3项目给ElementPlus设置中文的两个方案_vue elementplus 切换语言-CSDN博客

对话框

在保留当前页面状态的情况下,弹出一个子窗口,完成操作

https://element-plus.org/zh-CN/component/dialog.html


<template>
	<!-- 按钮 -->
	<el-button plain @click="dialogFormVisible = true">
		Open a Form nested Dialog
	</el-button>

	<!-- 
		dialogFormVisible : 控制对话框是否显示

	-->
	<!-- 对话框 -->
	<el-dialog v-model="dialogFormVisible" title="Shipping address" width="500">
		
		<!-- 表单 -->
		<el-form :model="form">
			<el-form-item label="Promotion name" :label-width="formLabelWidth">
				<el-input v-model="form.name" autocomplete="off" />
			</el-form-item>
			<el-form-item label="Zones" :label-width="formLabelWidth">
				<el-select v-model="form.region" placeholder="Please select a zone">
					<el-option label="Zone No.1" value="shanghai" />
					<el-option label="Zone No.2" value="beijing" />
				</el-select>
			</el-form-item>
		</el-form>

		<!-- 小按钮 -->
		<template #footer>
			<div class="dialog-footer">
				<el-button @click="dialogFormVisible = false">Cancel</el-button>
				<el-button type="primary" @click="dialogFormVisible = false">
					Confirm
				</el-button>
			</div>
		</template>
	</el-dialog>
</template>

<script lang="ts" setup>
import { reactive, ref } from 'vue'

const dialogTableVisible = ref(false)
const dialogFormVisible = ref(false)  //控制对话框是否显示
const formLabelWidth = '140px'

const form = reactive({
	name: '',
	region: '',
	date1: '',
	date2: '',
	delivery: false,
	type: [],
	resource: '',
	desc: '',
})


</script>

表单组件

表单组件由输入框、下拉列表、单选框、多选框等控件组成,用以收集、校验、提交数据。

https://element-plus.org/zh-CN/component/form.html

<template>
	<el-form :model="form" label-width="auto" style="max-width: 600px">
		<el-form-item label="Activity name">
			<el-input v-model="form.name" />
		</el-form-item>
		<el-form-item label="Activity zone">
			<el-select v-model="form.region" placeholder="please select your zone">
				<el-option label="Zone one" value="shanghai" />
				<el-option label="Zone two" value="beijing" />
			</el-select>
		</el-form-item>
		<el-form-item label="Activity time">
			<el-col :span="11">
				<el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%" />
			</el-col>
			<el-col :span="2" class="text-center">
				<span class="text-gray-500">-</span>
			</el-col>
			<el-col :span="11">
				<el-time-picker v-model="form.date2" placeholder="Pick a time" style="width: 100%" />
			</el-col>
		</el-form-item>
		<el-form-item label="Instant delivery">
			<el-switch v-model="form.delivery" />
		</el-form-item>
		<el-form-item label="Activity type">
			<el-checkbox-group v-model="form.type">
				<el-checkbox value="Online activities" name="type">
					Online activities
				</el-checkbox>
				<el-checkbox value="Promotion activities" name="type">
					Promotion activities
				</el-checkbox>
				<el-checkbox value="Offline activities" name="type">
					Offline activities
				</el-checkbox>
				<el-checkbox value="Simple brand exposure" name="type">
					Simple brand exposure
				</el-checkbox>
			</el-checkbox-group>
		</el-form-item>
		<el-form-item label="Resources">
			<el-radio-group v-model="form.resource">
				<el-radio value="Sponsor">Sponsor</el-radio>
				<el-radio value="Venue">Venue</el-radio>
			</el-radio-group>
		</el-form-item>
		<el-form-item label="Activity form">
			<el-input v-model="form.desc" type="textarea" />
		</el-form-item>
		<el-form-item>
			<el-button type="primary" @click="onSubmit">Create</el-button>
			<el-button>Cancel</el-button>
		</el-form-item>
	</el-form>
</template>

<script lang="ts" setup>
import { reactive } from 'vue'

// do not use same name with ref
const form = reactive({
	name: '',
	region: '',
	date1: '',
	date2: '',
	delivery: false,
	type: [],
	resource: '',
	desc: '',
})

const onSubmit = () => {
	console.log('submit!')
}
</script>

综合案例

,,

<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import {
	Aim,
	Document,
	Menu as IconMenu,
	Location,
	Setting,
	Timer
} from '@element-plus/icons-vue'
import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { ComponentSize } from 'element-plus'

//查询学生列表
const pageNum = ref(1) //当前页
const pageSize = ref(5) //每页条数
const total = ref(0) //总记录数
const size = ref<ComponentSize>('default')
const handleSizeChange = (val: number) => {
	findList();
}
const handleCurrentChange = (val: number) => {
	findList();
}
const studentList = ref([])
const findList = function () {
	//发送请求
	// axios.get("http://localhost:8090/student").then(resp => {
	// 	studentList.value = resp.data.data;
	// })
	axios.get("http://localhost:8090/student/findByPage", {
		params: {
			pageNum: pageNum.value,
			pageSize: pageSize.value
		}
	}).then(resp => {
		total.value = resp.data.data.total;
		studentList.value = resp.data.data.rows;
	})
}

//新增学生
const studentAddFrom = ref({}) //封装添加框数据
const addFormVisible = ref(false) //控制添加框显示
const addStudent = function () {
	//发送请求
	axios.post('http://localhost:8090/student', studentAddFrom.value).then(resp => {
		if (resp.data.code == 1) {
			//1. 关闭窗口
			addFormVisible.value = false
			//2. 清空添加框
			studentAddFrom.value = {}
			//3. 重新查询
			findList();
		}
	})
}


//修改学生
const studentUpdateFrom = ref({}) //封装添加框数据
const updateFormVisible = ref(false) //控制添加框显示
//点击修改框
const handleEdit = (index, row) => {
	//打开修改框
	updateFormVisible.value = true

	//根据id查询
	axios.get("http://localhost:8090/student/" + row.id).then(resp => {
		studentUpdateFrom.value = resp.data.data
	})

	//console.log(index, row.id)
}
//点击修改框修改按钮
const updateStudent = function () {
	//发送请求
	axios.put('http://localhost:8090/student', studentUpdateFrom.value).then(resp => {
		if (resp.data.code == 1) {
			//1. 关闭窗口
			updateFormVisible.value = false
			//2. 清空添加框
			studentUpdateFrom.value = {}
			//3. 重新查询
			findList();
		}
	})
}


//删除
const handleDelete = (index, row) => {
	ElMessageBox.confirm(
		'您是否确认要删除本条记录?',
		'',
		{
			confirmButtonText: '确认',
			cancelButtonText: '取消',
			type: 'warning',
		}
	).then(() => {
		axios.delete("http://localhost:8090/student/" + row.id).then(resp => {
			if (resp.data.code == 1) {
				findList();
				ElMessage({
					type: 'success',
					message: '删除成功',
				})
			}
		})
	})
}

//页面加载完毕
onMounted(function () {
	findList();
})

</script>


<template>

	<!-- 主界面 -->
	<div class="common-layout">
		<el-container>
			<el-header>
				<el-menu class="el-menu-demo" mode="horizontal" background-color="#545c64" text-color="#fff"
					active-text-color="#ffd04b">
					<el-menu-item index="1">Export</el-menu-item>
					<el-menu-item index="3">处理中心</el-menu-item>
					<el-sub-menu index="2">
						<template #title>我的工作台</template>
						<el-menu-item index="2-1">item one</el-menu-item>
						<el-menu-item index="2-2">item two</el-menu-item>
						<el-menu-item index="2-3">item three</el-menu-item>
					</el-sub-menu>
					<el-menu-item index="4" style="width: 400px">首页</el-menu-item>
				</el-menu>
			</el-header>
			<el-container>
				<el-aside width="200px">
					<el-menu default-active="1-1" class="el-menu-vertical-demo">
						<el-sub-menu index="1">
							<template #title>
								<el-icon>
									<location />
								</el-icon>
								<span>学工部</span>
							</template>
							<el-menu-item index="1-1"><el-icon>
									<Aim />
								</el-icon>在校学生管理</el-menu-item>
							<el-menu-item index="1-2"><el-icon>
									<Aim />
								</el-icon>学生升级/留级</el-menu-item>
							<el-menu-item index="1-3"><el-icon>
									<Aim />
								</el-icon>学生就业情况</el-menu-item>
						</el-sub-menu>
						<el-sub-menu index="2">
							<template #title>
								<el-icon>
									<Setting />
								</el-icon>
								<span>咨询部</span>
							</template>
							<el-menu-item index="2-1">在校学生管理</el-menu-item>
							<el-menu-item index="2-2">学生升级/留级</el-menu-item>
							<el-menu-item index="2-3">学生就业情况</el-menu-item>
						</el-sub-menu>
						<el-sub-menu index="3">
							<template #title>
								<el-icon>
									<Document />
								</el-icon>
								<span>教研部</span>
							</template>
							<el-menu-item index="3-1">在校学生管理</el-menu-item>
							<el-menu-item index="3-2">学生升级/留级</el-menu-item>
							<el-menu-item index="3-3">学生就业情况</el-menu-item>
						</el-sub-menu>
					</el-menu>


				</el-aside>
				<el-main>
					<div>
						<span style="font-weight: bold;color: red;">学生列表</span>
						<el-button type="primary" style="float: right;" @click="addFormVisible = true">添加学生</el-button>
					</div>
					<div>
						<el-table :data="studentList" style="width: 100%">
							<el-table-column prop="id" label="学号" width="180" />
							<el-table-column prop="name" label="姓名" width="180" />
							<el-table-column prop="birthday" label="生日" width="180" />
							<el-table-column prop="address" label="地址" width="180" />
							<el-table-column label="操作">
								<template #default="scope">
									<el-button type="warning" @click="handleEdit(scope.$index, scope.row)">
										编辑
									</el-button>
									<el-button type="danger" @click="handleDelete(scope.$index, scope.row)">
										删除
									</el-button>
								</template>
							</el-table-column>
						</el-table>
					</div>
					<div style="margin-top: 10px;">
						<el-pagination layout="total, sizes, prev, pager, next, jumper" v-model:current-page="pageNum"
							v-model:page-size="pageSize" :page-sizes="[5, 10, 15]" :size="size" :total="total"
							@size-change="handleSizeChange" @current-change="handleCurrentChange" />
					</div>
				</el-main>
			</el-container>
		</el-container>
	</div>

	<!-- 添加框 -->
	<el-dialog v-model="addFormVisible" title="添加学生信息" width="500">
		<el-form :model="studentFrom">
			<el-form-item label="学生学号">
				<el-input v-model="studentAddFrom.id" />
			</el-form-item>
			<el-form-item label="学生姓名">
				<el-input v-model="studentAddFrom.name" />
			</el-form-item>
			<el-form-item label="学生生日">
				<el-input v-model="studentAddFrom.birthday" />
			</el-form-item>
			<el-form-item label="学生地址">
				<el-input v-model="studentAddFrom.address" />
			</el-form-item>
		</el-form>
		<template #footer>
			<div class="dialog-footer">
				<el-button type="primary" @click="addStudent()">添加</el-button>
				<el-button @click="addFormVisible = false">重置</el-button>

			</div>
		</template>
	</el-dialog>



	<!-- 修改框 -->
	<el-dialog v-model="updateFormVisible" title="修改学生信息" width="500">
		<el-form :model="studentFrom">
			<el-form-item label="学生学号">
				<el-input v-model="studentUpdateFrom.id" />
			</el-form-item>
			<el-form-item label="学生姓名">
				<el-input v-model="studentUpdateFrom.name" />
			</el-form-item>
			<el-form-item label="学生生日">
				<el-input v-model="studentUpdateFrom.birthday" />
			</el-form-item>
			<el-form-item label="学生地址">
				<el-input v-model="studentUpdateFrom.address" />
			</el-form-item>
		</el-form>
		<template #footer>
			<div class="dialog-footer">
				<el-button type="primary" @click="updateStudent()">修改</el-button>
				<el-button @click="updateFormVisible = false">重置</el-button>
			</div>
		</template>
	</el-dialog>
</template>


<style>
.el-menu--horizontal>.el-menu-item:nth-child(1) {
	margin-right: auto;
}
</style>

标签:Vue,const,data,基础,vue,组件,import,ref
From: https://blog.csdn.net/w13114/article/details/141790110

相关文章

  • SprinBoot+Vue校园活动报名微信小程序的设计与实现
    目录1项目介绍2项目截图3核心代码3.1Controller3.2Service3.3Dao3.4application.yml3.5SpringbootApplication3.5Vue3.6uniapp代码4数据库表设计5文档参考6计算机毕设选题推荐7源码获取1项目介绍博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优......
  • OHIF Viewer 基础查看器的相关
    新版的ohif 封装的很好,跟3.8版本的 viewer修改成app  ui组件进行了整改3.9版本的更新OHIFViewer3.9相对于3.8版本进行了多项改进和更新。以下是一些主要的改进点:1.性能优化:在3.9版本中,团队对性能进行了优化,特别是针对大型数据集的加载和渲染速度,减少了延......
  • vue 批量自动引入并注册组件或路由
    有时候有大量的组件.vue后缀的,或.js,或.ts文件,需要一个个的手动引入很麻烦,那么你可以尝试这样创建一个index.js本项目使用vue3.x,vue2.x也可以照样用;这里在components里面创建了一个idnex.js文件require.context可以读取文件,第一个参数是指当前文件夹,第二个参......
  • WiFi基础(二):最新WiFi信道、无线OSI模型与802.11b/g/n
    liwen012024.09.01前言最近十几年,通信技术发展迅猛,通信标准更新频繁,有的设备还在使用802.11/b/g/n协议,有的已支持到WiFi6、WiFi7。而国内有关无线WiFi的书籍或资料却很少,就算能找着的,大多也是比较老旧。本文试图使用最新的数据来介绍WiFi相关的一些基础知识。关于WiF......
  • Day12_0.1基础学习MATLAB学习小技巧总结(12)——程序流程控制3-switch结构
    利用空闲时间把碎片化的MATLAB知识重新系统的学习一遍,为了在这个过程中加深印象,也为了能够有所足迹,我会把自己的学习总结发在专栏中,以便学习交流。素材来源“数学建模清风”特此说明:本博客的内容只在于总结在使用matlab中的一些小技巧,并非教程,若想系统的学习MATLAB,也可以移步......
  • 基于SpringBoot+Vue+uniapp的医院在线挂号预约系统的+jsp的详细设计和实现(源码+lw+部
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • Vue, Avoided redundant navigation to current location: "/login".
    VueAvoidedredundantnavigationtocurrentlocation:"/login".=================================报错解释:这个错误是在使用Vue.js框架时,发生的一个警告,表示尝试进行一个冗余的导航到当前位置(即“/login”路径)。这通常发生在VueRouter中,当你尝试通过编程方式导航到当前正......
  • RabbitMQ 队列使用基础教程
    实践环境JDK1.8.0_121amqp-client5.16.0附:查看不同版本的amqp-client客户端支持的JavaJDK版本https://www.rabbitmq.com/client-libraries/java-versionsmavnsettings.xml<?xmlversion="1.0"encoding="UTF-8"?><settingsxsi:schemaLocation="h......
  • 有没有办法在vue中设置route prop?
    在Vue中,你可以通过路由配置对象来设置路由的prop。以下是一个示例:constroutes=[{path:'/your-path',component:YourComponent,props:true//启用路由的prop传递}];在上述示例中,我们将props属性设置为true,这意味着路由将把路由参数作为属性传......
  • 从Vue的Weex迁移到Rax Weex
    据说:rax几乎没啥使用文档,有问题直接查询react官方文档,屡试屡爽目前没有实践过,先存下一言生成的文档:从Vue的Weex迁移到RaxWeex涉及到从一种前端框架(Vue)到另一种框架(Rax)的转换,同时保持与Weex的兼容性。由于Weex本身是一个跨平台的移动开发框架,支持Vue和Rax等多种前端框架,迁移......