从零开始学习vue3.2项目开发

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

参考B站视频

Vue3后台管理系统项目实战/vue+element-plus/vue经典全套系统案例讲解
Vue2后台管理系统项目实战/vue+element-ui/vue经典全套系统案例讲解
Vue3后台管理系统项目实战/vue+element-plus/vue经典全套系统案例讲解
前端精品课】用Vue3.0全家桶实现后台管理系统搭建/前端/Vue3的新特性
若依权限系统ruoyi前端版
在这里插入图片描述

1、vue创建项目和打包

1.1 安装node 版本

node版本

npm -v 
8.19.2
node -v
v18.12.1

1.2 打开vscode创建vue项目

vie官网https://cn.vitejs.dev/guide/
vie 创建vue项目

npm create vite@latest vue-test-new -- --template vue

# npm 7+, extra double-dash is needed: 官方样例
npm create vite@latest my-vue-app -- --template vue

选择 vue 和 javascript

PS E:\AH\fs\vuepro> npm create vite@latest vue-admin-learn -- --template vue
√ Select a framework: » Vue
√ Select a variant: » JavaScript

Scaffolding project in E:\AH\fs\vuepro\vue-admin-learn...

Done. Now run:

  cd vue-admin-learn
  npm install
  npm run dev

1.3 查看vite和vue版本信息

package.json

{
  "name": "vue-test-new",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.2.45"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.0.0",
    "vite": "^4.1.0"
  }
}

1.4 运行项目

在这里插入图片描述

1.5 打包项目

npm run build 

生成dist文件夹,使用nginx进行部署项目

1.6 安装插件自动导入vue模块

1.7 其他可忽略

1.8 解决加载vue时显示的 vite +vue字段vue项目初始化

在这里插入图片描述

2、添加路由vue-router

2.1. 安装vue-router

官网https://router.vuejs.org/zh/installation.html

npm install vue-router@4

2.2. 所需要修改的内容

  1. 创建 /src/router/index.js
import { createRouter, createWebHistory } from "vue-router";
import HelloWorld from "../components/HelloWorld.vue"
const routes = [{
    path: "/",
    component: HelloWorld,
    meta: {
        title: "前端学习"
    }
}]
const router = createRouter({
    history: createWebHistory(),
    routes
})
router.beforeEach((to, from, next) => {
    if (to.meta.title) {
        // console.log(to.meta.title)
        document.title = to.meta.title
    }
    next()
})
export default router
  1. 加载路由/src/main.js
import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router)
app.mount('#app')
  1. router-view的使用 APP.vue
<script setup>
</script>

<template>
    <router-view></router-view>
</template>

<style>
/* 清除标签中的默认边框宽度 */
* {
  margin: 0;
  padding: 0;
  height: 100%;
}
</style>
  1. 修改vue页面 /src/components/HelloWorld.vue
<script setup>
</script>

<template>
    <div>
        hello world
    </div>
</template>

<style scoped>
</style>

2.3 效果展示

npm run dev 

在这里插入图片描述
在这里插入图片描述

3、element-plus组件引入

官网https://element-plus.gitee.io/zh-CN/

3.1 安装element-plus

npm install element-plus --save

3.2 完全引入

// main.ts
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)

最终文件内容

// main.ts
import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(router)
app.use(ElementPlus)
app.mount('#app')

在HelloWorld.vue中使用按钮组件

<script setup>
</script>

<template>
    <div>
        hello world
        <el-row 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>
        </el-row>
    </div>
</template>

<style scoped>
</style>

3.3 效果展示

npm run dev 

在这里插入图片描述

4、创建其他路由

4.1 新建文件

src/views/Login/index.vue
src/views/Layout/index.vue

4.2 快速创建index.vue 内容

在文件中输入vue 按照下图提示选择
在这里插入图片描述
生成模板如下

<template>
  
</template>

<script>
export default {

}
</script>

<style>

</style>

4.3 在各自的vue文件中添加内容

src/views/Login/index.vue

<template>
    <h2>login</h2>
</template>

<script>
export default {

}
</script>

<style>

</style>

src/views/Layout/index.vue

<template>
    <h2>layout</h2>
</template>

<script>
export default {

}
</script>

<style>

</style>

4.4 添加路由到路由文件中

src/router/index.js

