From c3fd89f1dadd2f096b5359f0b74f458e618a7315 Mon Sep 17 00:00:00 2001 From: Jinjiang Date: Mon, 9 Apr 2018 02:22:54 +0800 Subject: [PATCH 1/2] translated components-props.md --- src/v2/guide/components-props.md | 314 +++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 src/v2/guide/components-props.md diff --git a/src/v2/guide/components-props.md b/src/v2/guide/components-props.md new file mode 100644 index 000000000..452d15103 --- /dev/null +++ b/src/v2/guide/components-props.md @@ -0,0 +1,314 @@ +--- +title: Prop +type: guide +order: 102 +--- + +> 该页面假设你已经阅读过了[组件基础](components.html)。如果你还对组件不太了解,推荐你先阅读它。 + +## Prop 的大小写 (camelCase vs kebab-case) + +HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名: + +``` js +Vue.component('blog-post', { + // 在 JavaScript 中是 camelCase 的 + props: ['postTitle'], + template: '

{{ postTitle }}

' +}) +``` + +``` html + + +``` + +重申一次,如果你使用字符串模板,那么这个限制就不存在了。 + +## 静态的和动态的 Prop + +现在,你已经知道了可以想这样给 prop 传入一个静态的值: + +```html + +``` + +你也知道 prop 可以通过 `v-bind` 动态赋值,例如: + +```html + +``` + +在上述两个示例中,我们传入的值都是字符串类型的,但实际上_任何_类型的值都可以传给一个 prop。 + +### 传入一个数字 + +```html + + + + + + +``` + +### 传入一个布尔值 + +```html + + + + + + + + + +``` + +### 传入一个数组 + +```html + + + + + + +``` + +### 传入一个对象 + +```html + + + + + + +``` + +### 传入一个对象的所有属性 + +如果你想要讲一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 `v-bind` (取代 `v-bind:prop-name`)。例如,对于一个给定的对象 `post`: + +``` js +post: { + id: 1, + title: 'My Journey with Vue' +} +``` + +下面的模板: + +``` html + +``` + +等价于: + +``` html + +``` + +## 单向数据流 + +所有的 prop 都使得其父子 prop 之间形成了一个**单向下行绑定**:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。 + +额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你**不**应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在命令行中发出警告。 + +这里有两种常见的试图改变一个 prop 的情形: + +1. **这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。**在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值: + + ``` js + props: ['initialCounter'], + data: function () { + return { + counter: this.initialCounter + } + } + ``` + +2. **这个 prop 以一种原始的值传入且需要做二次加工。**在这种情况下,最好使用这个 prop 的值来定义一个计算属性: + + ``` js + props: ['size'], + computed: { + normalizedSize: function () { + return this.size.trim().toLowerCase() + } + } + ``` + +

注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身**将会**影响到父组件的状态。

+ +## Prop 验证 + +我们可以为组件的 prop 定制需求。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这尤其在开发一个会被别人用到的组件的时候非常有帮助。 + +To specify prop validations, you can provide an object with validation requirements to the value of `props`, instead of an array of strings. For example: +为了定制 prop 的验证方式,你可以为 `props` 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如: + +``` js +Vue.component('my-component', { + props: { + // 基础的类型检查 (`null` 匹配任何类型) + propA: Number, + // 多个可能的类型 + propB: [String, Number], + // 必填的字符串 + propC: { + type: String, + required: true + }, + // 带有默认值的数字 + propD: { + type: Number, + default: 100 + }, + // 带有默认值的对象 + propE: { + type: Object, + // 对象或数组且一定会从一个工厂函数返回默认值 + default: function () { + return { message: 'hello' } + } + }, + // 自定义验证函数 + propF: { + validator: function (value) { + // 这个值必须匹配下列字符串中的一个 + return ['success', 'warning', 'danger'].indexOf(value) !== -1 + } + } + } +}) +``` + +当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个命令后的警告。 + +

注意那些 prop 会在一个组件实例被创建**之前**进行验证,所以实例的属性 (如 `data`、`computed` 等) 在 `default` 或 `validator` 函数中是不可用的。

