Vue 使用和概念的快速回顾 电脑版发表于:2021/2/2 18:24 # Vue 快速回顾 Vue 使用和概念的快速回顾,更多可查看官网文档 [Vue.js 官方文档](https://cn.vuejs.org/) ### 基础代码结构 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>render</title> </head> <body> <div id="app"> <p>公司名称:{{ company.name }}</p> <p>公司地址:{{ company.address }}</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { company: { name: "xxxx", address: "zzzzzzzz", }, }, }); </script> </body> </html> ``` 或者像这样 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>render</title> </head> <body> <div id="app"></div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ data: { company: { name: "xxxx", address: "zzzzzzzz", }, }, render(h) { return h("div", [ h("p", "公司名称:" + this.company.name), h("p", "公司地址:" + this.company.address), ]); }, }).$mount("#app"); </script> </body> </html> ``` ### 生命周期 [Vue 官网文档生命周期图示](https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA) - beforeCreate : 创建前 - created : 创建后 - beforeMount : 挂载前 - mounted : 挂载后 - beforeUpdate : 更新前 - updated : 更新后 - beforeDestroy : 销毁前 - destroyed : 销毁后 > 如果使用构造生成文件 ( 例如构造单文件组件 ),模板编译是提前执行的 ### Vue 语法和概念 #### 插值表达式(Mustache) ```html <p>Using mustaches: {{ rawHtml }}</p> ``` 如果包含 `html` 将会转换成字符串,如果你想输入正真的 `html` 您可以使用 `v-html` ```html <p>Using v-html directive: <span v-html="rawHtml"></span></p> ``` > 你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。 #### 指令(Directive) - v-text - v-html - v-show - v-if - v-else - v-else-if - v-for - [你可以在官网找到更多](https://cn.vuejs.org/v2/api/#%E6%8C%87%E4%BB%A4) #### 计算属性和侦听器 (computed & watch) - 计算属性 (computed) ```html <div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> ``` ```JavaScript var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } }) ``` - 侦听器 (watch) ```JavaScript watch: { a: function (val, oldVal) { console.log('new: %s, old: %s', val, oldVal) }, } ``` #### Class 和 Style 绑定 - Class 我们可以传给 v-bind:class 一个对象,以动态地切换 class: ```html <div v-bind:class="{ active: isActive }"></div> ``` - Style v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名 ```html <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> ``` ```JavaScript data: { styleObject: { color: 'red', fontSize: '13px' } } ``` #### 条件渲染/列表渲染 - v-if v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。 ```html <h1 v-if="awesome">Vue is awesome!</h1> <h1 v-else>Oh no ??</h1> ``` - v-show 另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样: ```html <h1 v-show="ok">Hello!</h1> ``` > v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 > v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。 > 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。 > 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。 - v-for 我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。 ```html <ul id="example-1"> <li v-for="item in items" :key="item.message">{{ item.message }}</li> </ul> ``` ```JavaScript var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) ``` #### 表单输入绑定 ```html <div id="example-4"> <input type="radio" id="one" value="One" v-model="picked" /> <label for="one">One</label> <br /> <input type="radio" id="two" value="Two" v-model="picked" /> <label for="two">Two</label> <br /> <span>Picked: {{ picked }}</span> </div> ``` ```JavaScript new Vue({ el: '#example-4', data: { picked: '' } }) ``` #### 组件 组件是 可复用的 Vue 示例 ```JavaScript // 定义一个名为 button-counter 的新组件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' }) ``` #### 插槽 可以通过 插槽 来分发内容 ```html <alert-box> Something bad happened. </alert-box> ``` ```JavaScript Vue.component('alert-box', { template: ` <div class="demo-alert-box"> <strong>Error!</strong> <slot></slot> </div> ` }) ``` #### 插件 插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种: - 添加全局方法或者 property。如:vue-custom-element - 添加全局资源:指令/过滤器/过渡等。如 vue-touch - 通过全局混入来添加一些组件选项。如 vue-router - 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。 - 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router #### 混入 mixin 如果多个组件有相同的选项,那么就可以使用 **混入** 的方式,把相同的选项进行合并,让代码合并,从而复用我们的代码 混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。 ```JavaScript // 定义一个混入对象 var myMixin = { created: function () { this.hello() }, methods: { hello: function () { console.log('hello from mixin!') } } } // 定义一个使用混入对象的组件 var Component = Vue.extend({ mixins: [myMixin] }) var component = new Component() // => "hello from mixin!" ``` #### 深入响应原理 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。 这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同,所以建议安装 vue-devtools 来获取对检查数据更加友好的用户界面。 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。 ```html <!DOCTYPE html> <html lang="cn"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>defineProperty</title> </head> <body> <div id="app">hello</div> <script> // 模拟 Vue 中的 data 选项 let data = { msg: "hello", }; // 模拟 Vue 的实例 let vm = {}; // 数据劫持:当访问或者设置 vm 中的成员的时候,做一些干预操作 Object.defineProperty(vm, "msg", { // 可枚举(可遍历) enumerable: true, // 可配置(可以使用 delete 删除,可以通过 defineProperty 重新定义) configurable: true, // 当获取值的时候执行 get() { console.log("get: ", data.msg); return data.msg; }, // 当设置值的时候执行 set(newValue) { console.log("set: ", newValue); if (newValue === data.msg) { return; } data.msg = newValue; // 数据更改,更新 DOM 的值 document.querySelector("#app").textContent = data.msg; }, }); // 测试 vm.msg = "Hello World"; console.log(vm.msg); </script> </body> </html> ``` [官方文档-深入响应原理](https://cn.vuejs.org/v2/guide/reactivity.html) #### 不同版本的 Vue [不同版本的 Vue](https://cn.vuejs.org/v2/guide/installation.html#%E5%AF%B9%E4%B8%8D%E5%90%8C%E6%9E%84%E5%BB%BA%E7%89%88%E6%9C%AC%E7%9A%84%E8%A7%A3%E9%87%8A) 为了适应不同的环境, Vue 提供了多个版本供我们使用 在 NPM 包的 dist/ 目录你将会找到很多不同的 Vue.js 构建版本。这里列出了它们之间的差别: | | UMD | CommonJS | ES Module (基于构建工具使用) | ES Module (直接用于浏览器) | | ------------------------- | -------------------- | --------------------- | ---------------------------- | -------------------------- | | 完整版 | vue.js | vue.common.js | vue.esm.js | vue.esm.browser.js | | 只包含运行时版 | vue.runtime.js | vue.runtime.common.js | vue.runtime.esm.js | - | | 完整版 (生产环境) | vue.min.js | - | - | vue.esm.browser.min.js | | 只包含运行时版 (生产环境) | vue.runtime.min.js - | - | - | - | ###### 术语 - 完整版:同时包含编译器和运行时的版本。 - 编译器:用来将模板字符串编译成为 JavaScript 渲染函数的代码。 - 运行时:用来创建 Vue 实例、渲染并处理虚拟 DOM 等的代码。基本上就是除去编译器的其它一切。 - UMD:UMD 版本可以通过 `<script>` 标签直接用在浏览器中。 `jsDelivr` CDN 的 `https://cdn.jsdelivr.net/npm/vue` 默认文件就是运行时 + 编译器的 UMD 版本 (vue.js)。 - CommonJS:CommonJS 版本用来配合老的打包工具比如 Browserify 或 webpack 1。这些打包工具的默认文件 (pkg.main) 是只包含运行时的 CommonJS 版本 (vue.runtime.common.js)。 - ES Module:从 2.6 开始 Vue 会提供两个 ES Modules (ESM) 构建文件: - 为打包工具提供的 ESM:为诸如 webpack 2 或 Rollup 提供的现代打包工具。ESM 格式被设计为可以被静态分析,所以打包工具可以利用这一点来进行“tree-shaking”并将用不到的代码排除出最终的包。为这些打包工具提供的默认文件 (pkg.module) 是只有运行时的 ES Module 构建 (vue.runtime.esm.js)。 - 为浏览器提供的 ESM (2.6+):用于在现代浏览器中通过 <script type="module"> 直接导入。