Vue3 基础

news2024/11/28 22:38:16

Vue3 基础

概述

Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。

Vue 的两个核心功能:

  • 声明式渲染:Vue 基于标准 HTML 拓展了一套模板语法,使得我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系。
  • 响应性:Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM。

Vue3官方文档

Vite官方文档

安装Vue

一、使用CDN

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

二、npm安装

npm init vue@latest

三、下载JavaScript文件自行托管

使用JS的方式引入Vue

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue3简单使用</title>
    <script src="./vue3.js"></script>
</head>

<body>
    <div id="counter">
        <p>{{uname}}</p>
        <p>{{age}}</p>
    </div>

    <script>
        // 配置对象
        const counter = {
            data: function () {
                return {
                    uname: "小明",
                    age: 0
                }
            }
        };

        // 使用createApp函数创建一个应用实例
        // 传入配置对象
        let app = Vue.createApp(counter)
            // 应用实例必须调用mount函数,挂载后才会渲染出来
            .mount("#counter");

        //数据双向绑定
        app.age = 18;
    </script>
</body>

</html>

使用vite

简介

Vite是要给web开发构建工具,由于其原生ES模块导入方式,可以实现闪电般的冷服务器启动。

使用vite搭建项目

npm create vite@latest

或者:

npm create vite@latest my-vue-app -- --template vue

接着依次执行命令启动vue项目:

cd my-vue-app
npm install
npm run dev

模板语法

Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。

在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。

基本使用

  • v-bind:可以简写为:
  • v-on:可以简写问@
<script>
export default {
    data() {
        return {
            name: "小明123",
            age: 18,
            num: 0,
            rawHtml: "<h2 style='color:red;'>hello msg</h2>",
            myid: "id01",
            isBtnDisabled: true,
            objAttrs: {
                id: "id01",
                class: "box"
            },
            imgUrl: "https://cn.vitejs.dev/logo-with-shadow.png",
            attributeName: "id",
            mouseEvent: "click",
        }
    },
    methods: {
        changeNum() {
            this.num++;
        },
        changeColor() {
            this.id = "id01";
        },
        alertMsg() {
            alert("hello world");
        }
    }
}
</script>

<template>
    <!-- 文本插值 -->
    <p>姓名:{{ name }}</p>
    <p>年龄:{{ age }}</p>
    <p>数量:{{ num }}</p>

    <!-- 仅修改一次 -->
    <p v-once>数量:{{ num }}</p>
    <button @click="changeNum">修改num</button>

    <!-- 使用html -->
    <p v-html="rawHtml"></p>

    <!-- 属性绑定 -->
    <p v-bind:id="myid">v-bind</p>
    <!-- v-bind简写 -->
    <p :id="myid">v-bind2</p>
    <!-- 布尔类型 -->
    <button :disabled="isBtnDisabled">v-bind2</button><br>
    <!-- 绑定多个属性 -->
    <p v-bind="objAttrs">hello world</p>

    <!-- 动态参数 -->
    <p v-bind:[attributeName]="myid">动态属性1</p>
    <img v-bind:src="imgUrl" style="width: 50px;">
    <!-- 简写 -->
    <p :[attributeName]="myid">动态属性2</p>
    <button @[mouseEvent]="attributeName = 'class'">动态事件</button>
    <button @click="mouseEvent = 'mouseover'">改变事件</button><br>

    <!-- 点击事件 -->
    <button v-on:click="changeColor">修改颜色</button>
    <!-- 简写 -->
    <button @click="changeColor">修改颜色</button><br>

    <!-- 使用JavaScript表达式 -->
    <p>{{ num + 1 }}</p>
    <p>{{ name.split("").reverse().join("") }}</p>
</template>

<style>
#id01 {
    color: red;
}

#id02 {
    color: blue;
}

.id01 {
    color: green;
}

.id02 {
    color: yellowgreen;
}

.active {
    color: red;
}

.box {
    border: 1px dashed red;
}
</style>

条件渲染

<script>
    export default {
        data() {
            return {
                age: 68,
                isShow: true
            }
        }
    }
</script>

<template>
<!-- v-if条件渲染 -->
<p v-if="age < 18">未成年人</p>
<p v-if="age >= 18 && age < 60">年轻人</p>
<p v-else>老人</p>

<!-- v-show,本质是display:none; -->
<p v-show="isShow">
    hello template
    </p>
</template>
  • v-if:会根据条件进行渲染,切换时元素会被销毁或重建,因此切换开销大。
  • v-for:本质是通过display进行显示和隐藏。

列表渲染

<script>
    export default {
        data() {
            return {
                userList: [
                    { name: "张三", age: 19, address: "北京" },
                    { name: "李四", age: 29, address: "上海" },
                    { name: "王五", age: 39, address: "广州" }
                ],
                userInfo: {
                    name: "小白",
                    title: "顶级作者",
                    bookName: "西游记"
                }
            }
        }
    }
