【web系列十三】vue3实操技巧

这篇具有很好参考价值的文章主要介绍了【web系列十三】vue3实操技巧。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

写在前面

纯前端

生命周期钩子

前后端都需要

通信

父组件向子组件传值用props

父组件触发子组件事件用defineExpose

子组件向父组件传值(触发事件)用$emit

发送axios同步请求

下载zip文件

开发小技巧

语法

script

proxy对象解析

布局

浮动布局

flex

动态开关组件

页面缓存

添加页面缓存

 清除部分缓存

一些报错汇总

vue-route

ts引入js库

ts懒加载

参考资料


写在前面

        这里主要记录博主在开发过程中遇到过的问题以及最终的解决方案,博主一般会选择比较通用的方法,希望大家遇到类似的问题可以少走弯路。

纯前端

生命周期钩子

生命周期钩子 | Vue.js (vuejs.org)

VUE3 之 生命周期函数 (bbsmax.com)

前后端都需要

通信

总结了 Vue3 的七种组件通信方式,别再说不会组件通信了 (baidu.com)

父组件向子组件传值用props

        父组件代码

        在子组件中定义一个show属性,父组件中通过该属性向子组件传值,并可用于控制子组件中的Button是否显示,注意,data前要加:

<template>
    <div class="test">
        <Son :show="true" />
    </div>
</template>

<script lang="ts" setup>
import Son from '@/components/son.vue'
</script>

<style></style>

        子组件代码

        由于使用了<script lang="ts" setup>,因此想要使用props需要先引入defineProps。

<template>
    <div class="test">
        <button v-if="!show">show</button>
    </div>
</template>

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

let props = defineProps({
    show: Boolean
});
</script>

<style></style>

父组件触发子组件事件用defineExpose

        父组件代码

        父组件中给button定义一个点击时间notify,用于触发子组件的时间remove。

<template>
    <div class="test">
        <button @click='notify' />
        <Son ref='child' />
    </div>
</template>

<script lang="ts" setup>
import Son from '@/components/son.vue'
import { getCurrentInstance } from '@vue/runtime-core'

let currentInstance = getCurrentInstance();

function notify() {
    currentInstance.ctx.$refs.child.remove();
}
</script>

<style></style>

         子组件代码

        子组件中定义待触发的事件remove,注意要用defineExpose将事件抛出,否则父组件是无法调用这个事件的。

<template></template>

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

let remove=() => {
    console.log('remove');
});

// 也可以这么写
// function remove() {
//     console.log('remove');
// });

defineExpose({
    remove
})
</script>

<style></style>

子组件向父组件传值(触发事件)用$emit

        父组件代码

        子组件中通过create事件触发父组件的create事件,父组件执行create函数。

<template>
    <div class="test">
        <Son @create="create" />
        <Test v-if="show" />
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import Son from '@/components/son.vue'
import Test from '@/components/test.vue'

let show = ref(false);

function create(data) {
    show.value = true;
    consolo.log(data);
}
</script>

<style></style>

         子组件代码

        由于使用了<script lang="ts" setup>,因此想要使用emits需要先引入defineEmits。

<template>
    <div class="test">
        <button @click="create">show</button>
    </div>
</template>

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

let emits = defineEmits (['create']);
let result = 1;

function create() {
    return emits("create", result)
}
</script>

<style></style>

发送axios同步请求

        如果我们用以下方法发送请求时,其实是异步的,这时我们打印的data还是空的。

let data = [];

function getData() {    
    axios.get("getData").then(response => {
        data = response.data;    
    });
}

getData();
console.log(data);

        而有时候我们希望等返回了data再执行后面的函数,这时可以实用async+await的方法实现。

let data = [];

async function getData() {    
    await axios.get("getData").then(response => {
        data = response.data;    
    });
}

getData();
console.log(data);

下载zip文件

        网上有很多web下载文件的方式,各有优缺点,以下这篇文章整理的还是比较全的,大家可以参考学习。

