Vue3【创建项目、代码分析、响应式原理-代理、data详解、methods、computed】

news/2024/11/28 21:54:18/

文章目录

    • 自动创建项目
    • 代码分析
    • 响应式原理-代理
    • data详解
    • methods
    • computed


自动创建项目

npm init vue@latest


yarn create vue
yarn
yarn dev


代码分析

  • data是一个函数
  • 在data中,this就是当前的组件实例vm
  • 如果使用箭头函数,则无法通过this来访问组件实例
  • 使用vue时,减少使用箭头函数

  • data会返回一个对象作为返回值,vue会对该对象进行代理
  • 从而将其转换为响应式数据,响应式数据可以直接通过组件实例访问

  • 直接向组件实例中添加的属性不会被vue所代理,不是响应数据,修改后页面不会发生变化

  • vm.$data 是实际的代理对象,通过vm可以直接访问到$data中的属性
  • vm.$data.msg 等价于 vm.msg


<script>
// const obj = {
//     msg:"哈哈,我是obj"
// }// window.obj = obj// 组件,一个组件可以创建多个组件实例
// 组件就是一个普通的js对象
export default {// data是一个函数// 在data中,this就是当前的组件实例vm// 如果使用箭头函数,则无法通过this来访问组件实例// 使用vue时,减少使用箭头函数// data: vm => {//     console.log("data", vm)//     return {//         msg: "我爱Vue"//     }// }data() {// console.log("data", this)// 直接向组件实例中添加的属性不会被vue所代理,不是响应数据,修改后页面不会发生变化// this.name = "孙悟空"// vm.$data 是实际的代理对象,通过vm可以直接访问到$data中的属性// vm.$data.msg 等价于 vm.msg// data会返回一个对象作为返回值,vue会对该对象进行代理//  从而将其转换为响应式数据,响应式数据可以直接通过组件实例访问return {msg: "我爱Vue"}// return obj},created(){// 会在组件创建完毕后调用// 可以通过vm.$data动态的向组件中添加响应式数据,但是不建议这么做this.$data.name = "孙悟空"}
}
</script><template><h1>{{ msg }}</h1><h2>{{ name }}</h2>
</template>