</script>

<template>   
    <!-- v-for遍历数组 -->
    <ul>
        <li v-for="(item, index) in userList">
            编号:{{ index }} 姓名:{{ item.name }} 年龄:{{ item.age }} 地址:{{ item.address }}
        </li>
    </ul>
    <ul>
        <li v-for="({ name, age, address }, index) in userList">
            编号:{{ index }} 姓名:{{ name }} 年龄:{{ age }} 地址:{{ address }}
        </li>
    </ul>

    <!-- v-for遍历对象 -->
    <ul>
        <li v-for="(value, key) in userInfo">
            {{ key }} : {{ value }}
        </li>
    </ul>
</template>

通过key管理状态

Vue 默认按照“就地更新”的策略来更新通过 v-for 渲染的元素列表。当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。

默认模式是高效的,但只适用于列表渲染输出的结果不依赖子组件状态或者临时 DOM 状态 (例如表单输入值) 的情况

在这里插入图片描述

为了给 Vue 一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的 key attribute:

<script>
    export default {
        data() {
            return {
                userList: [
                    { name: "张三", age: 19, address: "北京" },
                    { name: "李四", age: 29, address: "上海" },
                    { name: "王五", age: 39, address: "广州" }
                ]
            }
        },
        methods: {
            addUser() {
                this.userList.unshift({ name: "小白", age: "8", address: "成都" })
            }
        }
    }
</script>

<template>
    <!-- :key的使用 -->
    <ul>
        <li v-for="item in userList" :key="item">
            <input type="checkbox">{{ item.name }}
        </li>
    </ul>
    <button @click="addUser">添加user</button>
</template>

数组变化侦测

Vue 能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新。这些变更方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

计算属性

计算属性只会在依赖值发生变化时才会重新计算。

<script >
export default {
    data() {
        return {
            message: "hello world",
            firstMsg: "abc",
            lastMsg: "efg"
        }
    },
    //方法
    methods: {
        reverseMsg2() {
            console.log("reverseMsg2");
            return this.message.split("").reverse().join("");
        }
    },
    //计算属性
    computed: {
        reverseMsg() {
            console.log("reverseMsg");
            return this.message.split("").reverse().join("");
        },
        // 可写计算属性
        fullName: {
            // getter
            get() {
                return this.firstMsg + "-" + this.lastMsg;
            },
            // setter
            set(newValue) {
                [this.firstMsg, this.lastMsg] = newValue.split(" ");
            }
        }
    }
}
</script>

<template>
    <p>{{ message }}</p>
    <p>{{ reverseMsg2() }}</p>
    <p>{{ reverseMsg2() }}</p>
    <p>{{ reverseMsg }}</p>
    <p>{{ reverseMsg }}</p>
    <button @click="message = '你好'">修改message</button>
    <p>{{ fullName }}</p>
    <p>{{ fullName="ABC EFG" }}</p>
</template>

说明:

打印了2次“reverseMsg2”,说明每次调用方法都会执行一次;打印了1次“reverseMsg”,说明计算属性会缓存。

点击按钮修改了message属性,会重复上面操作,说明计算属性只有依赖值发生变化时才会重新计算。

侦听器

监听状态变化。

<script >
export default {
    data() {
        return {
            message: "hello world",
            isHidden: true,
            user: {
                name: "小明",
                age: 18,
                sex: true
            }
        }
    },
    // 侦听器
    watch: {
        // 侦听器,方式一,message发生变化时调用
        // message(newValue, oldValue) {
        //     console.log("新值:" + newValue, "旧值:" + oldValue);
        //     if (newValue.length < 5 || newValue.length > 10) {
        //         this.isHidden = false;
        //     } else {
        //         this.isHidden = true;
        //     }
        // }

        // 侦听器,方式二,初始化时触发
        message: {
            immediate: true, // 是否初始化时调用
            handler(newValue, oldValue) {
                if (newValue.length < 5 || newValue.length > 10) {
                    this.isHidden = false;
                } else {
                    this.isHidden = true;
                }
            }
        },
        // 深度监听,方式一,监听对象的每个属性
        // user: {
        //     handler(newValue) {
        //         console.log(newValue);
        //         console.log(newValue.name);
        //     },
        //     deep: true // 是否深度监听,给对象的每个属性都加上侦听器
        // },
        // 深度监听,方式二,监听对象的单个属性
        "user.name": {
            handler(newValue) {
                console.log(newValue);
            },
            deep: true // 是否深度监听
        }
    }
}
</script>