Web前端下载文件的几种常见方式_许进进的博客-CSDN博客_前端下载文件的方式

         我这边用一个比较通用且兼容性好的方式——blob。

        首先,我们封装一个前端的download库。

import axios from "axios";


export interface FileOptions {
	type?: string;
	name: string;
}

async function downloadFileByPost(
	url: string, 
	formData: FormData, 
	options: FileOptions
): Promise<void> {
    await axios
		.post(url, formData, {responseType: 'blob'})
		.then(response => download(response, options));
}

async function downloadFileByGet(
	url: string, 
	options: FileOptions
): Promise<void> {
    await axios
		.get(url, {responseType: 'blob'})
		.then(response => download(response, options));
}

functon download(
	response: any, 
	options: FileOptions
): Promise<void> {
    let blob = new Blob([response.data], {
		type: options.fileType ? options.fileType : 'application/octet-binary'
	});
    // 创建下载的链接
    let href = window.URL.createObjectURL(blob);
	// 创建临时元素
    let downloadElement = document.createElement('a');
    downloadElement.href = blobUrl
    // 下载后文件名
    downloadElement.download = fileName
    document.body.appendChild(downloadElement);
    // 点击下载
    downloadElement.click()
    // 下载完成移除元素
    document.body.removeChild(downloadElement);
    // 释放掉blob对象
    window.URL.revokeObjectURL(blobUrl);
}

export {
    downloadFileByPost,
    downloadFileByGet
};

        然后,来到需要下载文件的vue组件中使用。

<template>
...
</template>

<script lang="ts" setup>
import { FileOptions, downloadFileByGet } from '@/utils/download.ts';

funcion download(): void {
    let options:FileOptions = {
        name: 'xxx.zip'
    };
    downloadFileByGet('http://192.168.2.2:8080/download', options);
}
</script>

<style></style>

         最后来到服务器端,这里用的是django。

from django.http import HttpResponse
import os
from zipfile import ZipFile, ZIP_DEFLATED
from io import BytesIO


def download(request):
    response = BytesIO()
    file_root = "D:\\data"
    
    # 创建压缩文件
    with ZipFile(response, "w", ZIP_DEFLATED) as f:
        # 将需要的文件写入压缩文件
        for file in os.listdir(file_root):
            # 前一个参数是文件存放位置,后一个参数是打包后的文件路径
            f.write(os.path.join(file_root, file), os.path.join('download', file))
    # 指向文件头
    response.seek(0)

    return HttpResponse(response)

         这里只写了一些关键代码。

        当触发了页面的download函数后,前端会向后端发送请求,后端将需要的文件压缩为zip后返回给前端并触发页面的下载。

        这里用到了python的zipfile库,有人做了一个比较详细的整理,感兴趣的大家可以看看。

zipfile 模块详解 - nuoruo - 博客园 (cnblogs.com)

开发小技巧

语法

script

<script>中不需要再写成<script> export default {setup(){}}这种形式了,可以直接写

<script lang="ts" setup></script>

proxy对象解析

        使用toRaw可以获取proxy对象包裹的数据

<script lang="ts" setup>
import { toRaw } from '@vue/reactivity'

let list = toRaw(proxy_obj);
</script>

布局

浮动布局

可以参考博主的这篇文章中:其他的一些常用功能示例->浮动布局

【web系列五】CSS_Nicholson07的博客-CSDN博客

flex

使用flex排版比float方便不少,可以参考一下博文

Css 弹性布局(Flex)详细介绍(Flex 属性详解、场景分析)_前端不释卷leo的博客-CSDN博客_弹性布局

动态开关组件

        使用v-if控制显示状态的页面一开始是不会挂载的,未挂载的页面中的watch监视器是没有生效的。如果你想用pinia/vuex中的变量var作为v-if的参数控制页面显示状态,同时用watch监视var,你会发现当页面显示状态改变时,watch不会有任何反应。而有时候我们需要watch来监视页面显示状态的变化,应该怎么办呢?其实非常简单,只要把v-if替换成v-show就可以了,v-show的页面在不显示的状态下已经挂载了,只是增加了一个display属性,因此watch可以生效。

