vue3基础语法

Myth丶恋晨 2021-09-07 06:12 885阅读 0赞

一.组合式 API 也就是composition-api

(1) vue2 组件的局限性

  1. 组件越大,可续性越差

  2. 相同的代码逻辑很难在多个组件中复用

(2) 提供以下几个函数

  1. setup :组合api 的方法都是写在这里面的

  2. ref : 定义响应式数据 字符串 bool

  3. reactive :定义响应式数据 对象

  4. watchEffet :监听数据变化

  5. watch :监听数据变化

  6. computed :计算属性

  7. toRefs :解构响应式对象数据

  8. 生命周期的hooks

(2.1) setup

官网

  1. setup 函数会在 beforeCreate、created 之前执行,setup的生命周期 在 beforeCreate、created 之后执行

  2. setup 有2个参数

props 的父组件传递过来的参数

  1. ctx 上下文对象
  2. ctx.attrs
  3. ctx.slots
  4. ctx.parent
  5. ctx.root
  6. ctx.emit
  7. ctx.refs
  1. 在 setup() 函数中无法访问到 this【没有 this。这意味着,除了 props 之外,你将无法访问组件中声明的任何属性——本地状态、计算属性或方法。】

  2. 执行 setup 时,组件实例尚未被创建,你只能访问以下 property【props,attrs, slots, emit 】,你将无法访问以下组件选项【data,computed ,methods】

(2.2) ref ,reactive 定义响应式数据

ref 【定义字符串,num,bool,数组】

reactive【定义对象】

(2.3) toRefs 解构响应式对象数据

2.toRefs 解构响应式对象数据

{ {worksName}}

setup() {

  1. // 2.toRefs 解构响应式对象数据
  2. var worksInfos = reactive(\{
  3. worksName: "张三",
  4. worksDesi: "到好多好好的"
  5. \});
  6. return \{
  7. ...toRefs(worksInfos) //...worksInfos 这样的话可以显示数据,但是不能双向绑定数据
  8. \};

}