<template>
    <p>{{ message }}</p>
    <button @click="message = '你好'">修改message</button><br>
    <input type="text" v-model="message"><br>
    <p :hidden="isHidden">输入框中的内容不能小于5或大于10</p>
    <button @click="user.name = '小白'">修改user.name</button>
</template>

类和样式绑定

<script >
export default {
    data() {
        return {
            message: "hello wold",
            //class
            isActive: true,
            isBgColor: true,
            classObj: {
                active: true,
                bgColor: true
            },
            error: null,
            activeClass: "active",
            bgColorClass: "bgColor",
            //style
            activeColor: "red",
            bgColor: "grey",
            fontSize: "30px",
            styleObj: {
                color: "red",
                'background-color': "grey",
                fontSize: "30px"
            }
        }
    },
    // 计算属性
    computed: {
        classObject() {
            return {
                active: this.isActive && !this.error,
                bgColor: this.isBgColor && !this.error
            }
        }
    }
}
</script>

<template>
    <!-- 使用class -->
    <p class="active">hello world1</p>
    <!-- 绑定对象 -->
    <p :class="{ active: isActive }">hello world2</p>
    <p :class="{ active: isActive, bgColor: isBgColor }">hello world3</p>
    <!-- 绑定对象简写 -->
    <p :class="classObj">hello world4</p>
    <!-- 计算属性 -->
    <p :class="classObject">hello world5</p>
    <!-- 绑定数组 -->
    <p :class="[activeClass, bgColorClass]">hello world6</p>

    <button @click="isActive = !isActive">修改active</button>
    <button @click="isBgColor = !isBgColor">修改bgColor</button>


    <!-- 使用内联样式 -->
    <p style="color:red;">hello1</p>
    <!-- 绑定对象 -->
    <p :style="{ color: activeColor, 'background-color': bgColor, fontSize: fontSize }">hello2</p>
    <!-- 绑定对象 -->
    <p :style="styleObj">hello3</p>
    <!-- 绑定数组 -->
    <p :style="[styleObj]">hello4</p>
</template>

<style>
.active {
    color: red;
}