页面缓存

添加页面缓存

        使用keep-alive组件包裹,则再次进入页面时,会使用缓存中的组件,不会重新渲染(不再执行mounted及之前的生命周期中的代码),用于保存组件的原始状态(所有变量的值保持最终状态不变)

<keep-alive>
    <router-view></router-view>
</keep-alive>

 清除部分缓存

1、在 <keep-alive> 上添加 exclude属性

        exclude属性中罗列出所有不需要页面缓存的vue组件,并用','间隔。

<keep-alive exclude="test1,test2" >
    <router-view></router-view>
</keep-alive>

2、通过路由传参实现  $route.meta.keepAlive

<keep-alive >
    <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>

        在定义路由的文件中,设置 meta.keepAlive 参数,如在 src/routes.js 中

一些报错汇总

vue-route

        使用vue-route实现页面跳转时,有时会出现以下bug,偶发性的。

Uncaught (in promise) TypeError: api.now is not a function

         这可能是vue-route的bug,只要卸载后安装4.0.10,然后重启前端工程和devtools就可以了。

npm uninstall vue-router
npm i vue-router@4.0.10

ts引入js库

        基于ts建立的vue工程下导入js库会有如下报错。

Could not find a declaration file for module implicitly has an ‘any‘ type 

        在shims-vue.d.ts文件中添加

declare module '*.js'

        然后重启项目就好了。

ts懒加载

        之前开发时遇到一个问题,在vue的app.vue中引入了a.vue组件和b.ts文件,这两个文件中都包含了pinia初始化代码,而pinia是在app创建后才挂载的,导致了报错,大致意思是:未挂载pinia前就调用了pinia初始化。但是很奇怪的是a.vue组件中没有报错,b.ts中却报错了,原因应该是ts文件加载逻辑与vue不同,导致加载ts文件的时候执行了pinia初始化。

        解决方案是使用require懒加载推迟ts文件的加载,我们来看一下import和require的区别:

        import:编译时就加载(e.g. import { Bear } from './test.ts'),所以在编译时会报错,且导入的内容不能重新复制,防止被意外更改,但当我们修改了导入的文件模块时会随时更新。

        require: 运行时再加载(e.g. const { Bear } = require('./test')),所以在编译时不会报错,就算把文件名输错也没关系

参考资料

 总结了 Vue3 的七种组件通信方式,别再说不会组件通信了 (baidu.com)

 生命周期钩子 | Vue.js (vuejs.org)

 VUE3 之 生命周期函数 (bbsmax.com)

【web系列五】CSS_Nicholson07的博客-CSDN博客

 Web前端下载文件的几种常见方式_许进进的博客-CSDN博客_前端下载文件的方式

 zipfile 模块详解 - nuoruo - 博客园 (cnblogs.com)

vue 页面缓存 keep-alive(含配置清除页面缓存 exclude,局部缓存,动态缓存,路由控制缓存 $route.meta.keepAlive)_keep-alive :exclude_朝阳39的博客-CSDN博客

 js require和import区别与应用_ts js require_皮宁澜的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-419636.html