App.vue是根组件

  • createApp(App) 将根组件关联到应用上
    • 会返回一个应用的实例
  • app.mount(“#app”) 将应用挂载到页面中
    • 会返回一个根组件的实例,组件的实例通常可以命名为vm
    • 组件实例是一个Proxy对象(代理对象)

main.js

import { createApp } from 'vue'
import App from './App.vue'/* App.vue是根组件- createApp(App) 将根组件关联到应用上- 会返回一个应用的实例- app.mount("#app") 将应用挂载到页面中- 会返回一个根组件的实例,组件的实例通常可以命名为vm- 组件实例是一个Proxy对象(代理对象)*/
const app = createApp(App)const vm = app.mount("#app")// 将vm设置为全局变量
window.vm = vm
window.app = app// createApp(App).mount('#app')// console.log(vm)

响应式原理-代理

/* 如果直接修改对象的属性,那么就是仅仅修改了属性,没有去做其他的事情,这种操作只会影响对象自身,不会导致元素的重新的渲染希望在修改一个属性的同时,可以进行一些其他的操作,比如触发元素重新渲染!要实现这个目的,必须要对对象进行改造,vue3中使用的是的代理模式来完成对象的改造设置代理时不会对原对象产生影响!
*/
// obj.name = "猪八戒"// 创建一个对象
const obj = {name: "孙悟空",age: 18
}// 来为对象创建一个代理
const handler = {// get用来指定读取数据时的行为,它的返回值就是最终读取到的值// 指定get后,在通过代理读取对象属性时,就会调用get方法来获取值get(target, prop, receiver) {// 返回值之前做一些其他的操作...// 在vue中,data()返回的对象会被vue所代理// vue代理后,当我们通过代理去读取属性时,返回值之前,它会先做一个跟踪的操作//      当我们通过代理去修改属性时,修改后,会通知之前所有用到该值的位置进行更新// track() 追踪谁用了我这个属性/* 三个参数:target 被代理的对象prop 读取的属性receiver 代理对象*/return target[prop]},// set会在通过代理修改对象时调用set(target, prop, value, receiver){target[prop] = value// trigger() 触发所有的使用该值的位置进行更新// 值修改之后做一些其他的操作}
} // handler 用来指定代理的行为// 创建代理
const proxy = new Proxy(obj, handler)// 修改代理的属性
proxy.age = 28console.log(proxy.age)

data详解

  • vue在构建响应式对象时,会同时将对象中的属性也做成响应式属性。即深层响应式对象
  • 有些场景下,可以通过shallowReactive()来创建一个浅层的响应式对象。只能响应式修改第一层的值
  • 建议将那些暂时没有使用到的属性,也添加到data返回的对象中,值可以设置为null
  • /数组也是响应式数据
<script>
import MyButton from "./components/MyButton.vue"
import { shallowReactive } from "vue"export default {data() {// data返回的对象最终会被Vue所代理// this.$data.xxx = "xxx" 动态添加响应数据(不建议这么做)// 建议将那些暂时没有使用到的属性,也添加到data返回的对象中,值可以设置为nullreturn {msg: "今天天气真不错!",// vue在构建响应式对象时,会同时将对象中的属性也做成响应式属性// 深层响应式对象stu: {name: "孙悟空",age: 18,gender: "男",friend: {name: "猪八戒"}},hello: null// 数组也是响应式数据arr: ["孙悟空", "猪八戒", "沙和尚"]}// 有些场景下,可以通过shallowReactive()来创建一个浅层的响应式对象// 只能响应式修改第一层的值// return shallowReactive({//     msg: "大闸蟹今天没去玩游戏!",//     stu: {//         name: "孙悟空",//         age: 18,//         gender: "男",//         friend: {//             name: "猪八戒"//         }//     }// })},components: {MyButton}
}
</script>
<template><h1>{{ msg }}</h1><h2>{{ stu.name }} -- {{ stu.age }} -- {{ stu.gender }}</h2><h3>{{ stu.friend.name }}</h3><hr /><h2>{{ hello }}</h2><hr /><MyButton></MyButton><MyButton></MyButton><MyButton></MyButton><MyButton></MyButton>
</template>

methods

  • methods 用来指定实例对象中的方法
    • 它是一个对象,可以在它里边定义多个方法
    • 这些方法最终将会被挂载到组件实例上
    • 可以直接通过组件实例来调用这些方法
    • 所有组件实例上的属性都可以在模板中直接访问
    • methods中函数的this会被自动绑定为组件实例
<script>
import MyButton from "./components/MyButton.vue"
import { shallowReactive } from "vue"export default {// data用来指定实例对象中的响应式属性data() {return {msg: "今天天气真不错!"}},/* methods 用来指定实例对象中的方法 - 它是一个对象,可以在它里边定义多个方法- 这些方法最终将会被挂载到组件实例上- 可以直接通过组件实例来调用这些方法    - 所有组件实例上的属性都可以在模板中直接访问- methods中函数的this会被自动绑定为组件实例*/methods: {sum(a, b){// console.log(this) // 组件实例 vmreturn a + b},changeMsg(){this.msg = "新的消息!"}}
}
</script>
<template><h1>{{ msg }}</h1><h2>{{ sum(2, 5) }}</h2><button @click="changeMsg">点我一下</button>
</template>

computed

  • 计算属性,只在其依赖的数据发生变化时才会重新执行
    • 对比:methods中的方法每次组件重新渲染都会调用
  • 会对数据进行缓存
  • 会被挂载到组件实例上
  • 在计算属性的getter中,尽量只做读取相关的逻辑。 不要执行那些会产生(副)作用的代码,即不修改
  • 计算属性的简写(只有getter时)
        name(){return this.lastName + this.firstName}
  • 可以为计算属性设置setter,使得计算属性可写,但是不建议这么做
<script>
import MyButton from "./components/MyButton.vue"
import { shallowReactive } from "vue"export default {// data用来指定实例对象中的响应式属性data() {return {msg: "今天天气真不错",stu: {name: "孙悟空",age: 18,gender: "男"},firstName: "悟空",lastName: "孙",}},methods: {updateAge() {if (this.stu.age === 18) {this.stu.age = 17} else {this.stu.age = 18}},// methods中的方法每次组件重新渲染都会调用getInfo() {console.log("getInfo调用了!")return this.stu.age >= 18? "你是一个成年人。": "你是一个未成年人。"}},/* computed 用来指定计算属性{属性名:getter}- 计算属性,只在其依赖的数据发生变化时才会重新执行- 会对数据进行缓存- 会被挂载到组件实例上*/computed: {info() {// 在计算属性的getter中,尽量只做读取相关的逻辑// 不要执行那些会产生(副)作用的代码,即不修改console.log("---> , info调用了!")return this.stu.age >= 18? "你是一个成年人!!!": "你是一个未成年人!!!"},// 计算属性的简写(只有getter时)// name(){//     return this.lastName + this.firstName// }// 可以为计算属性设置setter,使得计算属性可写,但是不建议这么做name: {get() {return this.lastName + this.firstName},set(value) {// set在计算属性被修改时调用this.lastName = value[0]this.firstName = value.slice(1)}}}
}
</script>
<template><p>{{ msg }}</p><h1>{{ stu.name }} -- {{ stu.age }} -- {{ stu.gender }}</h1><h2>评语:{{ info }}</h2><h2>methods:{{ getInfo() }}</h2> <!--与上边info的效果一样,区别在于computed不会每次都调用,也不需要加括号--><button @click="updateAge">减龄</button><hr /><!-- <h3>{{ info }}</h3> --><h3>{{ name }}</h3><hr /><h2>{{ arr[0] }} -- {{ arr[1] }} -- {{ arr[2] }}</h2>
</template>

http://www.ppmy.cn/news/18607.html

相关文章

人大金仓数据库的用户与角色

创建用户 create user 用户名 授予用户创建数据库权限 alter user 用户名 要给的权限 然后查看用户信息 \du 用户名 设置用户密码 没有口令不能登录 alter user 用户名 password ‘kingbase’; 修改用户的并发连接数 alter user 用户 connection limit 要设置的连接数; 修改…

软件工程 黄金点游戏

这个故事最初出现在 《移山之道》中&#xff0c;我经常拿来做和创新的时机相关课堂练习和讨论&#xff0c;效果很好。我把这个练习和它的一些延伸话题都搬到这个新博客里。 黄金点游戏 N个同学&#xff08;N通常大于10&#xff09;&#xff0c;每人写一个 0~100之间的有理数 …

【GIT】git本地代码上传到github

第一步&#xff1a;建立git仓库 cd到你的本地项目根目录下&#xff0c;执行git命令 git init 1.2重命名当前分支&#xff1a; git branch -m <new_branch_name> 第二步&#xff1a;将项目的所有文件添加到仓库中 git add . 如果想添加某个特定的文件&#xff0c;只需…

cmake 03 一个可用的 cmake 工程应当是什么样的

cmake 学习笔记 代码地址: https://gitcode.net/u014254963/cmake-study/-/tree/master/hello_cmake_project https://gitcode.net/u014254963/cmake-study/-/tree/master/hello_cmake_project_vs 本文目标 多目录构建引用自己写的动态库关于单元测试的一些实践使用 python 脚…

Acwing——第 87 场周赛

题目链接 4797. 移动棋子 4798. 打怪兽 4799. 最远距离 题目描述 4797. 移动棋子 给定一个 5 行 5 列的方格矩阵&#xff0c;其中一个方格中有一个棋子。 现在&#xff0c;我们希望将棋子移动至矩阵的最中心方格中&#xff0c;即将其移动至矩阵的第 3行第 3列方格中。 每次…

Cheat Engine7.4 训练教程(非常详细)

目录 一.CE是干什么的&#xff1f; 二.怎么获得&#xff1f; 三.训练教程 步骤 1: 加载进程 步骤 2: 精确值扫描 步骤 3: 未知的初始值 步骤 4: 浮点数 步骤 5: 代码查找 步骤 6: 指针 步骤 7: 代码注入 步骤 8: 多级指针 提示&#xff1a;这篇文章不是一天写完的&a…

领域驱动设计(DDD)的几种典型架构介绍

我们生活中都听说了DDD&#xff0c;也了解了DDD&#xff0c;那么怎么将一个新项目从头开始按照DDD的过程进行划分与架构设计呢&#xff1f; 一、专业术语 各种服务 IAAS&#xff1a;基础设施服务&#xff0c;Infrastructure-as-a-service PAAS&#xff1a;平台服务&#xff0c…

铸造性能监控平台【grafana+influxdb/prometheus+Linux/Windows】

目录一、grafanainfluxdbjmeter1、前言2、安装grafana和influxdb3、启动grafana4、访问grafana5、启动influxdb6、配置influxdb和jmeter7、在grafana中显示数据8、其他模板二、grafanaprometheusexporter1、前言2、grafana启动3、exporter安装与运行4、prometheus安装与运行5、…