继续昨天分析源码
组件文件 src/components/shop-home.js
简单记录,对照shop-home.js
引入polymer 和 pwa 的相关,这个在node_modules 目录下import { html } from '@polymer/lit-element'; import { repeat } from 'lit-html/lib/repeat.js'; import { connect } from 'pwa-helpers/connect-mixin.js';
引入定制的基础视图组件,这个在src 目录下
import { PageViewElement } from './page-view-element.js'; import { shopButtonStyle } from './shop-button-style.js'; import './shop-image.js';
引入数据的js,这个在src 目录下
import { store } from '../store.js';
应用类定义
class ShopHome extends connect(store)(PageViewElement) {
渲染方法
_render({ _categories }) {
style 内容的引用
${shopButtonStyle}
主要内容,循环类别内容,内容来自于store.js
${repeat(Object.keys(_categories), key => { const category = _categories[key]; return html`<div class="item"> <a class="image-link" href="/list/${category.name}"> <shop-image src="${category.image}" alt="${category.title}" placeholder="${category.placeholder}"></shop-image> </a> <h2>${category.title}</h2> <shop-button> <a aria-label$="${category.title} Shop Now" href="/list/${category.name}">Shop Now</a> </shop-button> </div>`; })}
几个基础方法
static get properties() { return {
_stateChanged(state) {
应用类的实例化
customElements.define('shop-home', ShopHome);
下面将分析 数据来源 和 状态机的相关代码
首先我们回忆一下第一篇中分析过的 shop-app.js 文件中 的一个重要方法
_firstRendered() {
installRouter((location) => this._updateLocation(location));
}
_updateLocation(location) {
store.dispatch(updateLocation(location));
// Close the drawer - in case the *route* change came from a link in the drawer.
this._drawerOpened = false;
}
我们可以看到,页面第一次被渲染的时候,首先调用的就是_updateLocation(location), 参数location 就是url 地址,并从总调度store 调度方法 updateLocation(location) ,下面看看store.js 代码
- 核心调度文件 src/store.js
引入两个渲染文件
import app from './reducers/app.js';
import categories from './reducers/categories.js';
创建核心调度对象并注入渲染对象
export const store = createStore(
(state, action) => state,
compose(lazyReducerEnhancer(combineReducers), applyMiddleware(thunk))
);
store.addReducers({
app,
categories
});
我们直接往下跟踪 src/reducers/app.js
import {
UPDATE_LOCATION,
RECEIVE_LAZY_RESOURCES,
CLEAR_ANNOUNCER_LABEL,
SET_ANNOUNCER_LABEL,
CLOSE_MODAL,
UPDATE_NETWORK_STATUS,
CLOSE_SNACKBAR
} from '../actions/app.js';
跟踪 src/actions/app.js
export const updateLocation = (location) => async (dispatch, getState) => {
const path = window.decodeURIComponent(location.pathname);
const splitPath = (path || '').slice(1).split('/');
let page = splitPath[0];
switch (page) {
case '':
page = 'home';
dispatch(announceLabel(`Home, loaded`));
break;
我们可以看到调度是以截取url 的 目录作为page变量,然是根据page来做不同的处理,也就是页面跳转然后做调度
switch (page) {
case '':
page = 'home';
dispatch(announceLabel(`Home, loaded`));
break;
case 'cart':
await import('../components/shop-cart.js');
dispatch(announceLabel(`Cart, loaded`));
break;
case 'checkout':
await import('../components/shop-checkout.js');
dispatch(announceLabel(`Checkout, loaded`));
break;
case 'list':
categoryName = splitPath[1];
await import('../components/shop-list.js');
break;
case 'detail':
categoryName = splitPath[1];
itemName = splitPath[2];
await import('../components/shop-detail.js');
break;
default:
page = '404';
dispatch(announceLabel(`Page not found`));
}
我们从上面的调度可以看到,总是根据url路径来做相关调度和数据处理以及引入相关的视图
大致是从 components -> store.js -> reducers/app.js -> actions/app.js
今天就到这里,休息休息,明天我会继续分析相关代码