到了这里,关于【web系列十三】vue3实操技巧的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端系列19集-vue3引入高德地图,响应式,自适应

    npm i @amap/amap-jsapi-loader --save 要在Vue 3中引入高德地图,你可以按照以下步骤进行操作: 在项目目录中使用npm或yarn安装高德地图的JavaScript API库。你可以使用以下命令之一: npm install @amap/amap-jsapi-loader yarn add @amap/amap-jsapi-loader 在Vue组件中引入并使用高德地图。 在你的Vue组件中

    2024年02月07日
    浏览(46)
  • 【web系列十】Vue3+Django+MySQL搭建前后端框架

    目录 写在前面 Vue3和Django通信 代码转移 代码转移 页面请求与显示 跨域请求 服务端发出的跨域请求 浏览器发出的跨域请求 csrf认证 前后端通信示例 django vue3 演示 Django和MySQL通信 准备 安装插件 创建数据库 连接数据库 生成数据表 创建用户 另一种远程访问的方式 通信示例

    2023年04月08日
    浏览(62)
  • Web前端VScode/Vue3/git/nvm/node开发环境安装

    目录 1 基本配置 2 安装vscode 3 安装vue 4 配置bash 5 安装nvm 6 安装node 7 安装yarn 8 新建项目 9 运行helloworld 本篇是为了做前端开发的环境而写。使用的操作系统是windows 10 64位 现在做vue和node基本就是vscode和webstorm,本篇就是用vscode。 可以从主页直接下载 选择windows版本下载即可。

    2024年02月04日
    浏览(61)
  • 前端经典面试题 | 吊打面试官系列 之 Vue2和Vue3的区别

    🖥️ 前端经典面试题 吊打面试官 专栏:Vue2和Vue3的区别 🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 ✨ 个人主页:CoderHing的个人主页 🍀 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀️ 👉 你的一键三连是我更新的最大动力❤️ 目录 一、回答点 二、深入回答 监测机制

    2024年01月16日
    浏览(48)
  • 前端系列20集-vue3,微信小程序,brew,redis,WebSocket

    image.png image.png image.png image.png npm i --save-dev @types/websocket 特定的错误信息 \\\"Invalid argument\\\" 表明可能存在一个参数传递给数据库加载过程中的问题。 要解决这个问题,您可以考虑以下步骤: 检查加载数据库的代码,并检查是否存在传递错误或无效的参数。 验证数据库所需的依赖

    2024年02月12日
    浏览(53)
  • 前端系列——vue2+高德地图web端开发(使用和引入)

    本人非专业前端开发,其实是搞后端的,但是正好接了一个项目需要我负责全栈,所以写了这个系列的文章,如果以后项目可以开源我会放出来的 本次我们要实现的是vue2+高德地图的网页开发 本文需要大家系统学过vue以及初步了解高德地图的情况下理解起来会十分省力 高德

    2024年01月16日
    浏览(48)
  • web前端开发教学视频,VUE项目配置ESlint后一些报错解决方式,4个改变你编程技能的小技巧

    ‘no-delete-var’: 2, // 禁止出现未使用的变量 ‘no-unused-vars’: [2, {‘vars’: ‘local’, ‘args’: ‘none’}], // 禁止出现空函数 ‘no-empty-function’: 2, // 禁用不必要嵌套块 ‘no-lone-blocks’: 2, // 这条规则强制执行v-on指令样式,您应该使用速记。 ‘vue/v-on-style’: [2, ‘shorthand’], //*

    2024年04月13日
    浏览(36)
  • Web前端 ---- 【Vue3】computed计算属性和watch侦听属性(侦听被ref和reactive包裹的数据)

    目录 前言 computed watch watch侦听ref数据 ref简单数据类型 ref复杂数据类型 watch侦听reactive数据 本文介绍在vue3中的computed计算属性和watch侦听属性。介绍watch如何侦听被ref和reactive包裹的数据 在vue3中,计算属性computed也是组合式api,也就是说要先引入,再在setup中使用 语法 完整:

    2024年01月18日
    浏览(62)
  • 前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 第一章 技术栈简介 (开篇)

    旨在帮助初学者掌握使用现代前端技术栈构建应用的基础知识和技能。在这个系列中,我们将深入探讨如何结合Vue.js、Vite、TypeScript、Pinia和Sass这些强大的工具和框架来开发现代化的前端应用。 通过这个系列,我们将从零开始构建一个完整的前端项目,覆盖项目初始化、组件

    2024年02月05日
    浏览(53)
  • 前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 第十二章 常用工具函数 (Utils配置)

    在项目开发中,我们经常会使用一些工具函数,也经常会用到例如 loadsh 等工具库,但是这些工具库的体积往往比较大,如果项目本身已经引入了这些工具库,那么我们就没有必要再引入一次,所以我们需要自己封装一些工具函数,来简化我们的开发。 在 src/utils 目录下创建

    2024年02月20日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包