鼎鼎知识库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.md 11KB

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