From b5cd524830bce0f68d322eb909f5399d2a23ae04 Mon Sep 17 00:00:00 2001
From: sdras Essentials
Components
Transitions & Animation
Note that objects and arrays in JavaScript are passed by reference, so if the prop is an array or object, mutating the object or array itself inside the child **will** affect parent state.
- -### Prop Validation - -It is possible for a component to specify requirements for the props it is receiving. If a requirement is not met, Vue will emit warnings. This is especially useful when you are authoring a component that is intended to be used by others. - -Instead of defining the props as an array of strings, you can use an object with validation requirements: - -``` js -Vue.component('example', { - props: { - // basic type check (`null` means accept any type) - propA: Number, - // multiple possible types - propB: [String, Number], - // a required string - propC: { - type: String, - required: true - }, - // a number with default value - propD: { - type: Number, - default: 100 - }, - // object/array defaults should be returned from a - // factory function - propE: { - type: Object, - default: function () { - return { message: 'hello' } - } - }, - // custom validator function - propF: { - validator: function (value) { - return value > 10 - } - } - } -}) -``` - -The `type` can be one of the following native constructors: - -- String -- Number -- Boolean -- Function -- Object -- Array -- Symbol - -In addition, `type` can also be a custom constructor function and the assertion will be made with an `instanceof` check. - -When prop validation fails, Vue will produce a console warning (if using the development build). Note that props are validated __before__ a component instance is created, so within `default` or `validator` functions, instance properties such as from `data`, `computed`, or `methods` will not be available. - -## Non-Prop Attributes - -A non-prop attribute is an attribute that is passed to a component, but does not have a corresponding prop defined. - -While explicitly defined props are preferred for passing information to a child component, authors of component libraries can't always foresee the contexts in which their components might be used. That's why components can accept arbitrary attributes, which are added to the component's root element. - -For example, imagine we're using a 3rd-party `bs-date-input` component with a Bootstrap plugin that requires a `data-3d-date-picker` attribute on the `input`. We can add this attribute to our component instance: - -``` html -Note that Vue's event system is different from the browser's [EventTarget API](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget). Though they work similarly, `$on` and `$emit` are __not__ aliases for `addEventListener` and `dispatchEvent`.
+ +In addition, a parent component can listen to the events emitted from a child component using `v-on` directly in the template where the child component is used. + +You cannot use `$on` to listen to events emitted by children. You must use `v-on` directly in the template, as in the example below.
+ +Here's an example: + +``` html +{{ total }}
+{{ total }}
+{{ msg }}
+{{ msg }}
+Note that you still have to declare the `checked` prop explicitly.
+ +## Non Parent-Child Communication + +Sometimes two components may need to communicate with one-another but they are not parent/child to each other. In simple scenarios, you can use an empty Vue instance as a central event bus: + +``` js +var bus = new Vue() +``` +``` js +// in component A's method +bus.$emit('id-selected', 1) +``` +``` js +// in component B's created hook +bus.$on('id-selected', function (id) { + // ... +}) +``` + +In more complex cases, you should consider employing a dedicated [state-management pattern](state-management.html). \ No newline at end of file diff --git a/src/v2/guide/props.md b/src/v2/guide/props.md new file mode 100644 index 0000000000..dd7f9b660e --- /dev/null +++ b/src/v2/guide/props.md @@ -0,0 +1,285 @@ +--- +title: Props +type: guide +order: 12 +--- + +## Passing Data with Props + +Every component instance has its own **isolated scope**. This means you cannot (and should not) directly reference parent data in a child component's template. Data can be passed down to child components using **props**. + +A prop is a custom attribute for passing information from parent components. A child component needs to explicitly declare the props it expects to receive using the [`props` option](../api/#props): + +``` js +Vue.component('child', { + // declare the props + props: ['message'], + // like data, the prop can be used inside templates and + // is also made available in the vm as this.message + template: '{{ message }}' +}) +``` + +Then we can pass a plain string to it like so: + +``` html +Note that objects and arrays in JavaScript are passed by reference, so if the prop is an array or object, mutating the object or array itself inside the child **will** affect parent state.
+ +## Prop Validation + +It is possible for a component to specify requirements for the props it is receiving. If a requirement is not met, Vue will emit warnings. This is especially useful when you are authoring a component that is intended to be used by others. + +Instead of defining the props as an array of strings, you can use an object with validation requirements: + +``` js +Vue.component('example', { + props: { + // basic type check (`null` means accept any type) + propA: Number, + // multiple possible types + propB: [String, Number], + // a required string + propC: { + type: String, + required: true + }, + // a number with default value + propD: { + type: Number, + default: 100 + }, + // object/array defaults should be returned from a + // factory function + propE: { + type: Object, + default: function () { + return { message: 'hello' } + } + }, + // custom validator function + propF: { + validator: function (value) { + return value > 10 + } + } + } +}) +``` + +The `type` can be one of the following native constructors: + +- String +- Number +- Boolean +- Function +- Object +- Array +- Symbol + +In addition, `type` can also be a custom constructor function and the assertion will be made with an `instanceof` check. + +When prop validation fails, Vue will produce a console warning (if using the development build). Note that props are validated __before__ a component instance is created, so within `default` or `validator` functions, instance properties such as from `data`, `computed`, or `methods` will not be available. + +## Non-Prop Attributes + +A non-prop attribute is an attribute that is passed to a component, but does not have a corresponding prop defined. + +While explicitly defined props are preferred for passing information to a child component, authors of component libraries can't always foresee the contexts in which their components might be used. That's why components can accept arbitrary attributes, which are added to the component's root element. + +For example, imagine we're using a 3rd-party `bs-date-input` component with a Bootstrap plugin that requires a `data-3d-date-picker` attribute on the `input`. We can add this attribute to our component instance: + +``` html +Note that Vue's event system is different from the browser's [EventTarget API](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget). Though they work similarly, `$on` and `$emit` are __not__ aliases for `addEventListener` and `dispatchEvent`.
- -In addition, a parent component can listen to the events emitted from a child component using `v-on` directly in the template where the child component is used. - -You cannot use `$on` to listen to events emitted by children. You must use `v-on` directly in the template, as in the example below.
- -Here's an example: - -``` html -{{ total }}
-{{ total }}
-{{ msg }}
-{{ msg }}
-Note that you still have to declare the `checked` prop explicitly.
- -### Non Parent-Child Communication - -Sometimes two components may need to communicate with one-another but they are not parent/child to each other. In simple scenarios, you can use an empty Vue instance as a central event bus: - -``` js -var bus = new Vue() -``` -``` js -// in component A's method -bus.$emit('id-selected', 1) -``` -``` js -// in component B's created hook -bus.$on('id-selected', function (id) { - // ... -}) -``` - -In more complex cases, you should consider employing a dedicated [state-management pattern](state-management.html). - -## Content Distribution with Slots - -When using components, it is often desired to compose them like this: - -``` html -This is some original content
-This is some more original content
-This is some original content
-This is some more original content
-A paragraph for the main content.
-And another one.
- -Here's some contact info
-A paragraph for the main content.
-And another one.
-This is some original content
+This is some more original content
+This is some original content
+This is some more original content
+A paragraph for the main content.
+And another one.
+ +Here's some contact info
+A paragraph for the main content.
+And another one.
+
-
Welcome home!
' -} - -var vm = new Vue({ - el: '#example', - data: { - currentView: Home - } -}) -``` - -### `keep-alive` - -If you want to keep the switched-out components in memory so that you can preserve their state or avoid re-rendering, you can wrap a dynamic component in a `Hello!
-`$refs` are only populated after the component has been rendered, and it is not reactive. It is only meant as an escape hatch for direct child manipulation - you should avoid using `$refs` in templates or computed properties.
- -### Async Components - -In large applications, we may need to divide the app into smaller chunks and only load a component from the server when it's actually needed. To make that easier, Vue allows you to define your component as a factory function that asynchronously resolves your component definition. Vue will only trigger the factory function when the component actually needs to be rendered and will cache the result for future re-renders. For example: - -``` js -Vue.component('async-example', function (resolve, reject) { - setTimeout(function () { - // Pass the component definition to the resolve callback - resolve({ - template: 'If you're a Browserify user that would like to use async components, its creator has unfortunately [made it clear](https://github.com/substack/node-browserify/issues/58#issuecomment-21978224) that async loading "is not something that Browserify will ever support." Officially, at least. The Browserify community has found [some workarounds](https://github.com/vuejs/vuejs.org/issues/620), which may be helpful for existing and complex applications. For all other scenarios, we recommend using Webpack for built-in, first-class async support.
- -### Advanced Async Components - -> New in 2.3.0+ - -Starting in 2.3.0+ the async component factory can also return an object of the following format: - -``` js -const AsyncComp = () => ({ - // The component to load. Should be a Promise - component: import('./MyComp.vue'), - // A component to use while the async component is loading - loading: LoadingComp, - // A component to use if the load fails - error: ErrorComp, - // Delay before showing the loading component. Default: 200ms. - delay: 200, - // The error component will be displayed if a timeout is - // provided and exceeded. Default: Infinity. - timeout: 3000 -}) -``` - -Note that when used as a route component in `vue-router`, these properties will be ignored because async components are resolved upfront before the route navigation happens. You also need to use `vue-router` 2.4.0+ if you wish to use the above syntax for route components. - -### Component Naming Conventions - -When registering components (or props), you can use kebab-case, camelCase, or PascalCase. - -``` js -// in a component definition -components: { - // register using kebab-case - 'kebab-cased-component': { /* ... */ }, - // register using camelCase - 'camelCasedComponent': { /* ... */ }, - // register using PascalCase - 'PascalCasedComponent': { /* ... */ } -} -``` - -Within HTML templates though, you have to use the kebab-case equivalents: - -``` html - -
- {{ folder.name }}
-
These are compiled as the component's own template.
-Not parent's transclusion content.
-Welcome home!
' +} + +var vm = new Vue({ + el: '#example', + data: { + currentView: Home + } +}) +``` + +### `keep-alive` + +If you want to keep the switched-out components in memory so that you can preserve their state or avoid re-rendering, you can wrap a dynamic component in a `If you're a Browserify user that would like to use async components, its creator has unfortunately [made it clear](https://github.com/substack/node-browserify/issues/58#issuecomment-21978224) that async loading "is not something that Browserify will ever support." Officially, at least. The Browserify community has found [some workarounds](https://github.com/vuejs/vuejs.org/issues/620), which may be helpful for existing and complex applications. For all other scenarios, we recommend using Webpack for built-in, first-class async support.
+ +## Advanced Async Components + +> New in 2.3.0+ + +Starting in 2.3.0+ the async component factory can also return an object of the following format: + +``` js +const AsyncComp = () => ({ + // The component to load. Should be a Promise + component: import('./MyComp.vue'), + // A component to use while the async component is loading + loading: LoadingComp, + // A component to use if the load fails + error: ErrorComp, + // Delay before showing the loading component. Default: 200ms. + delay: 200, + // The error component will be displayed if a timeout is + // provided and exceeded. Default: Infinity. + timeout: 3000 +}) +``` + +Note that when used as a route component in `vue-router`, these properties will be ignored because async components are resolved upfront before the route navigation happens. You also need to use `vue-router` 2.4.0+ if you wish to use the above syntax for route components. \ No newline at end of file diff --git a/src/v2/guide/miscellaneous-components.md b/src/v2/guide/miscellaneous-components.md new file mode 100644 index 0000000000..c220f15999 --- /dev/null +++ b/src/v2/guide/miscellaneous-components.md @@ -0,0 +1,226 @@ +--- +title: Miscellaneous Component Information +type: guide +order: 16 +--- + +## Authoring Reusable Components + +When authoring components, it's good to keep in mind whether you intend to reuse it somewhere else later. It's OK for one-off components to be tightly coupled, but reusable components should define a clean public interface and make no assumptions about the context it's used in. + +The API for a Vue component comes in three parts - props, events, and slots: + +- **Props** allow the external environment to pass data into the component + +- **Events** allow the component to trigger side effects in the external environment + +- **Slots** allow the external environment to compose the component with extra content. + +With the dedicated shorthand syntaxes for `v-bind` and `v-on`, the intents can be clearly and succinctly conveyed in the template: + +``` html +Hello!
+`$refs` are only populated after the component has been rendered, and it is not reactive. It is only meant as an escape hatch for direct child manipulation - you should avoid using `$refs` in templates or computed properties.
+ +## Component Naming Conventions + +When registering components (or props), you can use kebab-case, camelCase, or PascalCase. + +``` js +// in a component definition +components: { + // register using kebab-case + 'kebab-cased-component': { /* ... */ }, + // register using camelCase + 'camelCasedComponent': { /* ... */ }, + // register using PascalCase + 'PascalCasedComponent': { /* ... */ } +} +``` + +Within HTML templates though, you have to use the kebab-case equivalents: + +``` html + +
+ {{ folder.name }}
+
These are compiled as the component's own template.
+Not parent's transclusion content.
+