import { createRouter, createWebHistory } from "vue-router";
import HelloWorld from "../components/HelloWorld.vue"
import Layout from '../views/Layout/index.vue'
import Login from '../views/Login/index.vue'

const routes = [{
        path: "/",
        component: HelloWorld,
        meta: {
            title: "前端学习"
        }
    },
    {
        path: "/layout",
        component: Layout,
        meta: {
            title: "首页布局"
        }
    },
    {
        path: "/login",
        component: Login,
        meta: {
            title: "登录"
        }
    }
]
const router = createRouter({
    history: createWebHistory(),
    routes
})
router.beforeEach((to, from, next) => {
    if (to.meta.title) {
        // console.log(to.meta.title)
        document.title = to.meta.title
    }
    next()
})
export default router

4.5 效果展示

在这里插入图片描述
在这里插入图片描述

4.6 不存路由返回404页面

参考

  1. vue3.0使用vue-router4.x配置路由* 404页面控制台报错
  2. 捕获所有路由或 404 Not found 路由
    在这里插入图片描述
    添加404路由 src/router/index.js
//导入文件
import NotFound from '../views/NotFound/404.vue'

/router下添加如下内容
    {
        path: '/404',
        name: '404',
        component: NotFound,
        meta: {
            title: "error"
        }
    },
    {
        path: '/:pathMatch(.*)',
        redirect: '/404'
    }

404页面的vue内容

<script setup>

</script>

<template>
    <div>
        404,  抱歉你访问的页面不存在
    </div>
</template>

<style>

</style>
  • 效果展示
    在这里插入图片描述

5、使用Normalize.css对vue项目样式初始化

5.1 安装normalize.css

npm install normalize.css

5.2 引入样式文件

//main.js
import 'normalize.css'
import './assets/css/base.css'

./assets/css/base.css 内容如下

h1,
h2,
h3,
p,
ul,
li {
    margin: 0;
    padding: 0;
}
a {
    list-style: none;
}
ul {
    list-style: none;
}

6、layout页面设计

6.1 使用element-plus进行menu菜单设计

6.2 vue代码格式化

6.3 element-plus-icon 不显示问题

需要安装单独的icon插件
参考 npm install -g @vue/cli 源文本中存在无法识别的标记。
在这里插入图片描述

npm install '@element-plus/icons-vue'

在这里插入图片描述

6.4 开启路由模式

添加 router, index由数字变成 路由
在这里插入图片描述

6.5 路由跳转

router/index.js中使用children配置路由跳转

7、折叠左侧菜单

7.1 重写样式可覆盖默认的样式

在这里插入图片描述
在这里插入图片描述

7.2 cursor: pointer; 样式

  • 配置了此属性时当鼠标点到此icon时会变为手的形状
    在这里插入图片描述

7.3 父传子数据

7.4 v-bind绑定class

8、content中的header中右上角显示时间

8.1 显示位置的布局

8.2 dayjs获取格式化时间

npm install dayjs
let time = ref(null)
onMounted(() => { 
    time.value = dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
    // console.log(time);
})

9、后端server环境搭建gin框架实现

  • 后端代码采用golang gin框架实现可以自行更具文档说明学习gin框架内容在这里感谢GinSkeleton的作者开源了此框架gitee地址如下
  • gitee地址 GinSkeleton

9.1 代码下载

git clone https://gitee.com/daitougege/GinSkeleton.git

9.2 golang运行此环境

9.2.1 mysql8.0.30环境的安装和使用

  • 欢迎点赞和收藏
    参考链接msyql8.0.30安装和使用
    使用sqlyog客户端管理mysql
    本文采用mysql5.7.34进行演示各位可以安装8.0.30版本都差不多

9.2.2 使用sqlyog创建数据库

在这里插入图片描述

9.2.3 根据ginscelenton文档配置数据库

  • 数据库信息根据个人的mysql数据库信息进行配置图中只是样例
    在这里插入图片描述

9.2.4 运行项目

在这里插入图片描述

9.2.5 后台服务测试

访问 http://localhost:20201/

在这里插入图片描述

9.2.6 自定义表名操作数据库

9.3 GinSkeleton默认允许跨域

在这里插入图片描述

9.4 gin框架接口的使用

