文章目录
1. 前言
我们希望在webpack环境中集成Vue,那么必然需要对其有依赖,所以需要先进行安装
- 因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖,要使用
--save
,而不是--save-dev
- 安装:
npm install vue --save
代码目录结构,本博客的演示代码在页面底部有下载链接(~ ̄▽ ̄)~
2. 代码演示
2.1 el和template模板的关系
index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>
<div id="app">
<h2>{
{message}}</h2>
<button @click="btnClick">按钮</button>
</div>
</body>
<script src="./dist/bundle.js"></script>
</html>
main.js文件
//使用vue进行开发
import Vue from 'vue'
let app = new Vue({
el: '#app',
data:{
message:'hello world'
},
methods:{
btnClick() {
console.log('---');
}
}
})
正常运行之后,我们来考虑另外一个问题:
- 如果我们希望将data中的数据显示在界面中,就必须是修改index.html
- 如果我们后面自定义了组件,也必须修改index.html来使用组件
- 但是html模板在之后的开发中,我并不希望手动的来频繁修改,是否可以做到呢?
定义 template
属性:
- 在前面的Vue实例中,我们定义了
el
属性,用于和 index.html 中的#app
进行绑定,让Vue实例之后可以管理它其中的内容 - 这里,我们可以将index.html文件中的div元素中的内容删掉,只保留一个基本的id为app的div元素
- 但是如果我依然希望在其中显示{ {message}}的内容,应该怎么处理呢?
- 我们可以再定义一个template属性,代码如下:
let app = new Vue({
el: '#app',
template: `
<div>
<h2>{
{message}}</h2>
<button @click="btnClick">按钮</button>
</div>
`,
data: {
message: 'hello world'
},
methods: {
btnClick() {
console.log('---');
}
}
})
重新打包,运行程序,显示和原来一样的结果和HTML代码结构。
那么,el和template模板的关系是什么呢?
- el用于指定Vue要管理的DOM,可以帮助解析其中的指令、事件监听等等。
- 而如果Vue实例中同时指定了template,那么template模板的内容会替换掉挂载的对应el的模板。
就像下面动图中展示的那样:template模板的内容会替换掉挂载的对应el的模板
这样做有什么好处呢?答案是:这样做之后我们就不需要在以后的开发中再次操作index.html,只需要在template中写入对应的标签即可
2.2 进一步抽离优化
对于上边的代码,书写template模块非常麻烦怎么办呢?
使用组件化的思想,我们可以将template模板中的内容进行抽离。
main.js
//使用vue进行开发
import Vue from 'vue'
// 1.抽离出一个组件
let App = {
template: `
<div>
<h2>{
{message}}</h2>
<button @click="btnClick">按钮</button>
</div>
`,
data() {
return {
message: 'hello world'
}
},
methods: {
btnClick() {
console.log('---');
}
}
}
let app = new Vue({
el: '#app',
template: '<App></App>', // 3.使用
components:{
// 2.在Vue根实例中进行注册
App
}
})
2.3 再次抽离成 js 文件
我们也可以将下面的代码抽取到一个js文件中,并且导出。
创建一个app.js文件
export default {
template: `
<div>
<h2>{
{message}}</h2>
<button @click="btnClick">按钮</button>
</div>
`,
data() {
return {
message: 'hello world'
}
},
methods: {
btnClick() {
console.log('---');
}
}
然后在main.js文件中进行引入
//使用vue进行开发
import Vue from 'vue'
import App from './vue/app'
let app = new Vue({
el: '#app',
template: '<App></App>',
components:{
App
}
})
2.4 继续抽离成 .vue 文件
但是上边的代码中,一个组件以一个js对象的形式进行组织和使用的时候是非常不方便的
- 一方面编写template模块非常的麻烦
- 另外一方面如果有样式的话,我们写在哪里比较合适呢?
现在,我们以一种全新的方式来组织一个vue的组件:创建一个 App.vue
文件
App.vue 文件
<template>
<div>
<h2 class="title">{
{
message}}</h2>
<button @click="btnClick">按钮</button>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
message: 'hello world'
}
},
methods: {
btnClick() {
console.log('---');
}
}
}
</script>
<style scoped>
.title {
color: red;
}
</style>
在main.js文件中进行引入
import Vue from 'vue'
// import App from './vue/app'
import App from './vue/App.vue' //注意需要加 .vue 后缀
let app = new Vue({
el: '#app',
template: '<App></App>',
components:{
App
}
})
重新打包,报错了。提示我们需要一个合适的 loader 来处理 .vue
文件
安装 vue-loader
和 vue-template-compiler
npm install vue-loader vue-template-compiler --save-dev
- vue-loader 是一个 webpack 的 loader,它允许你以一种名为单文件组件 (SFCs)的格式撰写 Vue 组件。
- vue-template-compiler 是对 vue文件进行编译的
配置
// webpack.config.js
module.exports = {
module: {
rules: [
// ... 其它规则
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
}
}
重新打包发现又报错了:提供我们 vue-loader 需要一个插件来配合使用
原因:我安装的 vue-loader的版本是 15.9.6,vue官网写到:Vue Loader v15 现在需要配合一个 webpack 插件才能正确使用。Vue Loader 的配置和其它的 loader 不太一样。除了通过一条规则将 vue-loader 应用到所有扩展名为 .vue 的文件上之外,还要确保在 webpack 配置中添加 Vue Loader 的插件 VueLoaderPlugin
。
这个插件是必须的! 它的职责是将你定义过的其它规则复制并应用到 .vue 文件里相应语言的块。 例如,如果我们有一条匹配 /\.js$/
的规则,那么它会应用到 .vue
文件里的 <script>
块。
// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
// ...
plugins: [
// 请确保引入这个插件来施展魔法
new VueLoaderPlugin()
]
}
重新打包,正常!
2.5 导入vue文件如何省略后缀名
// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
// ...
resolve: {
extensions:['.js','.vue','.css'] //加一条配置
}
}
3. 一些资料
https://www.cnblogs.com/vickylinj/p/10941112.html
演示代码下载链接:https://webchang.lanzous.com/i9bBNkgdnre 密码:34bq