diff --git a/docs/front-end/04-ES6/17-promise.md b/docs/front-end/04-ES6/17-promise.md index 9ece7413..27e190d1 100644 --- a/docs/front-end/04-ES6/17-promise.md +++ b/docs/front-end/04-ES6/17-promise.md @@ -529,6 +529,18 @@ const user = { } ``` +在script标签中 type属性值为 `model`时也相当于定义了一个async函数, + +```html + +``` + + + ### ② async 函数的返回值 async 函数返回一个 Promise 对象, Promise 对象的状态取决于 async 函数内的 return, 规则如下: diff --git "a/docs/front-end/09-vue/01-vue\345\205\245\351\227\250.md" "b/docs/front-end/09-vue/01-vue\345\205\245\351\227\250.md" index ffe21440..60adf5d1 100644 --- "a/docs/front-end/09-vue/01-vue\345\205\245\351\227\250.md" +++ "b/docs/front-end/09-vue/01-vue\345\205\245\351\227\250.md" @@ -120,6 +120,16 @@ var app = new Vue({ ## 数据和方法 +## 术语 + +```javascript +实例或组件中的 data,methods,template,components,computer 这类属性名 称为 property + +实例或组件中的 data中的数据,methods中的方法名,template,components中的组件名,computer方法名 这类属性名 称为 attribute +``` + + + ### 数据data ```javascript diff --git "a/docs/front-end/09-vue/02-\346\214\207\344\273\244.md" "b/docs/front-end/09-vue/02-\346\214\207\344\273\244.md" index 755adb5f..2a13a82d 100644 --- "a/docs/front-end/09-vue/02-\346\214\207\344\273\244.md" +++ "b/docs/front-end/09-vue/02-\346\214\207\344\273\244.md" @@ -236,6 +236,11 @@ v-show为true表示显示元素,false表示隐藏元素(通过display:none - `.prop` - 强制绑定为 DOM property。3.2+ - `.attr` - 强制绑定为 DOM attribute。3.2+ +```javascript +当用于组件 props 绑定时,所绑定的 props 必须在子组件中已被正确声明。 +当不带参数使用时,可以用于绑定一个包含了多个 attribute 名称-绑定值对的对象。 +``` + **示例代码** ```html @@ -311,14 +316,40 @@ div v-bind:style="[baseStyles, overridingStyles]"> ```javascript 语句:如果操作语句比较简单,建议直接写语句 函数:如果操作比较复杂或要在多个不同的地方调用且不需要传递参数使用函数 -内联声明:如果操作比较复杂或要在多个不同的地方调用且需要传递参数使用调用函数 -如果要传递事件对象可以通过$event全局对象 +内联声明:如果操作比较复杂或要在多个不同的地方调用且需要传递参数使用函数() +如果要传递事件对象可以通过 $event全局对象 v-on可以简写:@ +//api中的描述 事件类型由参数来指定。表达式可以是一个方法名,一个内联声明,如果有修饰符则可省略。 -当用于普通元素,只监听原生 DOM 事件。当用于自定义元素组件,则监听子组件触发的自定义事件。 -当监听原生 DOM 事件时,方法接收原生事件作为唯一参数。如果使用内联声明,声明可以访问一个特殊的 $event 变量:v-on:click="handle('ok', $event)"。 -v-on 还支持绑定不带参数的事件/监听器对的对象。请注意,当使用对象语法时,不支持任何修饰符。 +当用于普通元素,只监听原生 DOM 事件。 +当用于自定义元素组件,则监听子组件触发的自定义事件。 +当监听原生 DOM 事件时,方法接收原生事件作为唯一参数。 +如果使用内联声明,声明可以访问一个特殊的 $event 变量 +v-on:click="handle('ok', $event)" +v-on 还支持绑定不带参数的事件/监听器对象。 +请注意,当使用对象语法时,不支持任何修饰符。 +``` + +有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 `$event` 把它传入方法 + +```javascript + +``` + +```javascript +// ... +methods: { + warn: function (message, event) { + // 现在我们可以访问原生事件对象 + if (event) { + event.preventDefault() + } + alert(message) + } +} ``` ```javascript @@ -332,6 +363,8 @@ v-on 还支持绑定不带参数的事件/监听器对的对象。请注意, ``` + + ### 事件修饰符 - `.stop` - 调用 `event.stopPropagation()`。 diff --git "a/docs/front-end/09-vue/05-\344\272\213\344\273\266.md" "b/docs/front-end/09-vue/05-\344\272\213\344\273\266.md" new file mode 100644 index 00000000..3539ee85 --- /dev/null +++ "b/docs/front-end/09-vue/05-\344\272\213\344\273\266.md" @@ -0,0 +1,811 @@ +# 自定义事件 + +## 事件名 + +不同于组件和 prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。举个例子,如果触发一个 camelCase 名字的事件: + +```javascript +JS中 +this.$emit('myEvent') +``` + +则监听这个名字的 kebab-case 版本是不会有任何效果的: + +```html + + +``` + +不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 `v-on` 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 `v-on:myEvent` 将会变成 `v-on:myevent`——导致 `myEvent` 不可能被监听到。 + +`因此,我们推荐你始终使用 kebab-case 的事件名。事件名必须用短横线命名方式` + +## 通过监听事件实现通讯 + +在父组件中使用 on(zidingyi-eventName)监听事件,然后在子组件中使用on(yuansheng-eventName)监听事件,然后在子组件中使用emit(eventName) 触发事件,这样就能实现子组件向父组件传值。 + +```javascript +Vue.component('button-counter', { + template: '', + data: function () { + return { + counter: 0 + } + }, + methods: { + incrementCounter: function () { + this.counter += 1 + this.$emit('increment') + } + }, +}) + +new Vue({ + el: '#counter-event-example', + data: { + total: 0 + }, + methods: { + incrementTotal: function () { + this.total += 1 + console.log('第'+this.total+'次点击') + } + } +}) +
+

{{ total }}

+ + +
+``` + +## 使用事件抛出一个值 + +有的时候用一个事件来抛出一个特定的值是非常有用的。这时可以使用 `$emit` 的第二个参数来提供这个值 + +```javascript + incrementCounter: function () { + this.counter += 1 + this.$emit('increment', this.counter) + } +``` + +然后当在父级组件监听这个事件的时候,我们可以通过 `$event` 访问到被抛出的这个值 + +```html + +``` + +或者,如果这个事件处理函数是一个方法:那么这个值将会作为第一个参数传入这个方法: + +```vue + + +methods: { + incrementTotal: function (enlargeAmount) { + this.postFontSize += enlargeAmount + } +} +``` + +## 组件上使用v-bind + +在组件上使用v-bind,参数是子组件上的父组件传来的prop,(prop中的对象或数组是引用的形式),表达式是父组件上的methods中方法。相当于是借用父组件中的函数,子组件触发事件,调用父组件的函数。 + +父组件向子组件传入一个函数incrementTotal,子组件设置原生事件click,然后子组件监听click事件,表达式(回调函数)是父组件传来的incrementTotal + +```javascript +Vue.component('button-counter', { + props:['incrementTotal'], + template: '', +}) +``` + +Vue实例(父组件)方法 incrementTotal 默认接收一个参数event,event指向子组件触发事件的对象。 + +相当于原生JavaScript事件回调函数中的event + +```javascript +box.addEventListener('contextmenu', function(event) { + console.log('contextmenu', event); +}); +``` + +```javascript +// 定义Vue实例 +new Vue({ + el: '#counter-event-example', + data: { + total: 0 + }, + methods: { + incrementTotal: function (e) { + console.log(e) // PointerEvent{} + } + } +}) +``` + +```javascript +
+
+
+``` + +子向父传值,通过传递函数 + +```html + + +
+ +
+ + +``` + +```javascript + +``` + + + +## 组件上使用v-model + +组件内input需要满足条件: + +- 将其 `value` 特性绑定到一个名叫 `value` 的 prop 上 +- 在其 `input` 事件被触发时,将新的值通过自定义的 `input` 事件抛出 + +```javascript +Vue.component('custom-input', { + props: ['value'], + template: ` + + ` +}) +``` + +`v-model` 在组件上的使用 + +```html + + + + +``` + +一个组件上的 `v-model` 默认会利用名为 `value` 的 prop 和名为 `input` 的事件,但是像单选框、复选框等类型的输入控件可能会将 `value` attribute 用于[不同的目的](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Value)。`model` 选项可以用来避免这样的冲突: + +```javascript +Vue.component('base-checkbox', { + model: { + prop: 'checked', + event: 'change' + }, + props: { + checked: Boolean + }, + template: ` + + ` +}) +``` + +现在在这个组件上使用 `v-model` 的时候: + +```javascript + +``` + +这里的 `lovingVue` 的值将会传入这个名为 `checked` 的 prop。同时当 `` 触发一个 `change` 事件并附带一个新的值的时候,这个 `lovingVue` 的 property 将会被更新。 + +> 注意你仍然需要在组件的 `props` 选项里声明 `checked` 这个 prop。 + +## 子向父传值 + +1. 通过父向子传递函数,子组件调用函数改变父的数据 + +子组件在回调函数中如果不传参数,默认传递一个event对象。 + +```javascript +Vue.component('reine',{ + props:['num','changeNum'], + // 父向子传递函数 子组件调用函数改变父数据 + template:` +
+ +
+ `, +}) +``` + +```javascript +// 定义Vue实例 +new Vue({ + el:"#app", + data:{ + num:1, + }, + methods:{ + changeNum(num){ + this.num += num; + }, + }, +}) +``` + +```html +
父向子传递函数 子组件调用函数改变父数据
+ +``` + +2. 子组件设置自定义事件改变父数据 + +```javascript +Vue.component('hanser',{ + // 子组件设置自定义事件改变父数据 + props:['num'], + template:` +
+ +
+ `, + methods:{ + func(){ + // 设置自定义事件 + this.$emit('hanser-event',20); + }, + } +}) +``` + +```javascript +// 定义Vue实例 +new Vue({ + el:"#app", + data:{ + num:1, + }, + methods:{ + changeNum(num){ + this.num += num; + }, + }, +}) +``` + +```javascript +
子组件设置自定义事件改变父数据
+ +``` + +## 修饰符 + +### .native修饰符 + +你可能有很多次想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 `v-on` 的 `.native` 修饰符: + +```javascript + +``` + +在有的时候这是很有用的,不过在你尝试监听一个类似 `` 的非常特定的元素时,这并不是个好主意。比如上述 `` 组件可能做了如下重构,所以根元素实际上是一个 `