.bgColor {
    background-color: grey;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/364058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

升职加薪必备,2023年程序员不能不知道的AI辅助编码工具

已经有很多人把chatGPT当做必备的Bug修复工具了&#xff0c;对于用AI写代码&#xff0c;有人感到失落&#xff0c;害怕被取代&#xff0c;而另一些人则认为人工智能将加快编写更好代码的过程。 尽管 AI 编写的代码并非完美无缺&#xff0c;但我相信&#xff0c;最终AI将取代人…

Java实例——网络实例

1、主机IP地址获取 步骤一&#xff1a;获取主机InetAddress 步骤二&#xff1a;获取主机IP地址 InetAddress address null;try {address InetAddress.getByName("www.baidu.com");}catch (UnknownHostException e) {System.exit(2);}System.out.println("Host…

聚类(性能度量)

文章目录聚类&#xff08;性能度量&#xff09;外部指标例1内部指标例2聚类&#xff08;性能度量&#xff09; 对数据集 D{x1,x2,...,xm}D\{x_1,x_2,...,x_m\}D{x1​,x2​,...,xm​} &#xff0c;假定通过聚类给出的簇划分为 C{C1,C2,...,Ck}C\{C_1,C_2,...,C_k\}C{C1​,C2​,…

计算机组成原理错题

静态RAM&#xff08;SRAM&#xff09;和动态RAM&#xff08;DRAM&#xff09;的基本电路图不同&#xff0c;因此可以通过观察存储器的基本电路图来判断它属于哪一类。 静态RAM的基本电路图包括一个存储单元和一个数据选择器。每个存储单元由一个触发器&#xff08;flip-flop&a…

汽车零部件企业数字工厂管理系统建设方案

在汽车零部件制造领域&#xff0c;伴随工业信息化与机器人化&#xff0c;制造模式逐渐从 CAD/CAE/CAM 数字化设计及加工走向全产品周期虚拟现实的数字化工厂管理系统平台&#xff0c;实现虚拟现实设计制造&#xff0c;防范产品缺陷并预防设备故障&#xff0c;大幅提高生产效率。…

做出选择,直面挑战,揭开数据中心网络的发展真相

为什么&#xff1f;你们发现没有&#xff1f;不知道&#xff0c;从什么时候开始&#xff0c;这个世界&#xff0c;变得越来越快了。快得仿佛昨天刚刚来到这个世界&#xff0c;一眨眼就日暮西山了。是的&#xff0c;时间过得好快&#xff0c;回想起2002年7月电气和电子工程师协会…

炼石:八年饮冰难凉热血,初心如磐百炼成钢

炼石成立八周年 八载笃行&#xff0c;踔厉奋发。创立于2015年的炼石&#xff0c;今天迎来了八岁生日&#xff0c;全体员工共同举行了温暖又充满仪式感的周年庆典。过去的2022&#xff0c;是三年疫情的艰难“收官之年”&#xff0c;新的2023&#xff0c;将是数据安全行业成为独…

FFT的物理意义

FFT结果的物理意义 FFT是离散傅立叶变换的快速算法&#xff0c;可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的&#xff0c;但是如果变换到频域之后&#xff0c;就很容易看出特征了。这 就是很多信号分析采用FFT变换的原因。另外&#xff0c;FFT可以将一…

内网渗透(四十九)之域控安全和跨域攻击-多种方式离线读取ntds.dit文件中的hash值

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

Java方法【未完待续】

目录 前言 一、什么是方法&#xff1f; 二、方法的定义和调用 方法的定义 方法的调用 三、方法的重载 重载规则 实现理论 总结 前言 随着对Java这一编程语言的深入学习&#xff0c;大家可能会遇到一个熟悉又陌生的词——方法&#xff0c;其实Java方法就是我们学习C/C时…

2023该好好赚钱了,推荐三个下班就能做的副业

在过去的两年里&#xff0c;越来越多的同事选择辞职创业。许多人通过互联网红利赚到了他们的第一桶金。随着短视频的兴起&#xff0c;越来越多的人吹嘘自己年收入百万&#xff0c;导致很多刚进入职场的年轻人逐渐迷失自我&#xff0c;认为钱特别容易赚。但事实上&#xff0c;80…

构造agent类型的内存马(内存马系列篇十三)

写在前面 前面我们对JAVA中的Agent技术进行了简单的学习&#xff0c;学习前面的Agent技术是为了给这篇Agent内存马的实现做出铺垫&#xff0c;接下来我们就来看看Agent内存马的实现。 这是内存马系列篇的第十三篇了。 环境搭建 我这里就使用Springboot来搭建一个简单的漏洞…

电脑病毒已灭绝,是真的吗?

大家有没有这样一个疑问&#xff0c;觉得自己的电脑好像很久没有电脑病毒了&#xff1f;之前大名鼎鼎的蠕虫2000&#xff0c;熊猫烧香都变得不那么常见了。到底是电脑因为自身优化和杀毒软件的防护导致病毒变少了&#xff0c;还是本身电脑病毒变少了呢&#xff1f;&#xff08;…

Boost库文档搜索引擎

文章目录综述效果展示去标签化&#xff0c;清理数据构建索引用户查询综述 该项目使用了BS架构&#xff0c;实现了用户对Boost库进行站内搜索的功能&#xff0c; 用户输入关键字使用http协议通过ajax将数据发送给后端服务器&#xff0c;后端进行分词&#xff0c; 通过倒排索引…

【Kubernetes】第七篇 - Service 服务介绍和使用

一&#xff0c;前言 上一篇&#xff0c;通过配置一个 Deployment 对象&#xff0c;在内部创建副本集对象&#xff0c;副本集帮我们创建了 3 个 pod 副本 由于 pod 存在 IP 漂移现象&#xff0c;pod 的创建和重启会导致 IP 变化&#xff1b; 本篇&#xff0c;介绍 Service 服…

《计算机网络:自顶向下方法》实验5:NAT协议分析 Wireshark实验

实验12:NAT协议分析 1 What is the IP address of the client? 客户端的 IP 地址是192.168.1.100 2 The client actually communicates with several different Google servers in order to implement “safe browsing.” (See extra credit section at the end of this la…

Safety-Gym环境配置与安

官网&#xff1a; https://github.com/openai/safety-gym https://github.com/openai/safety-starter-agents 一、安装依赖环境配置 建议使用python 3.7及以下环境&#xff0c;因为官方的safety-rl是基于tensorflow1.13.1实现&#xff0c;而tensorflow1.13.1只能支持python…

leaflet 自定义添加地图网格线(087)

第087个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中自定义添加地图网格线。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共76行)安装插件相关API参考:专栏目标示例效果 配置方式 1)查看基…

前端学习第九站——Vue3基础篇

目录 一、环境搭建 创建项目 编码 IDE 修改端口 配置代理 项目架构 二、Vue组件 main.ts 属性绑定 事件绑定 表单绑定 计算属性 xhr axios 环境变量 baseURL 拦截器 条件和列表 监听器 vueuse useRequest usePagination&#xff08;分页&#xff09; 子组…

你什么档次?敢和我用一样的即时通讯平台WorkPlus?

现今&#xff0c;很多企业越来越青睐私有化部署&#xff0c;尤其是在选择组织内部即时通讯平台的时候&#xff0c;更是会提出私有化部署的需求。究其原因&#xff0c;企业选择私有化部署即时通讯软件完全是出于安全方面考虑。因此&#xff0c;越来越多的企业将眼光望向了本地化…