Vue3 带来的变化

源码

image.png

性能

image.png

新的 API

image.png

如何使用 Vue ?

Vue的本质,就是一个JavaScript的库,四种方式引入这个库:

  • 方式一:在页面中通过CDN的方式来引入;
  • 方式二:下载Vue的JavaScript文件,并且自己手动引入;
    • 可以打开CDN网址,复制里面的代码保存到一个 js 文件中,就是vue的源码。
  • 方式三:通过npm包管理工具安装使用它(webpack,vite);
  • 方式四:直接通过Vue CLI创建项目,并且使用它;

image.png

  1. <div id="app"></div>
  2. <script src="https://unpkg.com/vue@next"></script>
  3. <script>
  4. // 声明一个对象
  5. const why = {
  6. template: '<h2>Hello World</h2>'
  7. }
  8. // 存在全局对象 Vue,createApp() 接收一个对象创建一个vue实例
  9. const app = Vue.createApp(why);
  10. // 将实例挂载到元素中,替代掉元素中的内容
  11. app.mount("#app")
  12. </script>
  1. Vue.createApp({
  2. template: `<h2> hello </h2>`
  3. }).mount("#app")

声明式和命令式

image.png

MVVM 模型

MVC和MVVM都是一种软件的体系结构

  • MVC是Model – View –Controller的简称,是在前期被使用非常框架的架构模式,比如iOS、前端;
  • MVVM是Model-View-ViewModel的简称,是目前非常流行的架构模式;

通常情况下,我们也经常称Vue是一个MVVM的框架。

  • Vue官方其实有说明,Vue虽然并没有完全遵守MVVM的模型,但是整个设计是受到它的启发的。

在 vue 开发中,template 就是 view,createApp( ) 中的参数对象,就是 model,而 vue 自身就是 VM,起到了 dom 监听和数据绑定的作用。
image.png

template 属性

在使用createApp的时候,我们传入了一个对象,其中 template 属性表示Vue需要帮助我们渲染的模板信息。
template 属性中的字符串标签会替换掉我们挂载到的元素(比如id为app的div)里面的内容,先清空了 innerHTML

但是以字符串的形式写标签,没有任何提示和高亮,开发效率低。所以 vue 提供了两种方式来给 template 属性赋值。
方式一:使用script标签,并且标记它的类型为 x-template;
方式二:使用任意标签(通常使用template标签,因为不会被浏览器渲染),设置id;

  • template元素是 html 提供的一种用于保存客户端内容的机制,该内容在加载页面时不会被呈现,但随后可以在运行时使用JavaScript实例化
  • 如果使用其他元素标签,页面就会出现两次内容,一次是元素标签自身就渲染的,一次是 js 渲染的。

注意:无论是 script 标签还是 template 标签都必须有 id,并且 template 属性值以 # 开头,后面的内容就不会以标签识别,而是调用 querySelect 查找对应元素。

  1. <div id="app"></div>
  2. <script src="https://unpkg.com/vue@next"></script>
  3. <!-- script 标签模块。注意:必须要有 id-->
  4. <script type="x-template" id="templ">
  5. <h2> script 标签方式 </h2>
  6. </script>
  7. <script>
  8. const why = {
  9. template: "#templ" // 必须使用 #开头,看起来就和 id 选择器一样
  10. }
  11. const app = Vue.createApp(why);
  12. app.mount("#app")
  13. </script>
  1. <template id="templ">
  2. <h2> template 标签方式</h2>
  3. </template>

data 属性

data属性是传入一个函数,并且该函数需要返回一个对象:

  • 在Vue2.x的时候,也可以传入一个对象(虽然官方推荐是一个函数);
  • 在Vue3.x的时候,必须传入一个函数,否则就会直接在浏览器中报错;

data中返回的对象会被Vue的响应式系统捕获,之后对该对象的修改或者访问都会在劫持中被处理:

  • 所以我们在template中通过 {{counter}} 访问counter,可以从对象中获取到数据;
  • 所以我们修改counter的值时,template中的 {{counter}}也会发生改变;

    methods 属性

    methods 属性是一个对象,通常我们会在这个对象中定义很多的方法:

  • 这些方法可以被绑定到 template 模板中;

  • 在该方法中,我们可以使用this关键字来直接访问到data中返回的对象的属性; ```html

  1. <a name="r6H5k"></a>
  2. ## 方法为什么不能使用箭头函数?
  3. 因为使用箭头函数,向上查找作用域绑定 this 指向。methods 中的箭头函数向上一路都是对象,所以最终 this 会绑定到全局 window 上,而 window 又不能访问 data 中的数据,所以 methods 对象中的方法就不能使用箭头函数。
  4. 这和给元素添加监听事件回调函数类似,如果回调使用了箭头函数,就不能使用 this 来操作元素,因为此时 this 已经不指向该元素了。
  5. <a name="kISVs"></a>
  6. ## 不使用箭头函数的情况下,this指向的是什么?
  7. vue 会遍历 methods 对象中的所有函数,并对它们进行 bind 显示绑定当前模板对象对应的代理对象 Proxy。<br />bind 会返回修改好的函数,所以真正执行的其实是 bind 修改后的新函数。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22919157/1651126697210-d6bdb0ab-e0db-4e70-915c-e43f120ba01a.png#clientId=u04cc9308-2c58-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=386&id=u3e5d8292&margin=%5Bobject%20Object%5D&name=image.png&originHeight=483&originWidth=937&originalType=binary&ratio=1&rotation=0&showTitle=false&size=408545&status=done&taskId=u1e6648c2-3041-4609-9b4a-e9ac791729a&title=&width=749.6)
  8. <a name="UQh8J"></a>
  9. # 怎么阅读 Vue 的源码
  10. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22919157/1651126068913-2b7a6e73-c38f-400b-9c12-8ffc2e4b4dba.png#clientId=u04cc9308-2c58-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=414&id=udee0c0e9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=517&originWidth=874&originalType=binary&ratio=1&rotation=0&showTitle=false&size=124785&status=done&style=none&taskId=u65e9a144-58d7-4581-9dd5-eecc0b4cf98&title=&width=699.2)
  11. <a name="P7Gnx"></a>
  12. # (技巧)VSCode代码片段
  13. 对于一些重复代码,我们可以在 vscode 中配置用户代码片段,方便一键生成。<br />VSCode中的代码片段有固定的 json 格式,所以我们一般会借助于一个在线工具来完成<br />具体的步骤如下:
  14. - 第一步,复制自己需要生成代码片段的代码;
  15. - 第二步,[https://snippet-generator.app/](https://snippet-generator.app/)在该网站中生成代码片段;
  16. - 第三步,在VSCode中配置代码片段;
  17. ```json
  18. {
  19. "片段名字": {
  20. "prefix": "快捷指令",
  21. "body": [
  22. 代码片段
  23. ],
  24. "description": ""
  25. }
  26. }