vue3.0——setup函数/属性、响应式API、ref函数、reactive函数、响应式原理、计算属性

vite版本创建方式:

npm init vite viteapp -- --template vue

main.js的样子:

 

一、setup

(1) setup() 函数:

  • 语法:返回的对象的成员可以在模板中使用,也可以在组件的api中使用

                  但是在这个函数中不能使用组件api中的东西

  • 作用:为hook提供开发场景

    • setup函数中可以声明一些变量/函数  然后返回出去 供组件使用

    • setup函数可以设计成 script标签中写这个同名单词的属性 然后使整个标签环境都为setup函数环境(脚手架实现的)

    • setup函数内部的变量可以去设计为响应式的变量 可以使用官方的hook即ref reactive等工具

  • 特点:
    • 这个函数内部的函数/变量是局部的

    • 这个函数的返回值可以被当前组件的任意地方使用

    • 这个函数内部不能使用this来操作组件数据

    • setup返回的对象中的数据和data中的数据同名了 setup的优先级更高

    •  setup在组件加载期间,只会运行一次

  • 示例:

<script>
export default {
  setup(props) {
    var a = "这是标题";
    var b = [1, 2, 3];
    function fn() {
      console.log("fn");
    }
    var hookmsg = "hookmsg";
    function changehookmsg() {
      hookmsg = "修改了hookmsg";
      console.log("修改了hookmsg,但是数据不改");
    }
    //return出来后才能供外部使用  使用打包工具就可以不用一个一个导出
    return { title: "yoyo", b, fn,changehookmsg ,hookmsg};
  }
};
</script>

<template>
  <div>
      <p>{{title}}</p>
      <div v-for="(el, index) in b" :key="index">
        <p>{{el}}</p>
      </div>
      <button @click="fn">fn</button>
      <p>{{hookmsg}}--非响应式的</p>
      <button @click="changehookmsg">changehookmsg</button>  
  </div>
</template>
  • 结果显示:

(2) setup属性:(setup函数的语法糖)

  setup属性:

  • 会让打包工具打包时直接帮忙把setup函数内部声明的变量/函数 return 然后外部就可以使用了 不需要this
  • 可以直接导入组件 直接使用  不用注册和懒加载...
  • 示例:
<script setup>
    var a = "yoyo";
    var b = [1, 2, 3];
    var msg="hello";
    function fn() {
      console.log("fn");
    }
    var hookmsg = "hookmsg";
    function changehookmsg() {
      hookmsg = "修改了hookmsg";
      console.log("修改了hookmsg,但是数据不改");
    }
    function change() {
         msg = "haha";
         console.log("修改了msg,但是数据不改");
    }
</script>

<template>
  <div>
      <p>{{msg}}</p>
      <button @click="change">修改msg</button>
      <p>{{a}}</p>
      <div v-for="(el, index) in b" :key="index">
        <p>{{el}}</p>
      </div>
      <button @click="fn">fn</button>
      <p>{{hookmsg}}--非响应式的</p>
      <button @click="changehookmsg">changehookmsg</button>
    
  </div>
</template>
  • 显示结果:

 二、响应式API——ref函数

  • 作用:定义一个响应式的数据,可根据需求灵活设计数据是否为响应式

                  让数据之间是独立的,只局部刷新绑定了ref的变量

  • 语法:let xxx = ref("value")

    • 创建一个包含响应式的数据的引用对象(reference对象)

    • js中操作数据:xxx.value="new_value"

    • 模板中读取数据不需要.value,直接<div>{{xxx}}</div>

  • 注意

    • 接收的数据类型可以是基本数据类型也可以是引用数据类型

    • 基本类型的数据:响应式依然是靠Object.defineProperty()的get和set完成的

    • 对象类型的数据:内部“求助”了Vue3.0的一个新的函数------reactive函数

  • 响应式设计:

就是监听了value的改变 劫持value属性的setter getter