func main() {
   // 1.创建路由
   r := gin.Default()
   // 路由组1 处理GET请求
   v1 := r.Group("api/v1")
   // {} 是书写规范
   {
      v1.GET("/register", register)
      v1.GET("login", login)
   }
   v2 := r.Group("api/v2")
   {
      v2.POST("/register", register)
      v2.POST("/login", login)
   }
   r.Run(":8000") // 开启端口在8000
}

func login(c *gin.Context) {
   name := c.DefaultQuery("name", "jack")
   c.String(http.StatusOK, fmt.Sprintf("hello %s\n", name))
}

func register(c *gin.Context) {
   name := c.DefaultQuery("name", "lily")
   c.String(http.StatusOK, fmt.Sprintf("hello %s\n", name))
}
type Msg struct{
	Name    string `json:"user"`
	Message string
	Number  int
}
r.GET("/moreJSON", func(c *gin.Context) {
        msg.Name = "Lena"
        msg.Message = "hey"
        msg.Number = 123
        // 会输出  {"user": "Lena", "Message": "hey", "Number": 123}
        c.JSON(http.StatusOK, msg)
    })

9.5 gin 中使用gorm创建表单并且插入数据

  • 数据库名一般使用下划线 _ 连接词不要使用 -
    -例子 使用 vue_admin, 不使用vue-admin
import "goskeleton/app/global/variable"
func InsertGoods(c *gin.Context) {
	var goodsInfo GoodsModel
	//variable.GormDbMysql 是全局的mysql连接客户端
	DB := variable.GormDbMysql
	timeStr := time.Now().Format("2006-01-02 15:04:05")
	goodsInfo = GoodsModel{
		CreatedTime: timeStr,
		UpdatedTime: timeStr,
		Title:       "苹果",
		Price:       10.3,
		Category:    "水果",
		SellPoint:   "好吃",
		Desc:        "品牌",
	}
	//指定数据库的名称进行操作AutoMigrate会判断表是否存在不存在会自动创建表
	DB.Table("goods_info").AutoMigrate(&GoodsModel{})
	//往表中插入数据一条数据
	DB.Table("goods_info").Create(&goodsInfo)
}

9.6 mysql数据库中limit使用详解用作分页显示数据

select * from table_name limit 10;//检索前10行记录
select * from table_name limit 5 10;//从第6行开始检索10行记录即检索记录行 6-15

9.7 restfull风格介绍

9.8 如何利用sqlmapapi发起扫描

9.7 gorm 的增删改查参看文档

gorm官网地址https://gorm.io/docs/query.html#Retrieving-all-objects

//Retrieving all objects
// Get all records
result := db.Find(&users)
// SELECT * FROM users;

result.RowsAffected // returns found records count, equals `len(users)`
result.Error        // returns error
//Limit & Offset
db.Limit(3).Find(&users)
// SELECT * FROM users LIMIT 3;

// Cancel limit condition with -1
db.Limit(10).Find(&users1).Limit(-1).Find(&users2)
// SELECT * FROM users LIMIT 10; (users1)
// SELECT * FROM users; (users2)

db.Offset(3).Find(&users)
// SELECT * FROM users OFFSET 3;

db.Limit(10).Offset(5).Find(&users)
// SELECT * FROM users OFFSET 5 LIMIT 10;

// Cancel offset condition with -1
db.Offset(10).Find(&users1).Offset(-1).Find(&users2)
// SELECT * FROM users OFFSET 10; (users1)
// SELECT * FROM users; (users2)

9.8 Golang 获取系统信息的实现

https://www.jb51.net/article/250242.htm

9.9 goland配置设置file watchers以自动导包和fmt格式化代码

https://blog.51cto.com/zhangxueliang/5342587

10、axios请求封装以及api接口的定义

10.1 axios的安装

参考

npm install axios

10.2 效果展示 前后端数据已打通

在这里插入图片描述

10.3 vue3接收处理后端json对象

//方法一
// let homeCount = reactive({ data: {} })
// homeCount.data = res.data
//方法二
// 此homeCount不能用const定义
// let homeCount = reactive({
//     sale_total: 0,
//     sale: 0,
//     views_total: 0,
//     views: 0,
//     pay_total: 0,
//     pay: 0,
//     collect_total: 0,
//     collect: 0
// });
// Object.assign(homeCount, res.data);

//方法3
let homeCount = ref({})
// homeCount.value = res.data