+ +### 类型检查 + +`type` 可以是下列原生构造函数中的一个: + +- `String` +- `Number` +- `Boolean` +- `Function` +- `Object` +- `Array` +- `Symbol` + +额外的,`type` 还可以是一个自定义的构造函数,并且其验证方式内部是通过 `instanceof` 来断言的。例如,给定下列现成的构造函数: + +```js +function Person (firstName, lastName) { + this.firstName = firstName + this.lastName = lastName +} +``` + +你可以使用: + +```js +Vue.component('blog-post', { + props: { + author: Person + } +}) +``` + +来验证 `author` prop 的值是否是通过 `new Person` 创建的。 + +## 非 Prop 的特性 + +一个非 prop 特性是指传向一个组件,但是该组件并没有相应 prop 定义的特性。 + +因为显性定义的 prop 适用于向一个子组件传入信息,组件库的作者无法永远预见到组件使用时的上下文。这也是为什么组件可以接受任意的特性,而这些特性会被添加到这个组件的根元素上。 + +例如,想象一下你通过一个 Bootstrap 插件使用了一个第三方的 `` 组件,这个插件需要在其 `` 上用到一个 `data-date-picker` 特性。我们可以将这个特性添加到你的组件实例上: + +``` html + +``` + +然后这个 `data-date-picker="activated"` 特性就会自动添加到 `` 的根元素上。 + +### 替换/合并已有的特性 + +想象一下 `` 的模板是这样的: + +``` html + +``` + +为了给我们的日期选择器插件定制一个主题,我们可能需要像这样添加一个特别的 class: + +``` html + +``` + +在这种情况下,我们定义了两个不同的 `class` 的值: + +- `form-control`,这是在组件的模板内设置好的 +- `date-picker-theme-dark`,这是从组件的父级传入的 + +对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 `type="text"` 就会替换掉 `type="date"` 并把它破坏!庆幸的是,`class` 和 `style` 特性会稍微智能一些,即两边的值会被合并起来,从而得到最终的值:`form-control date-picker-theme-dark`。 + +### 禁用特性继承 + +如果你**不**希望组件的根元素继承特性,你可以设置在组件的选项中设置 `inheritAttrs: false`。例如: + +```js +Vue.component('my-component', { + inheritAttrs: false, + // ... +}) +``` + +尤其是它可以和实例的 `$attrs` 属性结合使用,该属性包含了传递给一个组件的特性名和特性值,例如: + +```js +{ + class: 'username-input', + placeholder: 'Enter your username' +} +``` + +有了 `inheritAttrs: false` 和 `$attrs`,你就可以手动决定这些特性会被赋予哪个元素。在撰写[基础组件](../style-guide/#基础组件名-强烈推荐)的时候是常会用到的: + +```js +Vue.component('base-input', { + inheritAttrs: false, + props: ['label', 'value'], + template: ` + + ` +}) +``` + +这个模式运行你在使用基础组件的时候更像是使用原始的 HTML 元素,而不会担心哪个元素是真正的根元素: + +```html + +``` From 3dcedf242920d7fefa20eedebbfdab3d420a5169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8B=BE=E4=B8=89=E8=82=A1=E5=9B=9B?= Date: Thu, 26 Apr 2018 19:16:16 +0800 Subject: [PATCH 2/2] Update components-props.md --- src/v2/guide/components-props.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/v2/guide/components-props.md b/src/v2/guide/components-props.md index 452d15103..f755da624 100644 --- a/src/v2/guide/components-props.md +++ b/src/v2/guide/components-props.md @@ -27,7 +27,7 @@ Vue.component('blog-post', { ## 静态的和动态的 Prop -现在,你已经知道了可以想这样给 prop 传入一个静态的值: +像这样,你已经知道了可以想这样给 prop 传入一个静态的值: ```html @@ -55,7 +55,7 @@ Vue.component('blog-post', { ### 传入一个布尔值 ```html - + @@ -90,7 +90,7 @@ Vue.component('blog-post', { ### 传入一个对象的所有属性 -如果你想要讲一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 `v-bind` (取代 `v-bind:prop-name`)。例如,对于一个给定的对象 `post`: +如果你想要将一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 `v-bind` (取代 `v-bind:prop-name`)。例如,对于一个给定的对象 `post`: ``` js post: { @@ -118,7 +118,7 @@ post: { 所有的 prop 都使得其父子 prop 之间形成了一个**单向下行绑定**:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。 -额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你**不**应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在命令行中发出警告。 +额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你**不**应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。 这里有两种常见的试图改变一个 prop 的情形: @@ -133,7 +133,7 @@ post: { } ``` -2. **这个 prop 以一种原始的值传入且需要做二次加工。**在这种情况下,最好使用这个 prop 的值来定义一个计算属性: +2. **这个 prop 以一种原始的值传入且需要进行转换。**在这种情况下,最好使用这个 prop 的值来定义一个计算属性: ``` js props: ['size'], @@ -148,9 +148,8 @@ post: { ## Prop 验证 -我们可以为组件的 prop 定制需求。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这尤其在开发一个会被别人用到的组件的时候非常有帮助。 +我们可以为组件的 prop 指定需求。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。 -To specify prop validations, you can provide an object with validation requirements to the value of `props`, instead of an array of strings. For example: 为了定制 prop 的验证方式,你可以为 `props` 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如: ``` js @@ -189,9 +188,9 @@ Vue.component('my-component', { }) ``` -当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个命令后的警告。 +当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。 -

注意那些 prop 会在一个组件实例被创建**之前**进行验证,所以实例的属性 (如 `data`、`computed` 等) 在 `default` 或 `validator` 函数中是不可用的。

+

注意那些 prop 会在一个组件实例创建**之前**进行验证,所以实例的属性 (如 `data`、`computed` 等) 在 `default` 或 `validator` 函数中是不可用的。

### 类型检查 @@ -205,7 +204,7 @@ Vue.component('my-component', { - `Array` - `Symbol` -额外的,`type` 还可以是一个自定义的构造函数,并且其验证方式内部是通过 `instanceof` 来断言的。例如,给定下列现成的构造函数: +额外的,`type` 还可以是一个自定义的构造函数,并且通过 `instanceof` 来进行检查确认。例如,给定下列现成的构造函数: ```js function Person (firstName, lastName) { @@ -230,7 +229,7 @@ Vue.component('blog-post', { 一个非 prop 特性是指传向一个组件,但是该组件并没有相应 prop 定义的特性。 -因为显性定义的 prop 适用于向一个子组件传入信息,组件库的作者无法永远预见到组件使用时的上下文。这也是为什么组件可以接受任意的特性,而这些特性会被添加到这个组件的根元素上。 +因为显式定义的 prop 适用于向一个子组件传入信息,然而组件库的作者并不总能预见组件会被用于怎样的场景。这也是为什么组件可以接受任意的特性,而这些特性会被添加到这个组件的根元素上。 例如,想象一下你通过一个 Bootstrap 插件使用了一个第三方的 `` 组件,这个插件需要在其 `` 上用到一个 `data-date-picker` 特性。我们可以将这个特性添加到你的组件实例上: @@ -248,7 +247,7 @@ Vue.component('blog-post', { ``` -为了给我们的日期选择器插件定制一个主题,我们可能需要像这样添加一个特别的 class: +为了给我们的日期选择器插件定制一个主题,我们可能需要像这样添加一个特别的类名: ``` html