1。回顾Vue的单文件组件
1.1 一个文件的组成部分
单文件组件 Vue SFC(single-file-component)是指扩展名为 .vue 的文件。内容通常包含三个块 使用单文件组件开发.vue的优点: 插入重要知识点-loaderwebpack配置方法 官方说法:loader总是被从右到左称为。在某些情况下,loader只关心请求后的元数据,而忽略前面的loader的结果。其实(从右到左)在执行loader之前,loader上的调试方法会叫从左到右民间:从左到右、从上到下的倾斜方法,作用:♼共享数据,将提前返回(跳过剩余的loader) 然后直接在输入文件中配置loader 打包结果:只写了loader AwithPitch中pitch方法中的内容,不执行loader B和loader AwithPitch的默认导出函数 .vue 文件最终是如何创建的?我们来看一个简单的 webpack 项目: VueLoaderPlugin - 转换webpack配置的module.rule,伪代码: vue-loader – 转换 .vue 文件: 当其他文件导入这个vue文件执行var component = Normalizer()时,代码会在Normalizer中编译并添加新属性;返回的对象如下:
template(模板块) script(js脚本块) style(样式块)
1.2 创建.vue文件的流程
官方文档:webpack.docschina.org/concepts/lo…
配置方法
loader从右到左(或从下到上)评估/执行module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true
}
},
]
}
]
}
};
内
//app.js
import style0 from 'style-loader!css-loader!./my.unknow'
// 这样就指定了到my.unknow这个文件时以(从右到左)css-loader=>style-loader的顺序去解析
console.log('hey')
例如以下示例://loaderAwithPitch.js
module.exports = function (source) {
console.log('runA')
return `10000\n${source}`
};
// 到处pitch方法给webpack
module.exports.pitch = function (remainingRequest, precedingRequest, data) {
console.log('pitch',remainingRequest,precedingRequest,data)
return 'nothing';
// return source;
}
//loaderB.js
module.exports = function (source) {
console.log('runB')
return `20000\n${source}\n`
};
//index.js
import str from "./loaderAwithPitch!./loaderB.js!./todo.js";
console.log(str);
过程有点像 在 DOM 事件中捕获和冒泡 :|- loaderAwithPitch `pitch`
|- loaderB `pitch`
|- requested module is picked up as a dependency
|- loaderB normal execution
|- loaderAwithPitch normal execution
//流程是 loaderAwithPitch的pitch方法=>loaderB的pitch方法(如果有)=>loaderB执行=>loaderA执行
//期间如果pitch方法提前返回,将不执行后面的流程
输入文件是main.js,然后加载vue文件
我们都知道浏览器可以直接运行js代码,但是vue文件中的代码不能在浏览器中直接运行
这样 webpack 支持 vue 文件已经转换好了,配置如下const { VueLoaderPlugin } = rquire("vue-loader");
module.exports = {
mode: "development",
module: {
rules: [
{
test: /\.vue/,
use: "vue-loader",
},
{
test: /\.css$/,
use: ["vue-style-loader", "css-loader"],
},
],
},
plugins: [new VueLoaderPlugin()],
}
.vue 文件 => vue-loader => js 文件
导入该文件里面的代码运行并返回 vue 组件配置对象
2。探索新模式
.vue 文件的优点不言而喻,现在我们来想一下缺点,对我来说是
有时候组件太多需要在IDE中维护时反复跳转?
现在让我们驱动:
既然import是一个对象,那么让我们制作一个可以生成对象的对象,但同时我们可以做一些数据/方法❀计算配置,如Function| object|class,都可以实现,我们先尝试使用class同时编写对应的loader来分析我们定义的模板区的模板代码
class VueCar {
constructor() {
this.options = {
data: {},
methods: {},
components: {},
mounted:[]
};
}
// 我们只要无脑的return this就能无限打点了
components(obj) {
Object.assign(this.options.components, ...obj);
return this;
}
template() {
// do
return this;
}
style() {
// do
return this;
}
done() {
return this;
}
data(obj) {
Object.assign(this.options.data, ...obj);
return this;
}
methods(fn) {
Object.assign(this.options.methods, ...fn.call(this.options));
return this;
}
mounted(fn){
this.options.mounted.push(()=>fn(this.options))
return this;
}
final(){//最后导出调用的方法,翻译this.options成VuecomponentOptions格式
return transformToVue(this.options)
}
}
然后这样写js文件
import List from './List.vue' //兼容vue文件
let Header = new VueCar()
.template(() => <header>this is header</header>)
.done()
.style(
<style>
.message{
color:blue;
}
</style>
)
.done()
.mounted((options) => {
console.log("mounted");
});
let Content = new VueCar()
.components({List})
.template(() => <footer><List/>is footer</footer>)
.mounted(() => console.log("footer mounted"));
let App = new VueCar();
App.components({
Header,
Content,
})
.template(() => (
<div>
<div>{{ message }}</div>
<button v-on:click="changeMessage">changeMessage</button>
</div>
))
.done()
.data({
message: "hey,vue",
})
.methods((options) => ({
changeMessage() {
options.data.message = Math.random();
},
}));
export { Header, Content, App };
这个js文件还必须配备vueCarLoader,解析并替换其中的模板/样式块(所以你需要。)
我们可以通过这种方式编写单独的几个组件js文件和导出是分开的。同时,也许我们的类也可以支持typescript配置……
ps:在测试过程中,我发现样式块无论如何都无法用js编写,并且IDE报错。也许未来需要插件支持?
根据上面的类模型,我构建了一个测试版本。名字是vue-highway。这是一个演示项目,大家看看
github.com/avenger9527…
如图所示,
优点 – 在一个 js 中编写多个组件 / 兼容原来的写法
缺点 模板中不支持
大佬们快来参与讨论吧!更多有趣的编码~ ?
多多批评!
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。