onMounted(() => {
    api.getHomeCount().then(res => {
        // console.log("获取首页统计数据", res.data);
        //使用Object.assign()进行对象的赋值不使用直接赋值,直接赋值会影响响应式
        // homeCount.data = res.data
        // Object.assign(homeCount, res.data);
        homeCount.value = res.data
    });
});

10.5 less样式

npm install less

在这里插入图片描述

11、echarts图表的使用按需导入

11.1 安装

npm install echarts

11.2 官网echarts的实例

在这里插入图片描述
在这里插入图片描述

11.3 目前首页效果展示

使用 element-plus 的 card组件进行做底部三个card框
在这里插入图片描述

12、产品管理-产品列表页

12.1 使用element-plus行内表单

在这里插入图片描述

12.2 使用element-plus table 创建商品列表表单

在这里插入图片描述

# mysql 的命令
SHOW DATABASES;
USE vue_admin_learn;
SELECT * FROM goods_info;
SELECT * FROM goods_info LIMIT 3;
DROP TABLE goods_info;

12.3 商品列表前后端联调显示

在这里插入图片描述

12.4 分页器实现

分页组件其他页面也可以使用因此放到components里面
使用element-plush组件实现

<template>
    <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        layout="total, prev, pager, next, jumper"
        :total="total"
        @current-change="handleCurrentChange"
    />
</template>

<script setup>
import { ref } from "vue";

const currentPage = ref(1);
const pageSize = ref(1);
const total = ref(10)
//ts 语法
// const handleCurrentChange = (val: number) => {
//   console.log(`current page: ${val}`)
// }
//js 语法
const handleCurrentChange = (val) => {
    console.log(`current page: ${val}`);
};
</script>

<style>
</style>

效果如下
在这里插入图片描述

12.5 分页组件中 total 英文转中文显示

  • 参考Element-Plus 分页组件由默认英文改为中文

  • 在 main.js 中添加以下两句语句

    import locale from 'element-plus/lib/locale/lang/zh-cn'
    app.use(ElementPlus, { locale });
    
  • 效果如下
    在这里插入图片描述
    在这里插入图片描述

  • 更具页码 查询到本页数据并且返回总的数据量的gorm写法
    参考 gorm查询条件中带有limit的同时查询count总条数

    type GetGoodsResponse struct {
    	Count int64        `json:"count"`
    	Data  []GoodsModel `json:"data"`
    }
    var goodsInfo GetGoodsResponse
    result := goodsDb.Limit(10).Offset(-1).Find(&goodsInfo.Data).Limit(-1).Offset(-1).Count(&goodsInfo.Count)
    

12.6 根据名称查询商品

用到子传父父传子请求调用函数的async

12.7 添加商品

路由跳转

import { useRouter } from "vue-router";
const router = useRouter()
// 点击添加商品
const addGoodsEvent = () => { 
    router.push('/goods/addgoods')
}

12.8 删除商品成功和失败提示

import { ElMessage } from 'element-plus'
ElMessage({
    message: 'Congrats, this is a success message.',
    type: 'success',
  })
  
ElMessage.error('Oops, this is a error message.')

12.9 vue post请求发送数据问题

 // 添加请求拦截器
request.interceptors.request.use(function(config) {
    // 在发送请求之前做些什么
    if (config.method == "post") {
        // config.headers["Content-Type"] = "application/json"
        config.headers["Content-Type"] = "application/form-data"
        console.log("data is ", config.data)
    }
    return config;
}, function(error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});
  • post 请求和get请求的区别是后面的参数不加{} 否则会回导致数据接收失败问题
    // 7、商品类目选择
    goodsItemCategory(params) {
        return request.get(base.goodsCategory, { params })
    },
    // 8.添加商品
    addGoods(params) {
        return request.post(base.addGoods, params)
    },

12.10 form表单中的数字总数当作字符串问题

<el-input v-model.number="goodsForm.price" type="number" placeholder="请输入商品价格"></el-input>
//v-model.number 绑定变量表示限制字符串输入传给后端的数据也是数字了

vue 限制输入是数字& 接口参数为数字而非字符

12.11 删除商品列表中的数据之后子组件分页未更新导致数据显示和分页数据不一致问题解决

vue 强制组件重新渲染重置

12.12 循环遍历的 forEach的使用

// 批量删除选择框table - form操作获取选择的id列表
const changeTable = (val) => {
    let arr = []
    val.forEach(ele => {
        arr.push(ele.id)
    });
    console.log("选中的id ", arr)
}