(2.4) computed 计算属性 【只能在setup】

  1. <input v-model="lastName" />
  2. <div>\{ \{fullName\}\}</div>
  3. setup() \{
  4. //3.computed :计算属性
  5. var userInfos2 = reactive(\{
  6. firstName: "王",
  7. lastName: "一搏"
  8. \});
  9. var fullName = computed(() => \{
  10. return userInfos2.firstName + userInfos2.lastName;
  11. \});
  12. return \{
  13. ...toRefs(userInfos2),
  14. fullName
  15. \};

(2.5) readonly “深层”的只读代理 (少用)

将响应式 数据(ref,reactive定义的数据),转正非响应式的数据(也就是原始数据)

readonly 传入一个对象(响应式对象),返回一个原始对象 只能读取不能修改。

var obj={

  1. username:"李小英"

}

obj 就是原始数据, 可以渲染在页面中,但是不能双向绑定

var userInfos = reactive({

  1. username: "张三",
  2. age: 20

});

userInfos 响应式数据,

可以把响应式数据 转成非响应式数据,

const copy = readonly(userInfos) //copy.username 只能读取,不能修改

(2.6) watchEffet 监听数据变化

  1. 在响应式地跟踪其依赖项时,立即运行一个函数,并在更改依赖项时重新运行它。

4.watchEffet 监听数据变化 —侦听器

  1. <div>\{ \{data.count\}\}</div>
  2. <button @click="stop">手动关闭侦听器</button>
  3. const data = reactive(\{
  4. count: 1,
  5. num: 1
  6. \});
  7. const stop = watchEffect(() => \{
  8. console.log("侦听器:", data.count);
  9. \});
  10. setInterval(() => \{
  11. data.count++;
  12. \}, 1000);

(2.7) watch , watch与watchEffect区别

1.watch与watchEffect区别:

const data = reactive({

  1. count: 10,
  2. num: 1

});

  1. 懒执行,也就是说只有侦听的值变更时才执行回调

    watchEffect(() => {

    1. console.log("侦听器:", data.count);// 可以输出1

    });

    watch(data, () => {

    1. console.log("watch 监听:", data.count);// 输出2

    });

    watch 只有监听到值(data.count)发生变化 才执行,watchEffect都可以执行

  2. 更明确哪些状态的改变会触发侦听器重新运行

    watchEffect 可以监听具体的对象【如:data.count】,watch 只能监听ref或是reactive定义的对象【如: data】

  3. 访问侦听状态变化前后的值

    watch(numVal, (newVal, oldVal) => {

    1. console.log("numVal新值跟旧值的变化:", newVal, oldVal);

    });

案例:

5.watch 监听数据变化 —侦听器

  1. <div>\{ \{data.count\}\}</div>
  2. <div>watch 双向数据绑定,前后数据</div>
  3. \{ \{numVal\}\}
  4. <input v-model="numVal" />
  5. <input v-model=data.count"/>
  6. const data = reactive(\{
  7. count: 10,
  8. num: 1
  9. \});
  10. // (1).简单的引用
  11. // 要监听对象data ,但是不能监听对象里的值data.count
  12. watch(data, () => \{
  13. console.log("watch 监听:", data.count);
  14. \});
  15. setInterval(() => \{
  16. data.count++;
  17. \}, 1000);
  18. var numVal = ref("1");
  19. // (2).watch 的两个参数,代表新的值和旧的值
  20. watch(numVal, (newVal, oldVal) => \{
  21. console.log("numVal新值跟旧值的变化:", newVal, oldVal);
  22. \});
  23. //(3). watch 多个值,返回的也是多个值的数组
  24. watch(\[numVal, data\], (newValue, oldValue) => \{
  25. console.log("old", oldValue); //\["13",Proxy \{count: "144", num: 1\}\]
  26. console.log("new", newValue); //\["134",Proxy \{count: "144", num: 1\}\]
  27. \});
  28. // (4).使用 getter 的写法 watch reactive 对象中的一项
  29. watch(\[numVal, () => data.count\], (newValue, oldValue) => \{
  30. console.log("old", oldValue); //old (2) \["1", 10\]
  31. console.log("new", newValue); //new (2) \["1", "103"\]
  32. console.log("updated:" + numVal.value + data.count); //updated:1103
  33. \});

(2.8) 生命周期

生命周期的vue3更新:

在vue3中对生命周期钩子的命名进行一些简单的命名更新,并且在setup函数中提供了新的生命周期函数钩子。

1. 命名改变

vue3对beforeDestroy 和destroy进行命名的修改,分别修改为beforeUnmount,unmounted。这个是命名的改变,回调时机上并没有发生任何的改变。

2. setup函数中提供了新的生命周期函数钩子

官网

都是 setup () 内部调用生命周期钩子,没有beforeCreate,created ,其他都是一样

(2.9)Provide / Inject

官网

不管组件层次 结构多深,都可以使用这个Provide(传递参数) / Inject (接受参数)

1.非组合api 写法

app.vue

provides:

location.vue:

点击fn,不能改变location.vue的值,就是没有响应的效果

没有办法 双向绑定

2. 组合api (重点)

provides:

location.vue:

3. 总结:

1.祖父组件定义provide,孙组件inject接受

2.provide inject实现父子组件传值的时候,子组件改变数据也会影响父组件

4. 不想子组件改变父组件的数据

最后,如果要确保通过 provide 传递的数据不会被 inject 的组件更改,我们建议对提供者的 property 使用 readonly

provide(“userInfos”, readonly(userInfos));

二.响应性

(1)比较vue2 和 vue3 响应式

1. vue2 的响应式:

核心:

对象:通过defineProperty对对象的已有属性值的读取和修改进行劫持(监视、拦截)

数组:通过重写数组更新数组一系列更新元素的方法实现元素修改的劫持【简单的理解:普通数组变成响应数组,对一个数组的元素进行更改的话,它会对这个更改的方法进行重新编写】

object.defineProperty(data,’count’,{

  1. get()\{\},
  2. set()\{\}

})

问题:

1). 对象直接新添加的属性或删除已有属性,界面不会自动更新

2). 直接通过下标替换元素或更新length,界面不会自动更新 arr[1] ={}

所以后面才有$set,去响应数据



{ {key}}:{ {val}}
  1. <button @click="add">修改数据</button>
  2. </div>
  3. //因为vue2 是通过object.defineProperty 来操作数据,所以不能检测数据的变动(虽然打印出来的数据是更新的,但是界面的数据没更新)
  4. export default \{
  5. data() \{
  6. return \{
  7. user: \{
  8. name: "王一博",
  9. age: 20
  10. \}
  11. \};
  12. \},
  13. methods: \{
  14. add() \{
  15. this.user.sex = "男";
  16. console.log( this.user);
  17. \}
  18. \}
  19. \};

注意同样的代码在vue3 里面就可以。不旦数据更新,界面也更新。原因是vue3使用prory

2.vue3 的响应式:

核心:

1).通过proxy(代理):拦截对data任意属性的任意(13种)操作,包括属性值的读写,属性的添加,属性的删除等

2).通过reflect(反射):动态对被代理对象的相应属性进行特定的操作

(2) 什么是响应式

  1. 响应性是一种允许我们以声明式的方式去适应变化的一种编程范例。

简单的理解:对对象进行修改,对象数据会改变,界面上也会发生改变

(3)深入vue3响应性原理

就是把目标对象变成代理对象(prory),然后通过代理对象对数据进行操作,通过reflect在反射回来。

