Object.freeze(),这会阻止修改现有的 property,也意味着响应系统无法再追踪变化。
1. export
用于规定模块的对外接口,export输出变量和方法、类
变量
1
2
3
4
5
6
7// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
//简写--优先使用
export {firstName, lastName, year}方法
1
2
3//如果想为输入的变量重新命名, 可以使用AS 关键字重新命名
import { buildMenus as buildMenus} from '@/api/menu';
//import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同
2. export default
为模块指定默认输出, 使用import命令的时候,用户需要知道所要加载的变量名和函数名,否则无法加载;了解模块有哪些方法和属性比较麻烦,使用export default命令,为模块指定默认输出
1 | // export-default.js |
上面代码是一个模块文件export-default.js。默认输出1个函数;
与export命令的区别:其他模块加载该模块是,import命令可以为该匿名函数指定任意名字
1 | // import-default.js |
上面代码的import
命令,可以用任意名称指向export-default.js
输出的方法,这时就不需要知道原模块输出的函数名。需要注意的是,这时import
命令后面,不使用大括号。
本质上,export default
就是输出一个叫做default
的变量或方法,然后系统允许你为它取任意名字。所以,下面的写法是有效的。
1 | // modules.js |
正是因为export default
命令其实只是输出一个叫做default
的变量,所以它后面不能跟变量声明语句。
总结:
export命令对外接口是有名称的且
import
命令从模块导入的变量名与被导入模块对外接口的名称相同,而export default命令对外输出的变量名可以是任意的,这时import
命令后面,不使用大括号。export default
命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此export default
命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能唯一对应export default
命令。
1 | //menu.js |
3. Const、var、let
ES5 中作用域有:全局作用域、函数作用域。没有块作用域的概念。
ES6 中新增了块级作用域。块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域
1 | { |
三者的区别:
- var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
- let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
- const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。
1 | // 块作用域 |
注意:const定义的对象属性是否可以改变
1 | const person = { |
因为对象是引用类型的,person中保存的仅是对象的指针,这就意味着,const仅保证指针不发生改变,修改对象的属性不会改变对象的指针,所以是被允许的。也就是说const定义的引用类型只要指针不发生改变,其他的不论如何改变都是允许的。
然后我们试着修改一下指针,让person指向一个新对象,果然报错
1 | const person = { |
4. promise
promise用途:异步编程的一种解决方案。
优点:比传统的解决方案——回调函数和事件——更合理和更强大。
三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。
1 | //基本用法: |
5. 生命周期
6. 模版语法
v-once
执行一次性插值,当数据变化的时候,该内容不会更新;可能会影响该节点其他的数据绑定
1 | <span v-once>这个将不会改变: {{ msg }}</span> |
v-html
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用v-html;
1 | var rawHtml = "<span>这是个使用v-htmls</span>" |
Attribute
Mustache ({}) 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind
指令:
1 | <div v-bind:id="dynamicId"></div> |
三元表达式
1 | {{ number + 1 }} |
7. 指令Directives
指令 (Directives) 是带有 v-
前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for
是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
1 | //v-if 指令将根据表达式 seen 的值的真假来插入/移除 <p> 元素。 |
参数
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind
指令可以用于响应式地更新 HTML attribute
1 | //href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定 |
动态参数
2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数
1 | <a v-bind:[attributeName] = "url"></a> |
绑定处理函数:
1 | <a v-on:[eventName]="dosomething"></a> |
对动态参数的值的约束
动态参数预期会求出一个字符串,异常情况下值为
null
。这个特殊的null
值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。对动态参数表达式的约束
动态参数表达式有一些语法约束,因为某些字符,如空格和引号,放在 HTML attribute 名里是无效的。例如:
修饰符
修饰符(modifier)是以半角句号.
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定;例如 .prevent
修饰符告诉v-on指令对触发的事件调用event.preventDefault();
1 | <form v-on:submit.prevent = "onSubmit"> |
缩写
1 | <!-- 完整语法 --> |
:
与 @
对于 attribute 名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析。而且,它们不会出现在最终渲染的标记中。
8. 计算属性
1 | <div id="example"> |
这里是想要显示变量 message
的翻转字符串。当你想要在模板中的多处包含此翻转字符串时,就会更加难以处理。
所以,对于任何复杂逻辑,你都应当使用计算属性
例如:
1 | <div id="example"> |
1 | var vm = new Vue({ |
声明了一个计算属性reversedMessage
;我们提供的函数将用作property vm.reversedMessage
的getter函数
1 | console.log(vm.reversedMessage) // olleH |
你可以打开浏览器的控制台,自行修改例子中的 vm。vm.reversedMessage
的值始终取决于 vm.message
的值。
你可以像绑定普通 property 一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage
依赖于 vm.message
,因此当 vm.message
发生改变时,所有依赖 vm.reversedMessage
的绑定也会更新。以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的。
计算属性 VS 方法
使用表达式中调用方法同样可以达到上面的结果
1 | <p>Reversed message: "{{ reversedMessage() }}"</p> |
1 | // 在组件中 |
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message
还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。
这也同样意味着下面的计算属性将不再更新,因为 Date.now()
不是响应式依赖:
1 | computed: { |
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。
计算属性 VS 侦听属性
侦听属性:vue提供了一种更通用的方式来观察和响应vue实例上的数据变动;当有一些数据需要随着其他数据变动而变动时;很容易滥用watch;通常更好的做法是使用计算属性而不是命令式的watch回调;
1 | <div id="demo">{{ fullName }}</div> |
1 | var vm = new Vue({ |
计算属性的setter
计算属性默认只有getter,自己可以提供一个setter
1 | computed: { |
现在再运行 vm.fullName = 'John Doe'
时,setter 会被调用,vm.firstName
和 vm.lastName
也会相应地被更新。
9. 侦听器
当需要在数据变化时执行异步或开销较大的操作时,watch是最有用的;同时也可以自定义侦听器;
1 | <div id="watch-example"> |
1 | <!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 --> |
使用 watch
选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的
10. class与style绑定
将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组
10.1 绑定html class
10.1.1对象语法
方式一:内联
1 | <div |
方式二:绑定的数据对象不必内联定义在模板里
1 | <div v-bind:class="classObject"></div> |
方式三:绑定一个返回对象的计算属性(常用)
1 | <div v-bind:class="classObject"></div> |