12.13 使用pinia实现兄弟组件之间的数据共享

npm install pinia
  • main.js全局导入
import { createPinia } from 'pinia'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
  • 使用pinia
    创建store文件夹创建**.js文件
import { defineStore } from 'pinia'
export const useGoodsStore = defineStore('goods', {
    state: () => ({
        rowData: {},
        title: "添加"
    }),
    getters: {

    },
    actions: {
        // 设置数据
        changeTitle(playload) {
            this.title = playload
        },
        changeRowData(playload) {
            this.rowData = playload
        },
        // 清空
        clearGoods() {
            this.title = "添加"
            this.rowData = {}
        }

    },
})
  • 在组建中导入 -存入数据到store
import { useGoodsStore } from "../../store/Goods"
const goodsStore = useGoodsStore()
const handleEdit = (index, row) => {
    console.log("编辑商品", row)
    goodsStore.changeTitle("编辑")
    goodsStore.changeRowData(row)
    routerJump.push('/goods/addgoods')
};
  • 兄弟组件读取store数据
import { useGoodsStore } from "../../store/Goods"
const goodsStore = useGoodsStore()
//直接使用
goodsStore.title == "编辑"

13 产品类型页面

13.1 vue中ref值的修改要使用.value

  • 不要忘记-- 不要忘记- 不要忘记
const dialogVisible = ref(false)
const submit= ()=>{
	dialogVisible.value = true
}

13.2 vite项目构建优化chunkSizeWarningLimit

在这里插入图片描述

//vite/config.js中添加一下代码
build: {
        chunkSizeWarningLimit: 1000,
        rollupOptions: {
            output: {
                manualChunks(id) {
                    if (id.includes('node_modules')) {
                        return id.toString().split('node_modules/')[1].split('/')[0].toString();
                    }
                }
            }
        }

    }

在这里插入图片描述

13.3 vue项目index.html修改

在这里插入图片描述

  • 图片需要放在public下
    放到public目录下是为了打包的时候会自动把public目录下的图片放到index.html同级目录中nginx部署是可以直接访问到

14 路由重定向

	{
        path: "/",
        redirect: "/redirect",
    },
	{
	    path: "/redirect",
	    component: WechatCode,
	},

15 背景图片铺满全屏

// vue代码示例
<template>
    <div class="homeIndex"></div>
</template>

.homeIndex {
    background: url("../../assets/scan_background.jpg");
    background-size: 100% 100%;
    height: 100%;
    position: fixed;
    width: 100%;
}

16 vue3路由useRoute和useRouter区别用法

17 vue3中现先请求后端数据再进行页面渲染问题

使用 async 和 await , await 会等响应完成之后在进行后面的操作 如下的例子

const scanCodeInfo= async () => {
    let res = await api.scanCodeInfo().then(res => {
        let { data, errorCode } = res.data;
        console.log("resdata is ---", res.data);
        console.log("token data is ---", data);
        console.log(errorCode);
        qrCodeParams.appid = data.appid;
        qrCodeParams.scanCodeUrl = data.scanCodeUrl;

        console.log(qrCodeParams.appid);
        console.log(qrCodeParams.scanCodeUrl);
    });
    // isShow.value =true
    console.log("ttttttttttttttttttttt")
    GetWechatCode(qrCodeParams);

};

18 vue3.0 router路由跳转传参router.push

https://blog.csdn.net/animatecat/article/details/117257037

19 vue3 跳转页面方法

2.在当前窗口打开新页面

window.location.href = “/classDel”
window.top.location.href = “/classDel”
​​​​​​​window.open(“/videoAd?id=” + e.id)
​​​​​​​window.top.open(“/videoAd?id=” + e.id)

const router = useRouter()
router.push(“/apphome”)

参考
window.location与window.open()的区别 "top.location.href"是最外层的页面跳转
如何实现vue3界面跳转这些代码你该记住~

20 vue3 aes加密和base64加密

//npm install crypto-js
// npm install js-base64

import CryptoJS from 'crypto-js'
// 默认的 KEY 与 iv 如果没有给
const key = CryptoJS.enc.Utf8.parse("D3]-eFJt@=v>yFQ>"); //""中与后台一样  密码
const iv = CryptoJS.enc.Utf8.parse('Ft%HorNZ9xo4w)P#'); //""中与后台一样  偏移量
/**
 * AES加密 字符串 key iv  返回base64
 */