let user = {

  1. name: "王一博",
  2. age: 20,
  3. words: \{
  4. adds: "g区18号",
  5. tell: "1727283848744",
  6. cars: \["宝马", "奥迪", "本田"\]
  7. \}
  8. \};
  9. // 把目标对象变成代理 对象
  10. // 使用prory 从new Proxy开始接受2个参数
  11. // 参数1:target目标对象----》 user
  12. // 参数2:Handel 处理器对象,用来监视数据及数据操作----》\{\}
  13. const proxyUser = new Proxy(user, \{
  14. // 获取目标对象的某个属性值
  15. //target目标对象。property被获取的属性名。
  16. get(target, prop) \{
  17. console.log("get方法调用了");
  18. return Reflect.get(target, prop);
  19. \},
  20. // 修改、添加目标对象的属性
  21. //target目标对象。property被获取的属性名 value 值
  22. set(target, prop, value) \{
  23. console.log("set方法调用了");
  24. return Reflect.set(target, prop, value);
  25. \},
  26. // 删除目标对象的某个属性值
  27. //target目标对象。property被获取的属性名
  28. deleteProperty(target, prop) \{
  29. console.log("delete方法调用了");
  30. return Reflect.deleteProperty(target, prop);
  31. \}
  32. \});
  33. // 通过代理对象获取目标对象中的某个属性值
  34. console.log(proxyUser.name);
  35. // 通过代理对象更新目标对象上的某个属性值
  36. proxyUser.name = "肖战";
  37. console.log("修改属性值:", user);
  38. //通过代理对象向目标对象添加一个新的属性
  39. proxyUser.sex = "男";
  40. console.log("添加新属性:", user);
  41. //通过代理对象删除目标对象的某个属性值
  42. delete proxyUser.age;
  43. console.log("删除age 后:", user);
  44. //深度的添加属性值
  45. proxyUser.words.name = "航天信息";
  46. console.log("深度的添加属性值:", user);

(4)什么是prory

proxy 是一个对象,可以代理一个对象或函数,允许拦截被代理的对象或函数

(5) Reflect

reflect

三.有意思的Teleport

官网

teleport 是vue3 内置组件,接受2个函数(to:指定将在其中移动 内容的目标元素 如:body,.home ,#home;disabled :禁止使用该功能)

请注意,这将移动实际的 DOM 节点,而不是被销毁和重新创建,并且它还将保持任何组件实例的活动状态。所有有状态的 HTML 元素 (即播放的视频) 都将保持其状态。

核心就是to的操作

  1. <template>
  2. <div style="position: relative;">
  3. <h3>Tooltips with Vue 3 Teleport</h3>
  4. <div>
  5. <modal-button></modal-button>
  6. </div>
  7. </div>
  8. </template>
  9. <script>
  10. import Vue from "vue";
  11. var modalButton = {
  12. template: `
  13. <button @click="modalOpen = true">
  14. 打开弹窗
  15. </button>
  16. <teleport to="body">
  17. <div v-if="modalOpen" class="modal">
  18. <div>
  19. I'm a modal!
  20. <button @click="modalOpen = false">
  21. Close
  22. </button>
  23. </div>
  24. </div>
  25. </teleport>
  26. `,
  27. data() {
  28. return {
  29. modalOpen: false
  30. };
  31. }
  32. };
  33. export default {
  34. components: {
  35. "modal-button": modalButton
  36. },
  37. created() {}
  38. };
  39. </script>
  40. <style>
  41. .modal {
  42. position: absolute;
  43. top: 0;
  44. right: 0;
  45. bottom: 0;
  46. left: 0;
  47. background-color: rgba(0, 0, 0, 0.5);
  48. display: flex;
  49. flex-direction: column;
  50. align-items: center;
  51. justify-content: center;
  52. }
  53. .modal div {
  54. display: flex;
  55. flex-direction: column;
  56. align-items: center;
  57. justify-content: center;
  58. background-color: white;
  59. width: 300px;
  60. height: 300px;
  61. padding: 5px;
  62. }
  63. </style>

四.VueConf 2021

1.视频

2.尤雨溪:做技术哪有什么两全之策,都是取舍和平衡

发表评论

表情:
评论列表 (有 0 条评论,885人围观)

还没有评论,来说两句吧...

相关阅读

    相关 vue基础语法

    目录 1:vue基础语法 2:内容渲染指令(操作标签体中的内容) 2.1:v-text指令 2.2:插值语法\{ \{\}\}语法: 2.3:v-html指令 3:

    相关 vue3基础语法

    一.组合式 API 也就是composition-api (1) vue2 组件的局限性  1. 组件越大,可续性越差  2. 相同的代码逻辑很难在多个组件中复用