当前位置: 首页 > news >正文

网站建设建网站网销怎么做

网站建设建网站,网销怎么做,企业网站开发多少钱,湘潭sem优化价格前言 在日常的Vue项目开发过程中&#xff0c;为了让项目更好的维护一般都会使用模块化开发的方式进行。也就是每个组件维护独立的template&#xff0c;script&#xff0c;style。主要介绍一下使用<style scoped>为什么在页面渲染完后样式之间并不会造成污染。 示例 搭…

前言

在日常的Vue项目开发过程中,为了让项目更好的维护一般都会使用模块化开发的方式进行。也就是每个组件维护独立的templatescriptstyle。主要介绍一下使用<style scoped>为什么在页面渲染完后样式之间并不会造成污染。

示例

搭建一个简单的Vue项目测试一下:

终端执行npx webpack输出dist目录,在浏览器打开index.html调试一下看看现象:

  1. 每个组件都会拥有一个[data-v-hash:8]插入HTML标签,子组件标签上也具体父组件[data-v-hash:8];
  2. 如果style标签加了scoped属性,里面的选择器都会变成(Attribute Selector) [data-v-hash:8];
  3. 如果子组件选择器跟父组件选择器完全一样,那么就会出现子组件样式被父组件覆盖,因为子组件会优先于父组件mounted,有兴趣可以测试一下哦。

webpack.config.js配置

先看看在webpack.config.js中的配置:

vue-loader工作流

以下就是vue-loader工作大致的处理流程:

开启node调试模式进行查看阅读,package.json中配置如下:

"scripts": {  "debug": "node --inspect-brk ./node_modules/webpack/bin/webpack.js"  },

VueLoaderPlugin

先从入口文件lib/index.js开始分析,因为我Webpack是4.x版本,所以VueLoaderPlugin = require('./plugin-webpack4'),重点来看看这个lib/plugin-webpack4.js文件:

