YII2到底是如何加载前端资源的呢 简单的分析下框架的内部实现过程,便于举一反三。
个人认为好多复杂的东西其实都很简单 把大象放进冰箱只需要三步即可
这里也是分了三步
AppAsset::register($this); // view -> assetBundles
BowerAsset::register($this);
这一步的作用主要是 把AppAset 这类对象注入到 View类的 assetBundles 中进行保存,
方便后续的调用
public function registerAssetBundle($name, $position = null)
{
if (!isset($this->assetBundles[$name])) {
$am = $this->getAssetManager();
$bundle = $am->getBundle($name);
$this->assetBundles[$name] = false;
// register dependencies
$pos = isset($bundle->jsOptions['position']) ? $bundle->jsOptions['position'] : null;
foreach ($bundle->depends as $dep) {
$this->registerAssetBundle($dep, $pos);
}
$this->assetBundles[$name] = $bundle; // 此处进行注入
} elseif ($this->assetBundles[$name] === false) {
throw new InvalidConfigException("A circular dependency is detected for bundle '$name'.");
} else {
$bundle = $this->assetBundles[$name];
}
if ($position !== null) {
$pos = isset($bundle->jsOptions['position']) ? $bundle->jsOptions['position'] : null;
if ($pos === null) {
$bundle->jsOptions['position'] = $pos = $position;
} elseif ($pos > $position) {
throw new InvalidConfigException("An asset bundle that depends on '$name' has a higher javascript file position configured than '$name'.");
}
// update position for all dependencies
foreach ($bundle->depends as $dep) {
$this->registerAssetBundle($dep, $pos);
}
}
return $bundle;
}
另外
$this->registerJs( // view -> js
'Config = {emojiBaseUrl: "' . $emojify->baseUrl . '"};',
\yii\web\View::POS_HEAD
);
这里其实就是把 你自己的js代码 注入到 View类的 js变量中。 跟上面的模式是一样的
<?php $this->head() ?>
<?php $this->endBody() ?>
第二步主要是进行标记钩子 方便我后面对此处进行进一步处理 进行替换
public function head()
{
echo self::PH_HEAD;
}
public function endBody()
{
$this->trigger(self::EVENT_END_BODY);
echo self::PH_BODY_END; // 做上标记
foreach (array_keys($this->assetBundles) as $bundle) {
// kartik\icons\FontAwesomeAsset
$this->registerAssetFiles($bundle);
}
}
head() 没啥好说的
endBody() 除了trigger()和ehco 标记 下面那个foreach() 里面的函数
protected function registerAssetFiles($name)
{
if (!isset($this->assetBundles[$name])) {
return;
}
$bundle = $this->assetBundles[$name];
if ($bundle) {
foreach ($bundle->depends as $dep) {
$this->registerAssetFiles($dep);
}
$bundle->registerAssetFiles($this); // 把css jss 文件都放入 view 全局变量中
}
unset($this->assetBundles[$name]);
}
主要就是把 css jss 文件都放入 view 全局变量中
<?php $this->endPage() ?>
public function endPage($ajaxMode = false)
{
$this->trigger(self::EVENT_END_PAGE);
$content = ob_get_clean();
echo strtr($content, [
self::PH_HEAD => $this->renderHeadHtml(),
self::PH_BODY_BEGIN => $this->renderBodyBeginHtml(),
self::PH_BODY_END => $this->renderBodyEndHtml($ajaxMode),
]);
$this->clear();
}
看到那个strtr 函数了么? 这里就是把你的css js 文件根据 key的代表的位置 进行替换到第二步中的钩子标记处
这样 css js 就注入到指定的位置了
一生二 二生三 三生万物,再复杂的事物都是有3步过来的。请记住把大象放冰箱只需要三步,学习YII2只需要三步。哈哈
本文由 ppker 创作,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。
赞,分享的很不错,但是排版还有待改善,学好 Markdown 排版,不要滥用格式,重新排版给你加精。