Pārlūkot izejas kodu

vue3.0初识

master
maomincoding pirms 4 gadiem
vecāks
revīzija
2d55a226ea
1 mainītis faili ar 410 papildinājumiem un 0 dzēšanām
  1. 410
    0
      专题/前端/vue3初识/index.md

+ 410
- 0
专题/前端/vue3初识/index.md Parādīt failu

@@ -0,0 +1,410 @@
1
+![在这里插入图片描述](https://img-blog.csdnimg.cn/20201008225507487.png#pic_center)
2
+
3
+# 初识
4
+
5
+## 什么是Vue?
6
+
7
+渐进式JavaScript 框架。渐进式就是指可以由浅入深的,由简单到困难的一种方式。
8
+## 它的优点都有什么?
9
+
10
+vue.js拥有更小的体积,压缩后的vue.js就只有33k;vue.js拥有更高的运行效率,vue.js是基于`虚拟dom`的,虚拟dom是一种可以预先通过JavaScript进行各种计算,把最终的dom操作计算出来并进行优化的技术。
11
+
12
+因为这个Dom的操作属于预处理操作,并没有真实的操作Dom,所以叫做虚拟Dom。
13
+
14
+vue.js基于虚拟Dom操作,大幅度提高了Dom的操作以及渲染效率。不仅如此,vue.js还实现了双向数据绑定。vue.js的双向数据绑定,让开发者不用再去操作Dom对象,可以把更多的精力投入到业务逻辑上。
15
+
16
+## vue3.0学习路线
17
+1. 先学习vue2.x,很多2.x内容依然保留;
18
+2. 先学习TypeScript,vue3.0是用TS重写的,想知其然知其所以然必须学习TS。
19
+
20
+## 为什么学习vue3.0?
21
+- 性能比vue2.x快1.2~2倍
22
+- 按需编译,体积比vue2.x更小
23
+- 组合API
24
+- 更好的TS支持
25
+- 暴露了自定义渲染API
26
+- 更先进的组件
27
+
28
+## vue3.0是如何变快的?
29
+### 1、diff方法优化
30
+
31
+vue2.x中的虚拟dom是进行全量的对比。而vue3.0新增了静态标记。在与上次虚拟节点进行对比的时候,只对比带有patch flag的节点,并且可以通过flag的信息得知当前节点要对比的具体内容。
32
+
33
+下面我们来举个例子,以下是代码片段。
34
+```html
35
+<div>
36
+  <p>标签</p>
37
+  <p>{{msg}}</p>
38
+</div>
39
+```
40
+vue2.x的diff算法是对虚拟dom树全量的对比。
41
+
42
+![在这里插入图片描述](https://img-blog.csdnimg.cn/20201011230003622.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDQ1NjQ1,size_16,color_FFFFFF,t_70#pic_center)
43
+
44
+vue3.0的diff算法在创建虚拟dom的时候,会根据dom中的内容是否发生变化,添加静态标记。只对比带有patch flag的节点。
45
+
46
+![在这里插入图片描述](https://img-blog.csdnimg.cn/20201011232453479.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDQ1NjQ1,size_16,color_FFFFFF,t_70#pic_center)
47
+
48
+我们可能看上面这个图不是很明白,那我们就用另一种方式直观看下。你们可以看到下图中存在数据绑定的元素中存在静态标记`1`,测试网址:
49
+
50
+https://vue-next-template-explorer.netlify.app/
51
+
52
+
53
+![在这里插入图片描述](https://img-blog.csdnimg.cn/20201012103554965.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDQ1NjQ1,size_16,color_FFFFFF,t_70#pic_center)
54
+
55
+### 2、hoistStatic(静态提升)
56
+
57
+vue2.x中无论元素是否参与更新,每次都会重新创建,然后再渲染。vue3.0中对于不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可。
58
+
59
+我们再来去那个测试网站,在静态标记的选项前面打上对号,这时我们会发现不同,右边之前数据固定不变的标签,也就是这里的`<p>标签</p>`,被放在了`render`函数的外面。所以这样只会在全局创建一次,这样性能就明显提升了。
60
+
61
+![在这里插入图片描述](https://img-blog.csdnimg.cn/2020101210410916.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDQ1NjQ1,size_16,color_FFFFFF,t_70#pic_center)
62
+### 3、cacheHandlers(事件侦听器缓存)
63
+
64
+默认情况下,如`onClick`事件会被视为动态绑定,所以每次都会追踪它的变化,但是因为是同一个函数,所以不用追踪变化,直接缓存起来复用即可。
65
+好,我们来对比一下开启事件侦听器缓存前后。
66
+
67
+- 未开启事件侦听器缓存
68
+
69
+我们会看到有一个静态标记,所以每次都会追踪。
70
+
71
+![在这里插入图片描述](https://img-blog.csdnimg.cn/20201012105810780.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDQ1NjQ1,size_16,color_FFFFFF,t_70#pic_center)
72
+- 开启事件侦听器缓存
73
+
74
+在事件侦听器缓存前打上对号,开启。我们看到没有了静态标记,就没有对比追踪了,性能就提升了。
75
+
76
+![在这里插入图片描述](https://img-blog.csdnimg.cn/20201012110020549.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDQ1NjQ1,size_16,color_FFFFFF,t_70#pic_center)
77
+
78
+​
79
+# 实战
80
+
81
+## 一、项目搭建
82
+vite是尤大大开发的一款意图取代webpack的工具。其实现原理是利用ES6的import发送请求加载文件的特性。拦截这些请求,做一些编译,省去webpack冗长的打包时间。并将其与Rollup捆绑在一起用于生产。
83
+在开发过程中没有捆绑。源代码中的ES Import语法直接提供给浏览器,浏览器通过本机`<script module>`支持对其进行解析,从而为每次导入发出HTTP请求。开发服务器拦截请求,并在必要时执行代码转换。例如,对`*.vue`文件的导入会在发送回浏览器之前即时进行编译。
84
+
85
+1、全局安装vite脚手架
86
+```bash
87
+npm install -g create-vite-app
88
+```
89
+2、使用脚手架创建项目
90
+```bash
91
+create-vite-app projectName
92
+```
93
+3、进入项目文件夹
94
+```bash
95
+cd projectName
96
+```
97
+4、安装依赖
98
+```bash
99
+npm install
100
+```
101
+5、启动vue3.0项目
102
+```bash
103
+npm run dev
104
+```
105
+## 二、vue2.x存在的问题
106
+2.x中的一点问题是当业务不断增多时,数据跟逻辑分散,会很难维护。
107
+
108
+```html
109
+<template>
110
+  <div>
111
+    <div>
112
+      <input type="text" v-model="obj.id">
113
+      <input type="text" v-model="obj.con">
114
+      <button @click="submit">提 交</button>
115
+    </div>
116
+    <ul>
117
+      <li v-for="(item,index) in list" :key="item.id" @click="cli(index)">
118
+        {{item.id}}-{{item.con}}
119
+      </li>
120
+    </ul>
121
+  </div>
122
+</template>
123
+
124
+<script>
125
+export default {
126
+  name:"filterBox",
127
+  data(){
128
+    return {
129
+      list:[
130
+        {
131
+          id:1,
132
+          con:"a"
133
+        },
134
+        {
135
+          id:2,
136
+          con:"b"
137
+        }
138
+      ],
139
+      obj:{
140
+        id:"",
141
+        con:""
142
+      }
143
+      // 代码数据1
144
+      // 代码数据2
145
+      // ...
146
+    }
147
+  },
148
+  methods:{
149
+    cli(index){
150
+      this.list = this.list.filter((item,idx)=>idx!==index);
151
+      console.log(this.list);
152
+    },
153
+    submit(){
154
+      // const obj = Object.assign({},this.obj);
155
+      this.list.push(this.obj);
156
+      this.obj.id = "";
157
+      this.obj.con = "";
158
+    },
159
+    // 执行代码代码逻辑3
160
+    // ...
161
+  },
162
+  computed:{
163
+  	// 执行代码代码逻辑1
164
+  },
165
+  watch:{
166
+   // 执行代码逻辑2
167
+  }
168
+}
169
+</script>
170
+
171
+<style>
172
+
173
+</style>
174
+```
175
+## 三、组合API
176
+### **ref**
177
+
178
+```html
179
+<template>
180
+  <div>
181
+    <p>{{count}}</p>
182
+    <button @click="add">add</button>
183
+  </div>
184
+</template>
185
+
186
+<script>
187
+import {ref} from "vue"
188
+export default {
189
+  name: 'App',
190
+  setup(){
191
+    // 定义一个名称叫做count变量,这个变量的初始值是0
192
+    // 这个变量发生该改变之后,vue会自动更新页面。
193
+    const count  = ref(0);
194
+	// 在组合API中,如果想定义方法,不用定义到methods中,直接在setup函数中定义即可。
195
+    const add = () => {
196
+      count.value+=1;
197
+    }
198
+	// 在组合API中定义的变量/方法,要想在外界使用,必须return出去。
199
+    return {
200
+      count,
201
+      add
202
+    }
203
+  }
204
+}
205
+</script>
206
+
207
+```
208
+`ref`只能监听简单类型的变化,不能监听复杂类型的变化(对象/数组)。
209
+
210
+另外,需要注意的是,如果是通过`ref`创建出来的数据,那么在`template`中使用的时候不用通过`.value`来获取。因为Vue会自动给我们添加`.value`	。
211
+
212
+### **reactive**
213
+`reactive` 可以监听复杂类型的变化,如对象或者数组。
214
+
215
+```js
216
+let state = reactive({
217
+	name:"maomin"
218
+});
219
+// 或
220
+let arr = reactive([1,2,3]);
221
+```
222
+我们来做一个小demo。
223
+```html
224
+<template>
225
+  <div>
226
+    <ul>
227
+      <li v-for="(item,index) in state.list" :key="item.id" @click="removeItem(index)">{{item.id}}--{{item.con}}</li>
228
+    </ul>
229
+  </div>
230
+</template>
231
+
232
+<script>
233
+import {reactive} from "vue"
234
+export default {
235
+  name: 'App',
236
+  setup(){
237
+    const state  = reactive({
238
+      list:[
239
+        {
240
+          id:1,
241
+          con:"A"
242
+        },
243
+        {
244
+          id:2,
245
+          con:"B"
246
+        },
247
+        {
248
+          id:3,
249
+          con:"C"
250
+        }
251
+      ]
252
+    });
253
+
254
+    const removeItem = (index) => {
255
+      state.list = state.list.filter((item,i)=>i!==index)
256
+    }
257
+
258
+    return {
259
+      state,
260
+      removeItem
261
+    }
262
+  }
263
+}
264
+</script>
265
+
266
+```
267
+我们可以改变下,把数据跟逻辑放在一块,这样就解决了vue2.x的数据跟逻辑分散的问题。
268
+```html
269
+<template>
270
+  <div>
271
+    <ul>
272
+      <li
273
+        v-for="(item, index) in state.list"
274
+        :key="item.id"
275
+        @click="removeItem(index)"
276
+      >
277
+        {{ item.id }}--{{ item.con }}
278
+      </li>
279
+    </ul>
280
+  </div>
281
+</template>
282
+
283
+<script>
284
+import { reactive } from "vue";
285
+export default {
286
+  name: "App",
287
+  setup() {
288
+    let {state,removeItem} = userReturn();
289
+    return {
290
+      state,
291
+      removeItem,
292
+    };
293
+  },
294
+};
295
+
296
+function userReturn(params) {
297
+  const state = reactive({
298
+    list: [
299
+      {
300
+        id: 1,
301
+        con: "A",
302
+      },
303
+      {
304
+        id: 2,
305
+        con: "B",
306
+      },
307
+      {
308
+        id: 3,
309
+        con: "C",
310
+      },
311
+    ],
312
+  });
313
+
314
+  const removeItem = (index) => {
315
+    state.list = state.list.filter((item, i) => i !== index);
316
+  };
317
+
318
+  return {state,removeItem}
319
+}
320
+</script>
321
+
322
+```
323
+
324
+## 四、组合API本质
325
+`compositionAPI`与`optionAPI`可以混合使用。其本质是注入。
326
+
327
+```html
328
+<template>
329
+  <div>
330
+    <p>Vue2.x</p>
331
+    <button @click="cli1">点击</button>
332
+    <p>Vue3.0</p>
333
+    <button @click="cli2">点击</button>
334
+  </div>
335
+</template>
336
+
337
+<script>
338
+import {ref} from "vue"
339
+export default {
340
+  name:"Demo2",
341
+  data(){
342
+    return {
343
+      msg:"Vue2.x"
344
+    }
345
+  },
346
+  methods:{
347
+    cli1(){
348
+      alert(this.msg);
349
+    }
350
+  },
351
+  setup(){
352
+    let txt = ref("Vue3.0"); // 注入到data函数内
353
+    function cli2() { // 注入到methods属性内
354
+      alert(txt.value); 
355
+    }
356
+    return {
357
+      txt,
358
+      cli2
359
+    }
360
+  }
361
+}
362
+</script>
363
+
364
+<style>
365
+
366
+</style>
367
+```
368
+## 五、setup执行时机与注意事项
369
+setup函数,是在`beforecreate`钩子之前完成的。所以无法使用`data`跟`methods`。
370
+另外要注意的是setup是同步的,不是异步的。
371
+
372
+```html
373
+<template>
374
+  <div>
375
+    <button @click="name">打开</button>
376
+  </div>
377
+</template>
378
+
379
+<script>
380
+export default {
381
+  name:"Demo3",
382
+  data(){
383
+    return {
384
+      msg:"hello"
385
+    }
386
+  },
387
+  setup(){
388
+    function name() {
389
+      console.log(this.msg); // undefined
390
+    }
391
+    return {
392
+      name
393
+    }
394
+  }
395
+}
396
+</script>
397
+
398
+<style>
399
+
400
+</style>
401
+```
402
+# 适合Vue3.0开发的UI框架
403
+
404
+**Ant Design of Vue**
405
+
406
+https://2x.antdv.com/docs/vue/introduce-cn/
407
+
408
+**Vant**
409
+
410
+https://vant-contrib.gitee.io/vant/next/#/zh-CN/

Notiek ielāde…
Atcelt
Saglabāt