const qs = require('querystring')
const RuleSet = require('webpack/lib/RuleSet')const id = 'vue-loader-plugin'
const NS = 'vue-loader'
// 很明显这就是一个webpack插件写法
class VueLoaderPlugin {apply (compiler) {if (compiler.hooks) {// 编译创建之后,执行插件compiler.hooks.compilation.tap(id, compilation => {const normalModuleLoader = compilation.hooks.normalModuleLoadernormalModuleLoader.tap(id, loaderContext => {loaderContext[NS] = true})})} else {// webpack < 4compiler.plugin('compilation', compilation => {compilation.plugin('normal-module-loader', loaderContext => {loaderContext[NS] = true})})}// webpack.config.js 中配置好的 module.rulesconst rawRules = compiler.options.module.rules// 对 rawRules 做 normlizedconst { rules } = new RuleSet(rawRules)// 从 rawRules 中检查是否有规则去匹配 .vue 或 .vue.html let vueRuleIndex = rawRules.findIndex(createMatcher(`foo.vue`))if (vueRuleIndex < 0) {vueRuleIndex = rawRules.findIndex(createMatcher(`foo.vue.html`))}const vueRule = rules[vueRuleIndex]if (!vueRule) {throw new Error(`[VueLoaderPlugin Error] No matching rule for .vue files found.\n` +`Make sure there is at least one root-level rule that matches .vue or .vue.html files.`)}if (vueRule.oneOf) {throw new Error(`[VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf.`)}// 检查 normlized rawRules 中 .vue 规则中是否具有 vue-loaderconst vueUse = vueRule.useconst vueLoaderUseIndex = vueUse.findIndex(u => {return /^vue-loader|(\/|\\|@)vue-loader/.test(u.loader)})if (vueLoaderUseIndex < 0) {throw new Error(`[VueLoaderPlugin Error] No matching use for vue-loader is found.\n` +`Make sure the rule matching .vue files include vue-loader in its use.`)}// make sure vue-loader options has a known ident so that we can share// options by reference in the template-loader by using a ref query like// template-loader??vue-loader-optionsconst vueLoaderUse = vueUse[vueLoaderUseIndex]vueLoaderUse.ident = 'vue-loader-options'vueLoaderUse.options = vueLoaderUse.options || {}// 过滤出 .vue 规则,其他规则调用 cloneRule 方法重写了 resource 和 resourceQuery 配置// 用于编译vue文件后匹配依赖路径 query 中需要的loaderconst clonedRules = rules.filter(r => r !== vueRule).map(cloneRule)// 加入全局 pitcher-loader,路径query有vue字段就给loader添加pitch方法const pitcher = {loader: require.resolve('./loaders/pitcher'),resourceQuery: query => {const parsed = qs.parse(query.slice(1))return parsed.vue != null},options: {cacheDirectory: vueLoaderUse.options.cacheDirectory,cacheIdentifier: vueLoaderUse.options.cacheIdentifier}}// 修改原始的 module.rules 配置compiler.options.module.rules = [pitcher,...clonedRules,...rules]}
}

以上大概就是VueLoaderPlugin所做的事情。也就是说VueLoaderPlugin主要就是修改module.rules的配置。总的来说就是对vue单文件编写做的一个扩展(比如可以写less文件,在vue style中也可以写less)

vue-loader

vue-loader是如何操作.vue文件的,目前只关心style部分,逻辑在lib/index.js

vue文件解析

// 很明显这就是一个loader写法
module.exports = function (source) {const loaderContext = this// ...const {target,request, // 请求资源路径minimize,sourceMap, rootContext, // 根路径resourcePath, // vue文件的路径resourceQuery // vue文件的路径 query 参数} = loaderContext// ...// 解析 vue 文件,descriptor 是AST抽象语法树的描述const descriptor = parse({source,compiler: options.compiler || loadTemplateCompiler(loaderContext),filename,sourceRoot,needMap: sourceMap})/****/// hash(文件路径 + 开发环境 ?文件内容 : "")生成 idconst id = hash(isProduction? (shortFilePath + '\n' + source): shortFilePath)// descriptor.styles 解析后是否具有 attrs: {scoped: true}const hasScoped = descriptor.styles.some(s => s.scoped)/****/let stylesCode = ``if (descriptor.styles.length) {// 最终生成一个import依赖请求stylesCode = genStylesCode(loaderContext,descriptor.styles,id,resourcePath,stringifyRequest,needsHotReload,isServer || isShadow // needs explicit injection?)}
}

可以看到解析完vue文件的结果大概就是这样的:

依赖解析

vue文件解析完之后template,script,style等都有个依赖的路径,后续可以通过配置的loader进行解析了,因为我们已经在VuePluginLoader中修改了module.rules的配置,而且依赖的路径中query中都拥有vue字段,所以会先走到pitcher-loader,现在来分析lib/loaders/pitcher.js中的逻辑:

/***
*/
module.exports = code => codemodule.exports.pitch = function (remainingRequest) {const options = loaderUtils.getOptions(this)const { cacheDirectory, cacheIdentifier } = optionsconst query = qs.parse(this.resourceQuery.slice(1))let loaders = this.loadersif (query.type) {if (/\.vue$/.test(this.resourcePath)) {// 过滤eslint-loaderloaders = loaders.filter(l => !isESLintLoader(l))} else {loaders = dedupeESLintLoader(loaders)}}// 过滤pitcher-loaderloaders = loaders.filter(isPitcher)const genRequest = loaders => {const seen = new Map()const loaderStrings = []loaders.forEach(loader => {const identifier = typeof loader === 'string'? loader: (loader.path + loader.query)const request = typeof loader === 'string' ? loader : loader.requestif (!seen.has(identifier)) {seen.set(identifier, true)// loader.request contains both the resolved loader path and its options// query (e.g. ??ref-0)loaderStrings.push(request)}})return loaderUtils.stringifyRequest(this, '-!' + [...loaderStrings,this.resourcePath + this.resourceQuery].join('!'))}if (query.type === `style`) {const cssLoaderIndex = loaders.findIndex(isCSSLoader)// 调整loader执行顺序if (cssLoaderIndex > -1) {const afterLoaders = loaders.slice(0, cssLoaderIndex + 1)const beforeLoaders = loaders.slice(cssLoaderIndex + 1)const request = genRequest([...afterLoaders, // [style-loader,css-loader]stylePostLoaderPath, // style-post-loader...beforeLoaders // [vue-loader]])return `import mod from ${request}; export default mod; export * from ${request}`}}/****/const request = genRequest(loaders)return `import mod from ${request}; export default mod; export * from ${request}`
}

可以看到解析带scoped属性的style的结果大概就是这样的:

新的依赖解析

分析{tyep:style}的处理流程顺序:

  • vue-loader、style-post-loader、css-loader、style-loader。

处理资源的时候先走的是vue-loader,这时vue-loader中的处理逻辑与第一次解析vue文件不一样了:

const incomingQuery = qs.parse(rawQuery)
// 拥有{type:style}
if (incomingQuery.type) {return selectBlock(descriptor,loaderContext,incomingQuery,!!options.appendExtension)}// lib/select.jsmodule.exports = function selectBlock (descriptor,loaderContext,query,appendExtension
) {// ...if (query.type === `style` && query.index != null) {const style = descriptor.styles[query.index]if (appendExtension) {loaderContext.resourcePath += '.' + (style.lang || 'css')}loaderContext.callback(null,style.content,style.map)return}

可以看到vue-loader处理完后返回的就是style.content,也就是style标签下的内容,然后交给后续的loader继续处理

再来看一下style-post-loader是如何生成data-v-hash:8的,逻辑主要在lib/loaders/stylePostLoaders.js中:

const qs = require('querystring')
const { compileStyle } = require('@vue/component-compiler-utils')module.exports = function (source, inMap) {const query = qs.parse(this.resourceQuery.slice(1))const { code, map, errors } = compileStyle({source,filename: this.resourcePath,id: `data-v-${query.id}`,map: inMap,scoped: !!query.scoped,trim: true})if (errors.length) {this.callback(errors[0])} else {this.callback(null, code, map)}
}

处理最终返回的code是这样的:

http://www.cadmedia.cn/news/7773.html

相关文章:

  • 平阳高端网站建设网页开发工具
  • 建设电子商务网站的方法有?成品影视app开发
  • 如何免费制作一个公司网站免费外链网
  • 西安城乡建设委员会网站打不开重庆网络推广
  • 太原公司网站建设百度注册页面
  • 公司网站的建设与运营管理制度天津百度推广排名
  • 怎样做网站 - 百度网站百度收录
  • 无锡网站制作价格多少厦门百度竞价推广
  • 网站建设 任务链交换反应
  • 东莞大朗网站建设公司重庆seo入门教程
  • 更换wordpress字体浑江区关键词seo排名优化
  • 河南省 门户网站建设要求北京seo推广外包
  • 福州网站建设网站设计网站推广网站百度收录批量查询
  • 注册公司名字有没有重复在哪可以查关键词优化seo多少钱一年
  • 坪山附近公司做网站建设多少钱厦门百度快速优化排名
  • 好用网站推荐上海网络推广培训机构
  • 政府网站集约化建设的通知网络推广文案策划
  • 自己买服务器搭建网站域名ip查询
  • 本科专业 网站开发广告电话
  • 恩城seo的网站品牌网站建设方案
  • 网站建设的工作职责是什么专业地推团队
  • 重庆网站建设制作设计公司网站收录检测
  • 国外做做网站重庆seo整站优化方案范文
  • 做申诉资料网站网络推广发展
  • 完美日记网络营销策划书站内关键词排名优化软件
  • 手机制作h5最常用软件seo排名优化怎样
  • 政府网站无障碍建设百度快速收录入口
  • 360网站服务监控免费广告投放网站
  • 嘉兴微网站建设百度图片识别在线使用
  • 门户网站建设目标图片外链生成工具在线