export function Encrypt(word) {
    let srcs = CryptoJS.enc.Utf8.parse(word);
    var encrypted = CryptoJS.AES.encrypt(srcs, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    console.log("加密后");
    console.log(encrypted);
    console.log("base64加密");
    console.log(CryptoJS.enc.Base64.stringify(encrypted.ciphertext))
        // return CryptoJS.enc.Hex.stringify(encrypted.ciphertext);
    return CryptoJS.enc.Base64.stringify(encrypted.ciphertext); //返回base64格式密文

}

/**
 * AES 解密 字符串 key iv  返回base64
 *  */
export function Decrypt(word) {
    let base64 = CryptoJS.enc.Base64.parse(word);
    let src = CryptoJS.enc.Base64.stringify(base64);

    var decrypt = CryptoJS.AES.decrypt(src, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });

    var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
    return decryptedStr.toString();
}

//npm install crypto-js
// npm install js-base64

//局部页面使用
import { Base64 } from 'js-base64'
var ed = Base64.encode("11111")
var dd = Base64.decode(ed)

21 localStorage存储对象sessionStorage存储数组对象

https://www.cnblogs.com/echolun/p/9088189.html

22 vue页面布局学习

Vue3+Element-Plus 主页布局功能功能开发 二二

23 CSS中height:100vh和height:100%的区别是什么

https://blog.csdn.net/lalala_dxf/article/details/128567292

24 elementPlus树状组件默认选中

https://blog.csdn.net/weixin_61570458/article/details/128238360

25 Vue 引入路径正确的一直报错 Already included file name ‘××ב differs from file name ‘××ב only in casing.

https://www.cnblogs.com/Lilc20201212/p/15957285.html

26 vue根据条件给标签添加属性

https://blog.csdn.net/weixin_50523809/article/details/118304487

27 Vue属性绑定ref变量

https://blog.csdn.net/weixin_47345230/article/details/128158883

28 vue路由守卫–用于前端实现用户权限验证

https://blog.csdn.net/m0_66504310/article/details/128458971

29 elbutton和el-upload一起使用不在同一行显示问题

<div class="addbutton">
    <el-button type="primary" :icon="Plus" @click="handleInsert">新增</el-button>
    <el-upload action="#" :limit="1" accept=".xlsx" :show-file-list="false" :before-upload="beforeUpload" :http-request="handleMany">
        <el-button type="success" @click="uploadTemplate">批量导入</el-button>
    </el-upload>
    <el-button type="warning" @click="downloadTemplate">批量导入模板下载</el-button>
</div>

.addbutton {
    display: flex; //将 列显示变为行显示
    margin-bottom: 10px;
}
/* el -button和 el-upload使用 */
.el-button {
    margin-right: 10px; //增加button之前的间隔
}

30 vue文件下载

后端gin 程序代码

func DownloadEmployeesTemplate(c *gin.Context) {
	//1.检查配置文件是否存在
	templateFile := variable.BasePath + "/storage/app/idaas/employees.xlsx"
	if _, err := os.Stat(templateFile); err != nil {
		LogInfo("err, file not exist")
		ErrorResponse(c, 400, "file not exist")
		return
	}

	//templateFile = strings.TrimSpace(c.PostForm(templateFile))
	//fmt.Println("2222222", templateFile)
	c.Header("Content-Type", "application/octet-stream")
	c.Header("Content-Disposition", "attachment; filename="+"employees.xlsx")
	c.Header("Content-Transfer-Encoding", "binary")
	c.File(templateFile)
	//NormalResponse(c, "")
	return
}

前端vue代码

// 在请求拦截中修改responseType 为block
if (config.url == "/api/employees/download-employees-template") { 
    config.timeout = 120000
    //将返回的数据转成blob/ 也可以使用 在 then里面 new Blob-- 两种方法选择其中之一
    config.responseType = 'blob'
}
// 下载模板
const downloadTemplate = async () => {
    let res = api.downloadEmployeesTemplate().then(res => {
        // 文件下载需要设置
        // console.log(res.data)
        let fileName = "employees.xlsx";
        let href = URL.createObjectURL(res.data);
        let link = document.createElement("a");
        link.download = fileName;
        link.href = href;
        link.style.display = "none";
        link.click();
        //document.body.removeChild(link); //下载完成移除元素
        URL.revokeObjectURL(link.href);
    });
};

