返回目录
返回目录
什么是组件化?
返回目录
步骤:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn>cpn>
<cpn>cpn>
<cpn>cpn>
<cpn>cpn>
div>
<script src="../js/vue.js">script>
<script>
//ES6用``可以代替字符串并不需要+拼接来换行写
// 1.创建组件构造器对象
const cpnC = Vue.extend({
template:`
我是标题
我是内容,哈哈哈哈
我是内容,呵呵呵呵
`
});
//注册组件
Vue.component('cpn',cpnC)
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
});
script>
body>
html>
Vue.component():
组件必须挂载在某个Vue实例下,否则它不会生效
返回目录
当我们调用Vue.component()注册组件时,组件的注册是全局的
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app2">
<cpn>cpn>
div>
<div id="app">
<cpn>cpn>
<cpn>cpn>
<cpn>cpn>
div>
<script src="../js/vue.js">script>
<script>
// 1.创建组件构造器
const cpnC = Vue.extend({
template:`
我是标题
我是内容,哈哈哈哈
我是内容,呵呵呵呵
`
});
// 2.注册组件(全局组件,意味着可以在多个Vue的实例下面使用)
/*Vue.component('cpn',cpnC)*/
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components:{
// cpn使用组件时的标签名,局部注册!!!
cpn: cpnC
}
});
const app2=new Vue({
el:'#app2'
})
script>
body>
html>
通过Vue.component()方法注册的组件是全局组件,通过 components 注册的是私有子组件
返回目录
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn2>cpn2>
div>
<script src="../js/vue.js">script>
<script>
// 1.创建第一个组件构造器(子组件)<只能在父组件中使用,想要外部使用,在外部也要进行注册>
const cpnC1=Vue.extend({
template:`
我是标题
我是内容,哈哈哈
`
})
// 2.创建第一个组件构造器(父组件)
const cpnC2=Vue.extend({
template:`
我是标题2
我是内容,呵呵呵
`,
components:{
cpn1:cpnC1
}
})
// root组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn2: cpnC2
}
});
script>
body>
html>
<div id="app">
<cpn2>cpn2>
div>
<script src="../js/vue.js">script>
<script>
// 1.创建第一个组件构造器(子组件)
const cpnC1 = Vue.extend({
template: `
我是标题1
我是内容, 哈哈哈哈
`
})
// 2.创建第二个组件构造器(父组件)
const cpnC2 = Vue.extend({
template: `
我是标题2
我是内容, 呵呵呵呵
`,
components: {
// 在父组件中注册子组件,这样就可以在父组件里面使用子组件
// 例如上面的
cpn1: cpnC1
}
})
// root组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
// cpn1子组件在cpn2父组件中注册,父组件cpn2在Vue实例里面注册
cpn2: cpnC2
}
})
script>
返回目录
Vue 为了简化这个过程,提供了注册的语法糖
主要是省去了调用 Vue.extend() 的步骤,而是可以直接使用一个对象来代替
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn>cpn>
<cpn2>cpn2>
div>
<script src="../js/vue.js">script>
<script>
// 1.全局组件注册的语法糖
// 不推荐的写法:const cpn = Vue.extend()
//2.注册组件(全局组件)
Vue.component('cpn',{
template:`
我是标题
我是内容,哈哈哈
`
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components:{
'cpn2':{
template: `
我是标题2
我是内容,哈哈哈
`
}
}
});
script>
body>
html>
返回目录
通过语法糖简化了 Vue 组件的注册过程,另外还有一个地方的写法比较麻烦,就是 template 模块写法
使用 script 标签:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn>cpn>
<cpn>cpn>
<cpn>cpn>
div>
<script type="text/x-template" id="cpn">
<div>
<h2>我是标题</h2>
<p>我是内容,哈哈哈</p>
</div>
script>
<script src="../js/vue.js">script>
<script>
// 1.注册一个全局组件
Vue.component('cpn', {
template: '#cpn'
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
script>
body>
html>
重点:使用template标签
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn>cpn>
<cpn>cpn>
<cpn>cpn>
div>
<template id="cpn">
<div>
<h2>我是标题h2>
<p>我是内容,呵呵呵p>
div>
template>
<script src="../js/vue.js">script>
<script>
// 1.注册一个全局组件
Vue.component('cpn', {
template: '#cpn'
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
script>
body>
html>
返回目录
组件可以访问Vue实例数据吗?
结论:组件不能直接访问Vue实例中的 data
注:即使访问放也不建议写在Vue实例中
组件是一个单独功能模块的封装:
组件自己的数据存放在哪呢?
<div id="app">
<cpn>cpn>
<cpn>cpn>
<cpn>cpn>
div>
<template id="cpn">
<div>
<h2>{{title}}h2>
<p>我是内容,呵呵呵p>
div>
template>
<script src="../js/vue.js">script>
<script>
// 1.注册一个全局组件
Vue.component('cpn', {
template: '#cpn',
data() {
return {
title: 'abc'
}
}
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
// title: '我是标题'
}
})
script>
为什么 data 在组件中必须是一个函数呢?
返回目录
在上一个小节中,我们提到了子组件是不能引用父组件或者Vue实例的数据的
但是,在开发中,往往一些数据确实需要从上层传递到下层
如何进行父子组件间的通信呢?
在组件中,使用选项 props 来声明需要从父级接收到的数据(properties)
props 的值有两种方式:
传数组:
<div id="app">
<cpn :cmessage="message" :cmovies="movies">cpn>
div>
<template id="cpn">
<div>
<h1>{{cmovies}}}h1>
<h1>{{cmessage}}h1>
div>
template>
<script src="../js/vue.js">script>
<script>
// 1.创建组件构造器(子组件)
const cpn = {
template: '#cpn',
props: ['cmovies', 'cmessage'] //父传子,props
}
// 3.注册组件(将子组件在父组件里面注册)
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['海王', '海贼王', '海尔兄弟']
},
components: {
//对象字面量增强写法的属性增强写法
cpn
}
})
script>
传对象:
验证支持的数据类型有:
①类型限制
我们可以在 props 里面限制父组件给子组件传递的数据类型
<div id="app">
<cpn :cmessage="message" :cmovies="movies">cpn>
div>
<template id="cpn">
<div>
<h1>{{cmovies}}}h1>
<h1>{{cmessage}}h1>
div>
template>
<script src="../js/vue.js">script>
<script>
// 父传子: props
const cpn = {
template: '#cpn',
props: {
// 1.类型限制
cmovies: Array, // 限制父组件传的是数组类型
cmessage: String, // 限制父组件传的是字符串类型
}
}
// root组件,我们当作父组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['海王', '海贼王', '海尔兄弟']
},
components: {
//对象字面量增强写法的属性增强写法
cpn
}
})
script>
②默认值和必传值
<div id="app">
<cpn :cmessage="message" :cmovies="movies">cpn>
div>
<template id="cpn">
<div>
<h1>{{cmovies}}}h1>
<h1>{{cmessage}}h1>
div>
template>
<script src="../js/vue.js">script>
<script>
// 父传子: props
const cpn = {
template: '#cpn',
// props: ['cmovies', 'cmessage'],
props: {
// 2.提供一些默认值, 以及必传值
cmessage: {
type: String, // 类型限制为 String
default: 'aaaaaaaa', // 如果没有传值,则给一个默认值
required: true // required 必须的,即意味着这个值是必须要传递的,不传就报错
},
// 类型是对象或者数组时, 默认值必须是一个函数
cmovies: {
type: Array,
default() {
return []
}
}
},
// root组件,我们当作父组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['海王', '海贼王', '海尔兄弟']
},
components: {
//对象字面量增强写法的属性增强写法
cpn
}
})
script>
③自定义类型
当我们有自定义构造函数时,验证也支持自定义的类型
④props驼峰标识
当我们 props 里面的属性是驼峰写法的时,在传入值时需要进行 - 连接
<div id="app">
<cpn :c-info="info" :child-my-message="message" >cpn>
div>
<template id="cpn">
<div>
<h2>{{cInfo}}h2>
<h2>{{childMyMessage}}h2>
div>
template>
<script src="../js/vue.js">script>
<script>
const cpn = {
template: '#cpn',
props: {
// 驼峰写法cInfo
cInfo: {
//类型是对象或者数组时, 默认值必须是一个函数
type: Object,
default() {
return {}
}
},
childMyMessage: {
type: String,
default: ''
}
}
}
const app = new Vue({
el: '#app',
data: {
info: {
name: 'why',
age: 18,
height: 1.88
},
message: 'aaaaaa'
},
components: {
cpn
}
})
script>
返回目录
什么时候需要自定义事件呢?
自定义事件的流程:
我们来看一个简单的例子:
我们之前做过一个两个按钮 +1 和 -1,点击后修改 counter
我们整个操作的过程还是在子组件中完成,但是之后的展示交给父组件
这样,我们就需要将子组件中的 counter,传给父组件的某个属性,比如total
<body>
<div id="app">
<cpn @item-click="cpnClick">cpn>
div>
<template id="cpn">
<div>
<button v-for="item in categories"
@click="btnClick(item)">
{{item.name}}
button>
div>
template>
<script src="../js/vue.js">script>
<script>
// 1.子组件
const cpn = {
template: '#cpn',
data() {
return {
categories: [
{id: 'aaa', name: '热门推荐'},
{id: 'bbb', name: '手机数码'},
{id: 'ccc', name: '家用家电'},
{id: 'ddd', name: '电脑办公'},
]
}
},
methods: {
btnClick(item) {
// console.log(item);
// 1.发射事件: 自定义事件
// 第一个参数是自定义事件的名称,第二个参数是自定义事件的参数
this.$emit('item-click', item)//发射
}
}
}
// 2.父组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn
},
methods: {
// 3.父组件里面定义方法处理
cpnClick(item) {
console.log('cpnClick', item);
}
}
})
script>
body>
返回目录
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn :number1="num1" :number2="num2" @num1change="num1change" @num2change="num2change">cpn>
div>
<template id="cpn">
<div>
<h2>props:{{number1}}h2>
<h2>data:{{dnumber1}}h2>
<input type="text" :value="dnumber1" @input="num1Input">
<h2>props:{{number2}}h2>
<h2>data:{{dnumber2}}h2>
<input type="text" :value="dnumber2" @input="num2Input">
div>
template>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
num1:1,
num2:0
},
methods:{
num1change(value){
this.num1=Number(value);
},
num2change(value){
this.num2=Number(value);
}
},
components:{
cpn:{
template:'#cpn',
props:{
number1:Number,
number2:Number,
},
data(){
return{
dnumber1:this.number1,
dnumber2:this.number2
}
},
methods:{
num1Input(event){
this.dnumber1=event.target.value;
this.$emit('num1change',this.dnumber1)
},
num2Input(event){
this.dnumber2=event.target.value;
this.$emit('num2change',this.dnumber2)
}
}
}
}
});
script>
body>
html>
返回目录
返回目录
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn :number1="num1" :number2="num2" @num1change="num1change" @num2change="num2change">cpn>
div>
<template id="cpn">
<div>
<h2>props:{{dnumber1}}h2>
<h2>data:{{dnumber1}}h2>
<input type="text" v-model="dnumber1">
<h2>props:{{dnumber2}}h2>
<h2>data:{{dnumber2}}h2>
<input type="text" v-model="dnumber2">
div>
template>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
num1:1,
num2:0
},
methods:{
num1change(value){
this.num1=value;
},
num2change(value){
this.num2=value;
}
},
components:{
cpn:{
template:'#cpn',
props:{
number1:Number,
number2:Number,
},
data(){
return{
dnumber1:this.number1,
dnumber2:this.number2
}
},
watch:{
dnumber1(newValue){
this.dnumber1=newValue
this.$emit('num1change',this.newValue)
},
dnumber2(newValue){
this.dnumber2=newValue
this.$emit('num2change',this.newValue)
}
}
}
}
});
script>
body>
html>
返回目录
有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件。
父组件访问子组件:使用 $children 或 $refs
子组件访问父组件:使用$parent
我们先来看下$children (它是一个复数)的访问
$children 的缺陷:
$refs 的使用
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn>cpn>
<cpn>cpn>
<cpn ref="aaa">cpn>
<button @click="btnClick">按钮button>
div>
<template id="cpn">
<div>我是子组件div>
template>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
methods: {
btnClick() {
// 2.$refs => 对象类型, 默认是一个空的对象 必须在组件上加 ref='bbb'
/*console.log(this.$children)//$children不常使用因为不建议使用下标值取值
this.$children[0].showMessage();
this.$children[0].name;*/
console.log(this.$refs.aaa.name);
}
},
components: {
cpn: {
template: '#cpn',
data() {
return {
name: '我是子组件的name'
}
},
methods: {
showMessage(){
console.log('我是子组件的方法')
}
}
},
}
})
script>
body>
html>
返回目录
如果我们想在子组件中直接访问父组件,可以通过 $parent
尽管在 Vue 开发中,我们允许通过 $parent 来访问父组件,但是在真实开发中尽量不要这要做
子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了
如果我们将子组件放入另外一个组件之内,很可能该父组件没有对应的属性,往往会引起问题
$parent(了解即可)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn>cpn>
div>
<template id="cpn">
<div>
<h2>我是cpn组件h2>
<ccpn>ccpn>
div>
template>
<template id="ccpn">
<div>
<h2>我是ccpn子组件h2>
<button @click="btnClick">按钮button>
div>
template>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn',
data(){
return{
name:'我是cpn组件的name'
}
},
components: {
ccpn: {
template: '#ccpn',
methods: {
btnClick() {
// 1.访问父组件$parent
console.log(this.$parent)
// 2.访问父组件的name
console.log(this.$parent.name);
}
}
}
}
}
}
})
script>
body>
html>
返回目录
slot翻译为插槽
组件的插槽
栗子:移动网站中的导航栏
如何封装这类组件呢?
如何封装合适呢?抽取共性,保留不同
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn><button>我是按钮button>cpn>
<cpn><span>我是spanspan>cpn>
<cpn>
<cpn>cpn>
cpn>
<cpn>
<button>按钮1button>
<button>按钮2button>
<button>按钮3button>
cpn>
div>
<template id="cpn">
<div>
<h2>我是组件h2>
<p>我是组件,哈哈哈p>
<slot><button>外界未指定则显示此默认button>slot>
div>
template>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components:{
cpn: {
template:'#cpn'
}
}
});
script>
body>
html>
返回目录
当子组件的功能复杂时,子组件的插槽可能并非是一个。
如何给插槽起名字呢?
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn><span slot="center">中间标题span><button slot="right">右边按钮button>cpn>
div>
<template id="cpn">
<div>
<slot name="left"><span>左边span>slot>
<slot name="center"><span>中间span>slot>
<slot name="right"><span>右边span>slot>
div>
template>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components:{
cpn: {
template:'#cpn'
}
}
});
script>
body>
html>
返回目录
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn v-show="isShow">cpn>
div>
<template id="cpn">
<div>
<h2>我是子组件h2>
<p>我是内容哈哈哈p>
<button v-show="isShow">按钮button>
div>
template>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isShow: true
},
components:{
cpn: {
template:'#cpn',
data(){
return{
isShow:false
}
}
}
}
});
script>
body>
html>
答案:最终可以渲染出来,也就是使用的是 Vue 实例的属性
为什么呢?
返回目录
一句话总结:父组件替换插槽的标签,但是内容由子组件来提供
我们先提一个需求:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn>cpn>
<cpn>
<template v-slot="slot">
<span v-for="item in slot.data">{{item}}-span>
template>
cpn>
<cpn>
<template slot-scope="slot">
<span v-for="item in slot.data">{{item}}***span>
template>
cpn>
<cpn>
<template slot-scope="slot">
<span>{{slot.data.join('***')}}span>
template>
cpn>
div>
<template id="cpn">
<div>
<slot :data="pLanguages">
<ul>
<li v-for="item in pLanguages">{{item}}li>
ul>
slot>
div>
template>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components:{
cpn:{
template:'#cpn',
data(){
return{
pLanguages:['javascript','python','Swift','Go','C++','java','C#']
}
}
}
}
});
script>
body>
html>
返回目录
JavaScript原始功能
在网页开发的早期,js制作作为一种脚本语言,做一些简单的表单验证或动画实现等,那个时候代码还是很少的。
返回目录
在项目发布之前,我们必然需要对js等文件进行压缩处理
npm install [email protected] --save-dev
返回目录
webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。
类似于 node.js 阶段用到的 nodemon 工具,每当修改了源代码, webpack 会自动进行项目的动态打包构建(没有真实的映射到硬盘,所以最后测试完发布的时候只需要必须执行一次打包命令)
npm install [email protected] --save-dev
配置命令:
输入npm run dev指令
测试:
服务器运行时我们进行动态修改代码就行了,最后部署的时候一定要执行打包命令
优化配置,不需要我们手动访问浏览器
测试指令npm run dev,完成(Ctrl+C中断服务器)
返回目录
场景引入:
这时候就需要我们进行单独分离了,把测试时和打包发布时的配置分离出来
平时小项目且生产环境和开发环境不是很复杂的时候是不需要分离的,而且Vue脚手架也是做了分离的
建立build文件夹和三个js文件
现在的问题是怎么在不同的阶段组合配置文件
下载安装webpack-merge(merge是合并的意思)
npm install webpack-merge
base.config.js中放公共的配置:
/*动态获取路径第一步导入我们的path*/
const path =require('path')/*这个path文件存在node包中,需要我们手动装*/
const webpack = require('webpack');
const HtmlWebpackPlugin=require('html-webpack-plugin');
module.exports={
entry:'./src/main.js',
output:{
path:path.resolve(__dirname,"dist"),/*动态获取我们的路径,resolve方法拼接,__dirname为所依赖的路径*/
filename:'bundle.js',
/*publicPath:'dist/'不再需要*/
},
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader' , 'css-loader']
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
esModule:false,
name: 'img/[name].[hash:8].[ext]'
},
}]
},
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { targets: "defaults" }]
]
}
}
},
{
test: /\.vue/,
use: ['vue-loader']
}
]
},
resolve:{
//alias:别名
alias:{
'vue$':'vue/dist/vue.esm.js'
}
},
plugins:[
new webpack.BannerPlugin('最终版权归ldx所有'),
new HtmlWebpackPlugin({
template:'index.html'
}),
]
}
dev.config.js:放入测试时的配置:
const webpackMerge=require('webpack-merge')
const baseConfig=require('./base.config')
module.exports= webpackMerge.merge(baseConfig,{//高版本的webpack-merge是一个对象,需要调用其merge方法才能正常运行
devServer:{
contentBase:'./dist',/*为哪一个文件夹提供本地服务,默认是根文件夹,我们这里填写./dist*/
inline:true/*页面实时刷新*/
}
})
pro.config.js:放入打包发布时的配置:
const UglifyJsWebpackPlugin=require('uglifyjs-webpack-plugin')
const webpackMerge=require('webpack-merge')
const baseConfig=require('./base.config.js')
module.exports=webpackMerge.merge(baseConfig,{//高版本的webpack-merge是一个对象,需要调用其merge方法才能正常运行
plugins:[
new UglifyJsWebpackPlugin()
]
})
删除原来的webpack.config.js文件
在package.json中配置命令:
打包:路径问题
打包位置在build下的dist包中,需要我们修改base.config.js文件的输出路径:
再次打包:
路径正确:
可以试试npm run dev:
也成功运行:
动态添加内容试试:
浏览器也是实时刷新: