Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Vue] Upgrade version 2.x to 3.x #724

Merged
merged 11 commits into from
Jun 22, 2021
4 changes: 2 additions & 2 deletions docs/data/routes/docs/client-frameworks/vue/reference/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ The library provides helper components to help output Sitecore field values.

> The helper components that are exposed from `sitecore-jss-vue` are all stateless functional components with the exception of `Placeholder`, which is a typical stateful component.

> In accordance with Vue's [recommendations for functional components](https://vuejs.org/v2/guide/render-function.html#Passing-Attributes-and-Events-to-Child-Elements-Components), any non-prop attributes passed to the component will be rendered as html attributes on the enclosing tag. Events that are passed will be propagated as well.
> In accordance with Vue's [attribute inheritance](https://v3.vuejs.org/guide/component-attrs.html#attribute-inheritance), any non-prop attributes passed to the component will be rendered as html attributes on the enclosing tag. Events that are passed will be propagated as well.

> It is also important to note that _none_ of the helper components exposed from `sitecore-jss-vue` are registered globally, e.g. via `Vue.component()`. This is intentional so as not to pollute the global component space and also to align with the tree-shaking capabilities of bundling tools like Webpack or Rollup. Therefore you will need to locally require/import any of the helper components you wish to use in your own components.
> It is also important to note that _none_ of the helper components exposed from `sitecore-jss-vue` are registered globally, e.g. via `app.component()`. This is intentional so as not to pollute the global component space and also to align with the tree-shaking capabilities of bundling tools like Webpack or Rollup. Therefore you will need to locally require/import any of the helper components you wish to use in your own components.

Below is a list of all supported field helper components, and how they are used (where `field` is data coming from a placeholder component):

Expand Down
10 changes: 5 additions & 5 deletions docs/data/routes/docs/client-frameworks/vue/sample-app/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The Vue sample supports running in all [JSS application modes](/docs/fundamental

## Component Format

The JSS Vue sample primarily uses [Single-File Components (SFC)](https://vuejs.org/v2/guide/single-file-components.html) for presentational components. However, you are free to use whichever component declaration and registration method you choose, e.g. `render` functions, inline `template` properties, etc...
The JSS Vue sample primarily uses [Single-File Components (SFC)](https://v3.vuejs.org/guide/single-file-component.html#introduction) for presentational components. However, you are free to use whichever component declaration and registration method you choose, e.g. `render` functions, inline `template` properties, etc...

## Routing + State Management

Expand Down Expand Up @@ -90,9 +90,9 @@ The JSS [disconnected mode](/docs/fundamentals/application-modes) enables develo

Refer to the [JSS + GraphQL](/docs/fundamentals/services/graphql) documentation to understand the overall capabilities first - we're only talking about Vue and _Connected GraphQL_ specifically here. _Integrated_ GraphQL works at the server level, so it is identical in any supported frontend framework.

The Vue sample app makes use of the [vue-apollo](https://akryum.github.io/vue-apollo/) library which in turn integrates with the [Apollo GraphQL client](https://www.apollographql.com/client). Usage is fairly straightforward and you can follow the `vue-apollo` documentation for implementation specifics.
The Vue sample app makes use of the [@vue/apollo](https://v4.apollo.vuejs.org/) library which in turn integrates with the [Apollo GraphQL client](https://www.apollographql.com/client). Usage is fairly straightforward and you can follow the `@vue/apollo` documentation for implementation specifics.

> When server-side rendering (SSR), the sample app uses the `prefetch` functionality of `vue-apollo` to prefetch GraphQL query data and render the app to HTML on the server. This allows server-side rendering with the async results of GraphQL queries evaluated. If not using GraphQL, the `vue-apollo` prefetching functionality can be removed. It is _important_ to note that when `vue-apollo` is prefetching queries the queries do _not_ have access to instantiated components. This means no access to component props, state, or other instance properties. If queries need that type of data to populate query variables, the data will need to be extracted from the SSR state available via the `renderView` function.
> When server-side rendering (SSR), the sample app uses the `prefetch` functionality of `@vue/apollo` to prefetch GraphQL query data and render the app to HTML on the server. This allows server-side rendering with the async results of GraphQL queries evaluated. If not using GraphQL, the `@vue/apollo` prefetching functionality can be removed.

> Complete examples of using connected and integrated GraphQL are provided with the sample app and are heavily commented, for example `src/components/GraphQL-ConnectedDemo`. Please refer to these samples for implementation details.

Expand All @@ -116,12 +116,12 @@ export default {

Usage of `this.$jss` is dependent on installing the `SitecoreJssStorePlugin`:

_createApp.js_ (where your Vue instance is created, e.g. `new Vue()`)
_createApp.js_ (where your Vue instance is created, e.g. `createApp()/createSSRApp()`)

```javascript
import SitecoreJssStorePlugin from './lib/SitecoreJssStorePlugin';

Vue.use(SitecoreJssStorePlugin);
app.use(SitecoreJssStorePlugin);
```

The final piece of using `this.$jss.sitecoreContext()` and `this.$jss.routeData()` is to ensure that the `store` used by the `SitecoreJssStorePlugin` is updated when the Sitecore context/route data changes. This could be when the route changes in your app, or when server-side rendering passes down a state object - any time new layout data is pulled from Sitecore and rendered. To accomplish this, we use the `this.$jss.store.setSitecoreData()` function to update the JSS plugin store with data received from Layout Service. The `setSitecoreData` function accepts raw Layout Service data and updates the app-level context and route data accordingly. You can see an example of usage in `RouteHandler.js`. An abbreviated example is below:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jss start

We recommend reading the [sample app walkthrough](/docs/client-frameworks/vue/sample-app) to understand the sample app, but it's also well commented if you'd rather read code.

> The sample app was built using the [`@vue/cli` version 3](https://github.com/vuejs/vue-cli) as a starting point. However, the `sitecore-jss-vue` package has no dependencies on `@vue/cli`.
> The sample app was built using the [`@vue/cli` version 4](https://github.com/vuejs/vue-cli) as a starting point. However, the `sitecore-jss-vue` package has no dependencies on `@vue/cli`.

## Tools

Expand Down
26 changes: 14 additions & 12 deletions docs/data/routes/docs/client-frameworks/vue/vue-placeholders/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ Another technique allows you to get _an array of the Vue components in a placeho
All of the following examples assume you have installed the `SitecoreJssPlaceholderPlugin` on your Vue instance:

```
import Vue from 'vue';
import { createApp, createSSRApp } from 'vue';
import { SitecoreJssPlaceholderPlugin } from '@sitecore-jss/sitecore-jss-vue';
import componentFactory from './path/to/your/componentFactory.js';

const app = isSSR ? createSSRApp(vueOptions) : createApp(vueOptions);

// The plugin uses a "global" componentFactory, but you can override
// the `componentFactory` at the component level if needed.
Vue.use(SitecoreJssPlaceholderPlugin, { componentFactory });
app.use(SitecoreJssPlaceholderPlugin, { componentFactory });
```

### Basic Usage
Expand Down Expand Up @@ -88,7 +90,7 @@ export default {

### How It Works

The `SitecoreJssPlaceholderPlugin` uses a mixin that attaches to the `beforeCreate` hook to look for a `withPlaceholder` property on a component definition. The plugin then uses the value provided by the `withPlaceholder` property to find the specified placeholder data, e.g. `tabs` in the `rendering` prop data. The plugin then creates a computed property on the component, using the name of the placeholder as the property name by default, and assigns an array of all the Vue components for that placeholder to the computed property. This allows you to use the built-in Vue [dynamic component](https://vuejs.org/v2/guide/components.html#Dynamic-Components) to render the placeholder components in your template.
The `SitecoreJssPlaceholderPlugin` uses a mixin that attaches to the `beforeCreate` hook to look for a `withPlaceholder` property on a component definition. The plugin then uses the value provided by the `withPlaceholder` property to find the specified placeholder data, e.g. `tabs` in the `rendering` prop data. The plugin then creates a computed property on the component, using the name of the placeholder as the property name by default, and assigns an array of all the Vue components for that placeholder to the computed property. This allows you to use the built-in Vue [dynamic component](https://v3.vuejs.org/guide/component-basics.html#dynamic-components) to render the placeholder components in your template.

When you iterate the component array in your template, Vue will render the components where you emit them. The main advantage of this technique is that _there is no wrapper component_. If you use the `Placeholder` component, all child components render underneath it in the Vue component tree. If you emit the placeholder contents with this technique, the placeholder contents will have no wrapping component and will render inline. This is very useful when you're using Vue libraries that are based on a specific component hierarchy, for example this example of `vue-carousel`:

Expand Down Expand Up @@ -119,7 +121,7 @@ If the library doesn't mind a single layer of component wrapping, you can place
```
<template>
<carousel>
<component v-for="(slide, index) in slidesPlaceholder" :is="slide" :key="`slide${index}`" />
<component v-for="(slide, index) in $options.computed.slidesPlaceholder" :is="slide" :key="`slide${index}`" />
</carousel>
</template>

Expand Down Expand Up @@ -163,7 +165,7 @@ If you need a completely flat component hierarchy (`Carousel` -> `Slide` in our
```
<template>
<carousel>
<template v-for="(slide, index) in slidesPlaceholder">
<template v-for="(slide, index) in $options.computed.slidesPlaceholder">
<!-- this `v-if` is important, as it helps prevents breakage of the carousel markup when using Sitecore Experience Editor -->
<component v-if="slide.isxEditorComponent" :is="slide" />

Expand Down Expand Up @@ -194,16 +196,16 @@ export default {
</script>
```

## Scoped Slot API
## Slot API

If you like the [scoped slot pattern](https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots) instead of a dynamic computed prop, you'll be happy to know JSS placeholder a default scoped slot too! Using the `<Placeholder>` component's `default` scoped slot prop, you can take over rendering of the placeholder contents in the same way as with the dyanmic computed prop.
If you like the [slot pattern](https://v3.vuejs.org/guide/component-slots.html#slots) instead of a dynamic computed prop, you'll be happy to know JSS placeholder a default scoped slot too! Using the `<Placeholder>` component's `default` scoped slot prop, you can take over rendering of the placeholder contents in the same way as with the dyanmic computed prop.

The following example illustrates how to get the components array and render it using the default scoped slot.

```
<template>
<sc-placeholder :rendering="rendering" name="jss-main">
<div slot-scope="{components, isEmpty}">
<div v-slot="{components, isEmpty}">
<!--
The placeholder is considered "empty" if it contains no assigned presentation components.
However, if in Experience Editor (EE) mode, the placeholder may still contain EE-generated components.
Expand Down Expand Up @@ -295,7 +297,7 @@ export default {
},
computed: {
activeTab() {
return this.tabsPlaceholder && this.tabsPlaceholder[this.activeTabIndex];
return this.$options.computed.tabsPlaceholder && this.$options.computed.tabsPlaceholder[this.activeTabIndex];
},
},
}
Expand Down Expand Up @@ -341,10 +343,10 @@ export default{
<template>
<div>
<div class="col-1">
<component v-for="(comp, index) in phColumn1" :is="comp" :key="`comp${index}`" />
<component v-for="(comp, index) in this.$options.computed.phColumn1" :is="comp" :key="`comp${index}`" />
</div>
<div class="col-2">
<component v-for="(comp, index) in phColumn2" :is="comp" :key="`comp${index}`" />
<component v-for="(comp, index) in this.$options.computed.phColumn2" :is="comp" :key="`comp${index}`" />
</div>
</div>
</template>
Expand Down Expand Up @@ -375,7 +377,7 @@ export default {

## SitecoreJssPlaceholderPlugin API

As described earlier in The `SitecoreJssPlaceholderPlugin` uses a mixin that attaches to the `beforeCreate` hook to look for a `withPlaceholder` property on a component definition. The plugin then uses the value provided by the `withPlaceholder` property to find the specified placeholder data, e.g. `tabs` in the `rendering` prop data. The plugin then creates a computed property on the component, using the name of the placeholder as the property name by default, and assigns all of the Vue components for that placeholder to the computed property. This allows you to use the built-in Vue [dynamic component](https://vuejs.org/v2/guide/components.html#Dynamic-Components) to render the placeholder components in your template.
As described earlier in The `SitecoreJssPlaceholderPlugin` uses a mixin that attaches to the `beforeCreate` hook to look for a `withPlaceholder` property on a component definition. The plugin then uses the value provided by the `withPlaceholder` property to find the specified placeholder data, e.g. `tabs` in the `rendering` prop data. The plugin then creates a computed property on the component, using the name of the placeholder as the property name by default, and assigns all of the Vue components for that placeholder to the computed property. This allows you to use the built-in Vue [dynamic component](https://v3.vuejs.org/guide/component-basics.html#dynamic-components) to render the placeholder components in your template.

## Enhancing Placeholders

Expand Down
Loading