31 vue下载excel文件的方法

vue下载excel文件的方法

VUE3.X – 如何实现文件下载功能

32 vue3定时器vue3清除定时器vue3动态显示当前时间

https://blog.csdn.net/qq_44535402/article/details/128051402

33 vue3生命周期

Vue3生命周期

Vue2.X和Vue3.X对比
vue2           ------->      vue3
beforeCreate   -------->      setup(()=>{})
created        -------->      setup(()=>{})
beforeMount    -------->      onBeforeMount(()=>{})
mounted        -------->      onMounted(()=>{})
beforeUpdate   -------->      onBeforeUpdate(()=>{})
updated        -------->      onUpdated(()=>{})
beforeDestroy  -------->      onBeforeUnmount(()=>{})
destroyed      -------->      onUnmounted(()=>{})
activated      -------->      onActivated(()=>{})
deactivated    -------->      onDeactivated(()=>{})
errorCaptured  -------->      onErrorCaptured(()=>{})

34 Vue3解决Vuex异步获取数据页面先渲染问题

https://blog.csdn.net/weixin_67560997/article/details/129342631

35 elementPlus树状组件默认选中

https://blog.csdn.net/weixin_61570458/article/details/128238360

两个字段配合使用

node-key="id"是唯一标识
current-node-key="1"是当前选中可以用来设置默认选中

36 element plus tree Element-UI tree 组件 选中节点高亮的问题处理

https://zhidao.baidu.com/question/1775302071392901660.html

:deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content){
    background-color: rgb(158, 213, 250) !important;
    color: #409EFF; 
}

修改背景色和字体颜色
效果如下
在这里插入图片描述

37 element plus icon不能和文字一样居中问题

elementUI图标按钮调整宽高后图标如何居中
在样式中增加下面字段即可

<div class="cloudpass-tunnel">
    <el-icon style="padding-left:10px"><List /></el-icon>
    通道列表
</div>
    display: flex;
    align-items: center;

如果需要水平居中再加

justify-content: center;

在这里插入图片描述

38 Element Plus的el-table表格中单元格内容过多显示省略号

https://blog.csdn.net/AiGarry/article/details/124293561

show-overflow-tooltip="true" 

39 element ui table 报错 type check failed for prop “showOverflowTooltip“. Expected Boolean, got Stri

https://blog.csdn.net/qq_35226176/article/details/115730325

40 Added non-passive event listener to a scroll-blocking ‘touchstart‘ event. Consider marking event…

https://blog.csdn.net/yjl13598765406/article/details/125496865

// 安装插件
npm install -S default-passive-events
// 在main.js引入
import 'default-passive-events'

41 v-if判断相等

v-if="title.classify==='今日要闻'"

42 el-table中某一列的隐藏

<el-table 中某一列不需要显示但又不能删除即需要隐藏时
在<el-table-column  中加上   v-if="false"

43 element plus - el-select 添加可输入功能

https://blog.csdn.net/qq_38374286/article/details/128004501

44 element-ui 表单校验el-select校验失效问题

el-select表单校验输入值之后表单规则不会自动清除
https://blog.csdn.net/m0_66899315/article/details/124494296

blur 变为change

45 vue v-if 判断某个元素满足多个条件的写法

https://blog.csdn.net/weixin_67849181/article/details/129130290

46 vue3中使用 vue3-slide-verify 滑块验证登录

vue3中使用 vue3-slide-verify 滑块验证登录

主要参考 - vue3滑块验证使用vue3-slide-verify宽度自适应

参考 vue-monoplasty-slide-verify在H5页面的使用和参数说明

47 el-form的表单验证 rules 必填 且为纯数字

  • 注意当rules中设置了 number 时 对应的 v-model 设置为 v-model.number
   <el-form :model="ruleForm" :rules="rules" ref="ruleForm">
     <el-form-item label="版本号" prop="versionCode" :label-width="formLabelWidth">
          <el-input v-model.number="ruleForm.versionCode" placeholder="输入版本号"></el-input>
        </el-form-item>
   </el-form>
   
 data(){
  return {
     rules:{
         versionCode: [
          {required: true, message: "输入版本号", trigger: "blur" },
          { required: true, type:"number",message: "版本号为数字", trigger: "blur" },
        ],
      }
   }
}

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: vue