因此ref一般用在基本数据,或者引用数据的嵌套层级不深的数据上

  • 示例:
<script setup>
	import {ref} from "vue"
	//msg0为普通变量
	let msg0="msg0--hello"
	//msg为响应式的变量
	let msg=ref("msg--hello")
	let changeMSG0=()=>{
		msg0.value="msg0改变了"
		console.log(msg0.value)
	}
	let changeMSG=()=>{
		msg.value="msg改变了"
		console.log(msg.value)
	}
</script>
<template>
	<div>
		<p>{{msg0}}</p>
		<button @click="changeMSG0">修改msg0</button>
		<p>{{msg}}</p>
		<button @click="changeMSG">修改msg</button>
	</div>
</template>
  • 显示结果:

 三、响应式API——reactive函数

  • 作用:定义一个对象类型的响应式数据(基本数据类型用ref函数)

  • 语法:const 代理一个对象 = reactive(被代理的对象) 接收一个对象(或数组),返回一个代理器对象(proxy对象)

    • js中操作数据:不需要.value 直接操作对象

  • 注意:reactive定义的响应式数据是“深层次的”

  • 响应式设计:

跟ref一样 但是底层基于ES6的Proxy实现,代理了整个引用数据

  • 示例:
<script setup>
import {  reactive } from "vue";
let arr = reactive([
  { name: "红烧肉", info: { price: 21, state: "可出餐" }, count: 5 },
  { name: "肉末茄子", info: { price: 18, state: "已售完" }, count: 0 },
  { name: "水煮肉片", info: { price: 40, state: "可出餐" }, count: 2 }]
);
let changearr = () => {
  arr[1].info.state ="可出餐";
  arr[1].count =1;
};
</script>
<template>
	<div>
		<div v-for="(item, index) in arr" :key="index">
			<p>{{item}}</p>
		</div>
		<button @click="changearr">changearr</button>	
	</div>
</template>
  • 显示结果:

四、Vue2.0和Vue3.0中的响应式原理

(1)vue2.0的响应式

  • 实现原理

    • 对象类型:通过Object.definedProperty()对属性的读取、修改进行拦截(数据劫持)

    • 数组类型:通过重写更新数据的一系列方法来实现拦截。(对数组的方法进行了包裹)

    存在问题:

    • 新增属性,删除属性都不会刷新界面

    • 直接通过下标修改数组,界面不会自动更新

(2)vue3.0的响应式

  • 实现原理

    • 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性的读写,属性的添加,属性的删除等

    • 通过Reflect(反射):对被代理对象的属性进行操作

    • MDN文档中描述的Proxy与Reflect:

五、计算属性

  • 与vue2.x中computed配置功能一致

示例:

<script setup>
import { reactive, computed } from "vue";
let arr = reactive([
  { name: "红烧肉", info: { price: 21, state: "可出餐" }, count: 5 },
  { name: "肉末茄子", info: { price: 18, state: "已售完" }, count: 0 },
  { name: "水煮肉片", info: { price: 40, state: "可出餐" }, count: 2 }
]);

let total = computed(() => {
  console.log("计算了1次总价");
  return arr.reduce((n1, n2) => {
    return n1 + n2.info.price * n2.count;
  }, 0);
});
let changename = () => {
  arr[0].name ="麻婆豆腐";
  console.log("修改了菜名但没有修改价格和数量,不触发computed")
};
let changecount = () => {
  arr[0].count =6;
  console.log("修改了数量,触发了computed")
};

</script>

<template>
	<div class="box">
    <h3>Box1</h3>
		<div v-for="(el, index) in arr" :key="index">
			<div>
        <button @click="changename">修改菜名</button>
        {{el.name}}:{{el.info.price}}元		
		  	<span>数量:{{el.count}}</span>
        <button @click="changecount">修改数量</button>
			</div>
		</div>
		<p>  利润:<b>{{total}}元</b></p> 
	</div>
</template>

结果显示:

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈ha~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值