vuejs、vue CLI、webpack笔记

一、vue.js语法

1. 开始操作

1.1 安装vue.js

官网 下载js文件,添加到项目文件夹中

1.2 使用vue

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>title</title>
	</head>
	<body>
		<div id='app'>{{message}}</div> <!-- 双括号mustache(胡须)语法 -->
		<script src='../js/vue.js'></script>
		<script>
			//声明式编程,区别于document.getElementById('app')这种命令式编程
			const app = new Vue({
				el:'#app',//用于挂载要管理的元素
				data:{//初始化数据
					message:'vue 我来了'
				}
			})
		</script>
	</body>
</html>

2. 标签

2.1 v-if

作用:
  v-if:'data',若data数值为真就渲染组件,否则不渲染。

2.2 v-else-if

作用:
  与v-if结合使用,效果类似。

2.3 v-show

  v-show='data',若data数值为真就显示组件,否则不显示,不显示效果等同于display:none;区别于v-if的不渲染。

2.4 v-pre

作用:
  跳过这个元素和它的子元素的编译过程。一些静态的内容不需要编辑加这个指令可以加快编辑。

2.5 v-once

作用:
  如果显示的信息后续不需要再修改,使用v-once,这样可以提高性能。

2.6 v-bind

作用:
  动态将数据和属性(style,class...)标签进行绑定。
简写:':'

2.7 v-cloak

2.7.1 语法格式
 <div v-cloak>{{data}}</div>
作用:
  在网络延迟高时,可能会在页面突兀的显示代码: {{data}},加上v-cloak(斗篷)在data还没有完全加载出来前可以掩藏 {{data}}。

2.8 v-for

作用:
  遍历数组或者对象元素,遍历出来的数据绑定组件逐个渲染。
示例
<!-- 根据实际开发中的重要性,先value,最后index;value,key,index名字可以自定义 -->
<div v-for='(value, key, index) in object'>
   <div>{{index}} {{key}} {{value}} </div>
</div>

2.9 v-on

作用
  绑定事件函数,示例:v-on:click = 'clickFunction' 等同于 on-click = 'clickFunction'
修饰符
  • stop:停止向上冒泡
  • once:使绑定的事件只响应一次
  • prevent:阻止组件的默认行为,比如form表格的默认active行为
  • {keyCode|keyAlias}:对按键事件的过滤,例如:v-on:key.enter = 'functionName' 只有按下enter建才进行回调
  • native:监听组件根元素的原生事件
简写:'@'

2.10 v-model

作用:
  实现数据与表单的双向绑定。
原理
<input v-model="message" value="message">
<!-- 上面代码效果等同于下面-->
<input v-bind:value="message" @input="message=$event.target.value"/>
v-model 结合单选按钮
<body>
      <div id='app'>
	<input value='男' type='radio' name='radio-group' v-model="sex"/>男
	<input value='女' type="radio" name='radio-group' v-model='sex'/>女
	<h3>{{sex}}</h3>
      </div>
	<script src='../js/vue.js'></script>
	<script>
	const app = new Vue({
			el:'#app',
			data:{
				sex:'男'
			      }
			})
	</script>
</body>
v-model 结合复选框

复选框单选对应 bool值,多选对应数组[]

<body>
      <div id='app'>
	<input type="checkbox" v-bind:value='agree' v-model='agree' />同意协议
	<h3>{{agree}}</h3>
	</div>
	<script src='../js/vue.js'></script>
	<script>
	const app = new Vue({
			el:'#app',
			data:{
				agree:false
			}
			})
	</script>
</body>

<body>
      <div id='app'>
	<div v-for='(hobby,index) in hobbies'>
	      <input v-bind:value='hobby' type='checkbox' name='index' v-model="selectedHobbies"/>{{hobby}}
		</div>
		<h3>{{selectedHobbies}}</h3>
		</div>
      <script src='../js/vue.js'></script>
      <script>
      const app = new Vue({
		el:'#app',
		data:{
		hobbies:['游泳','跑步','看书','绘画'],
		selectedHobbies:[]
		}
		})
      </script>
</body>
v-model 结合select
<!-- 若想实现多选 添加标签:multiple -->
<select name='abc' v-model='fruit'>
      <option value='苹果'>苹果</option>
      <option value='香蕉'>香蕉</option>
      <option value='葡萄'>葡萄</option>
      <option value='榴莲'>榴莲</option>
</select>
修饰符:
  • lazy:对于绑定的组件,只在其失去焦点或按下回车才更新vue实例中的数据。
  • number:传入vue实例中的数据为Number对象
  • trim:除去数据中的前后空格

3. 组件中的key属性

3.1 作用:

  唯一确定组件,使组件能不随意更新。通俗讲可以让组件更好复用或不复用。

3.2 示例:若不加入key,js内核会复用input组件,造成组件中的值会保留。

<body>
      <div id='app'>
            <div v-if='flag'>
	      <input key='account'/>账号登录
            </div>
            <div v-else>
                  <input key='email'/>邮箱登录
            </div>
      <button @click="btnClick">{{login}}</button>
      </div>
<script src='../js/vue.js'></script>
<script>
      const app = new Vue({
                  el:'#app',
                data:{
		        flag:true,
                        login:'切换邮箱登录'
			},
              methods:{
			btnClick(){
			      if(this.flag){
				this.flag = !this.flag;
				this.login = '切换账号登录';
				}else{
					this.flag = !this.flag;
					this.login = '切换邮箱登录'
				}
			}
		        }
			})
</script>
</body>

4. 响应式函数

4.1 响应式操作

修改vue实例中数据,绑定vue实例中数据的组件/属性会实时更新。通过函数实现的响应式操作即为响应式函数。

4.2 关于数组操作的响应式函数

  • push('') 最后加多元素
  • pop() 删最后一个
  • shift() 删第一个
  • unshift('') 最开头添加多个元素
  • splice('','','') start, length ,item 它可以进行删除元素,插入元素,替换元素
  • reverse 数组反转

4.3 非响应式操作

通过索引改变数组!!!

5. Vue实例中的过滤器对象

5.1 作用

将数据按照一定的规则转化为另外一个数据返回。

5.2 示例:将price作为参数传入priceFilter中,返回修改后的price

<body>
      <div id='app'>
	<!-- 使用过滤器 ,默认将price作为参数传入给priceFilter-->
	<h4>价格:{{price | priceFilter}}</h4>
      </div>
      <script src='../js/vue.js'></script>
      <script>
            const app = new Vue({
                        el:'#app',
                        data:{
				price:12.3
			      },
                        filters:{ //在vue实例中加入filter对象,在filter对象里面定义过滤器(函数)
				priceFilter(price){
				//保留小数2位:Number.toFixed(2) 
				return '¥' + price
				}
			}
			})
	</script>
</body>

6. js中高阶函数 (很多高级语言中都会有)

6.1 filter()

  result = array.filter(callback(n){}) 回调函数返回的必须为一个bool值,若为true自动 将n加入内部数组,否则不加入

6.2 map()

  result = array.map(callback(n){}) 回调函数的返回值为新数值返回

6.3 reduce()

  result = array.reduce(callback(n1,n2){},0) 第二个参数为第一个值的初始值, 对两个值进行操作,返回操作后的结果作为下一组传入的第一个值。 

7. 组件化

7.1 自定义第一个组件 (创建构造器,注册组件,使用组件)

<body>
		<div id='app'>
			<!-- 使用组件 -->
			<my-component></my-component>
		</div>
		<script src='../js/vue.js'></script>
		<script>
			//创建组件构造器
			creater = Vue.extend({
				//tab键上面的那个符号在ES6中可以实现内部内容任意换行圈成一个整体
				name:'cmp',
				template:`
				<div>
					<h4>我的第一个组件</h4>
				</div>
				`
			})
			//注册组件 (此方法注册的组件为全局组件,所有vue实例挂载的元素中都可以使用)
			Vue.component('my-component',creater)
			const app = new Vue({
				el:'#app'
			})
		</script>
	</body>

7.2 全局组件注册的简写(语法糖)

//Vue.compontent会自动将第二个参数{}传给Vue.extend()
Vue.component('my-component',{ 
	template:`<div></div>`
	})

7.3 局部组件注册 (确立一个概念:Vue实例本身是个组件)

<body>
		<div id='app'>
			<cpn></cpn>
		</div>
		<div id='app2'>
			<!-- <cpn></cpn>  试图引用app实例的局部组件,报错! -->
		</div>
		<script src='../js/vue.js'></script>
		<script>
			const cpnC = Vue.extend({
				template:'<div>局部组件</div>'
			})
			const app = new Vue({
				el:'#app',
				components:{
					cpn:cpnC
				}
			})
			const app2 = new Vue({
				el:'#app2'
			})
		</script>
	</body>

7.4 组件中的模板(template)分离写法

1.通过脚本分离:
<script type='text/x-template' id='temp'>
	<div>
		在类型为'text/x-template'的script中定义
	</div>
</script>
<script >
		//通过id引用
		Vue.component('my-component',{template:'#temp'})
</script>
2.通过组件模板分离
<template id='#temp'>
	<div>
		在template组件中定义模板
	</div>
</template>

<script>
	Vue.component('my-component',{template:'#temp'})
</script>

7.5 向组件中存放数据

<!-- 使用组件中message数据 -->
<cpn>{{message}}</cpn>
--------------------------------------------------
<script>
Vue.component('cpn',
	{
		template:'#cpn',
		data()   //这个对象必须为函数
		{
			return {message:'abc'}
		}
	}
)
</scirpt>

7.6 思考:组件中data为什么是函数?

这可以保证数据作用域仅限于当前组件,而不会作用于其他相同的组件!

7.8 创建父子组件

<body>
	<div id='app'>
		<!-- 使用组件 -->
		<cpn2></cpn2>
	</div>
	<script src='../js/vue.js'></script>
	<script>
		const cpnC = Vue.extend({
		template:'<div>子组件</div>'
		})
		Vue.component('cpn2',{
			template:'<div>父组件<cpn></cpn></div>',
			components:{
			cpn : cpnC  //*这里只能是一个组件构造器,若为一个组件就报错找不到
				}
			}
		)
		const app = new Vue({
			el:'#app'
			})
	</script>
</body>

7.9 父子组件的通信

需求:子组件不能引用父组件或者Vue实例的数据,但是实际开发中却需要父子组件相互通信!
Vue提供的方法:
	通过props(properts 简写)向子组件传递数据;
	通过事件($emit Events)向父组件发送数据。
1. 父组件向子组件传递数据:
<body>
		<div id='app'>
			<!-- 父组件向子组件传递数据 -->
			<cpn v-bind:movies='movieList'></cpn>
		</div>
		<template id="temp">
			<div>
				<ul>
					<!-- 遍历显示组件中的movies数据 -->
					<li v-for='movie in movies'>{{movie}}</li>
				</ul>
			</div>
		</template>
		<script src='../js/vue.js'></script>
		<script>
			const app = new Vue({
				el:'#app',
				data:{
					movieList:['三傻大闹宝莱坞','我不是药神','唐人街探案']
				},
				components:{
					cpn:{
						template:'#temp',
						props:['movies'] //这里的movies在上面被当成一个变量属性
					}
				}
			})
		</script>
</body>
1.1 props的一些可选操作
  1. 数据类型限制:
    props:

  2. 带默认值:(对象中 required 表示 是否必须传数据)

props:
{movies:
      {	
	type:Array,
	default:[''],
	required:true
      }
}

上面的语法有个错误,default默认值为数组或对象类型时default必须为一个函数:default(){return []}

  1. 自定义数据类型:
    props:
1.2 props中数据变量驼峰命名问题:
props:{moviesName:Array} //声明时为驼峰

<cpn v-bind:movies-name='moviesName'/> //使用时要以-连接
2.子组件向父组件传递数据:($emit发射的事件同样不能用驼峰命名法)
<!-- 触发流程:btnClick -->cpn-event -->getCpnData -->
<body>
		<div id='app'>
			<cpn @cpn-event='getCpnData'></cpn>
			<h2>子组件传来的数据:{{cpnData}}</h2>
		</div>
		<template id="temp">
			
		</template>
		<script src='../js/vue.js'></script>
		<script>
			const app = new Vue({
				el:'#app',
				data:{
					cpnData:''
				},
				methods:{
					getCpnData(item){
						this.cpnData = item
					}
				},
				components:{
					cpn:{
						template:`
						<div>
							<button @click="btnClicked">子组件按钮</button>
						</div>
						`,
						data(){
							return {item:'子组件数据'}
						},
						methods:{
							btnClicked(){
								return this.$emit('cpn-event',this.item)
							}
						}
					}
				}
			})
		</script>
	</body>
扩展知识
<!-- component watch 对象 监听数据改变;
watch中的函数名 和 data 返回的变量名相同 -->
data(){
	return {number1:123}
      },
watch:{
         number1(newValue, oldValue){
         this.number1 = newValue;
         this.$emit('numb1change',this.number1) 
         }
      }

7.10 父子组件互相访问

1.父组件访问子组件

$children 或者 $refs (reference)

this.$children[0].function()
this.$children[1].name

在实际开发中一般不使用this.$children ,组件数量随时会变,下标取值不稳定

this.$refs.aaa 父组件中访问子组件,refs默认为空,在组件中需要加ref
<cpn ref='aaa'> </cpn> 组件中加入ref使用
2.子组件访问父组件
his.$parent  //在子组件中访问父组件
this.$root //在子组件中访问vue实例

7.11 slot 插槽

作用
使组件内部具有更好可扩展性。使得我们可以给自定义组件中添加中添加其他html内容。
使用方法
<!-- 1.在模板中定义slot -->
<template id="temp">
	<div>自定义组件
		<slot></slot>
	</div>
</template>

<!-- 2.使用带有slot的模板的组件 -->
<!-- h2 和 button 会替换组件中的slot,可以将slot理解为一个占位符 -->
<cpn>
	<h2>给自定义组件添加html元素</h2>
	<button>按钮</button>
</cpn>
slot常见几种情形
<!-- 1.带默认值slot -->
<!-- 若不给自定义组件中添加html内容,默认显示button;若添加了就替换button  -->
<slot><button>按钮</button></slot>

<!-- 2.具名(带name)slot -->
<template id='barTemp'>
	<slot name='left'></slot>
	<slot name='center'></slot>
	<slot name='right'></slot>
</template>
<!-- 使用:(指名道姓替换组件中某个插槽) -->
<cpn><button slot='left'>返回</button></cpn>
<cpn><span slot='center'>标题</span></cpn>
<cpn><button slot='right'>搜索</button></cpn>

<!-- 3.作用域slot :父组件替换插槽的标签,但是内容由子组件来提供-->
<!-- 需求:内容在子组件,希望父组件告诉我们如何展示,怎么办? -->
<template>
	<slot v-bind:data='子组件数据'></slot>
</template>
<!-- 重点是:slot-scope='slot' -->
<cpn>
	<template slot-scope='slot'>
		<div v-for='item in slot.data'>{{item}}</div>
	</template>
</cpn>

二、模块化和webpack

1. 模块化规范

1.1 常见模块化规范:

CommonJS(node采用的该规范)、AMD、CMD、ES6的Modules

1.2 CommonJS 的导出

请在node 环境下使用

a.js文件:

flag = true
sum(a,b){
	return a+b
}
<!-- 重点:module.exports -->
module.exports = {
	flag:flag,
	sum:sum
}

2.2 CommonJS 的导入

b.js文件

<!-- 重点:require -->
var obj = require('a.js')
console.log(obj.flag)
console.log(obj.sum(1,2))

2.3 脚本标签中的 module 类型

作用:
  将每个js文件作为独立的模块,避免了js文件间命名冲突。
演示

a.js文件中:

var flag = true
if(flag){console.log('a.js文件')}

b.js文件中:

if(flag){console.log('b.js文件')}

index.html 文件中

<!-- 加入type='module' 后会报错 ,
因为type='module' 可以保证多个文件共同引用不会出现命名冲突-->
<script src='a.js' type='module'></script>
<script src='b.js' type='module'></script>
思考:一个js文件想引用另外一个js文件中的数据ES6中怎么实现?
ES6 标准中的export,import 的运用。

2.4 ES6 的导出

a.js文件中 export演示

var name = '鲤鱼的探险历程'
getName()
{
      return name
}
//方式一:对象形式导出
export {name, getName}
//方式二:直接导出
export var name2 = 'vue coder'
//方式三:匿名导出
const email = '123@126.com'
export default email   //同一个模块(文件)中只能存在一个

2.5 ES6 的导入

b.js文件中 import演示

//对应方式一:
import {name, getName} from 'a.js'
//对应方式二:
import {name2} from 'a.js'
//对应方式三:
import my_email from 'a.js' //导入者自己命名变量

应用于除了匿名导出的其他方式:
//‘* as ’的作用:给导入对象命名,避免 1.导入变量和当前文档中的变量相同产生冲突,2.导入数据过多的问题
import * as aaa from '../aa.js'  
console.log(aaa.val)

2. webpack的使用

webpack官网

webpack中文

webpack功能图

2.1 webpack 的安装

全局安装
  npm install webpack -g 
本地(局部)安装
  npm install webpack --save

2.2 建立项目

目录结构
  • dist //保存打包后的文件
  • src //源代码文件夹
    * main.js //在该文件引用所有js文件
    * a.js
    * b.js
  • index.html //项目入口文件

2.3 打包文件

把终端(cmd)路径换成当前项目路径,然后键入(4.x.x版本):

webpack ./src/main.js -o ./dist/bundle.js

webpack3.x.x的版本使用:

webpack ./src/main.js ./dist/bundle.js

解释:将main.js以及它所引用的所有js文件打包到bundle.js文件;
若是webpack 5.x.x会在dist/bundle.js 的文件夹中生成打包后的main.js
思考:怎么精简:webpack ./src/main.js ./dist/bundle.js ?
需要对webpack进行配置。
配置流程:
  1. 当前项目中建立文件:webpack.config.js
  2. webpack.config.js中添加内容:
const path = require('path')  //导入node的path包
module.exports = {
	entry:'./src/main.js',
	//output中的路径必须为绝对路径
	output:{
	//__dirname 为node中上下文全局变量,值为当前路径,
	//path.resolve 进行路径拼接
	path:path.resolve(__dirname,'dist'),
	filename:'bundle.js'
	},
	mode:'development' //不加这条代码,在4.x.x以上的webpack默认打包为压缩后的代码
}
//概括:将src下的main.js文件打包到当前路径下的dist文件夹的bundle.js文件中
思考:这里引用了nodo的path包,那么就需要配置一个package.json文件,该文件如何配置?
1. 在当前项目路径下运行终端命令:npm init 
2. 按照提示进行配置,配置完后项目中就会生成 package.json 文件
<!-- package.json 文件内容 -->
{
  "name": "webpacktest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",//随便填的入口文件
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
       },
  "author": "",
  "license": "ISC"
}
  1. 以后在终端直接输入:webpack ,即可起到相同打包效果。

2.4 npm 运行 webpack

思考:若配置文件很多webpack命令就会又变得很长,怎么解决?
  用 npm run ... 代替。
怎么用npm run build 代替 webpack ?
  在 package.json 的scripts中添加:"build":"webpack" 
运行npm run build 时,会默认先从局部(本地)找webpack,再找全局
这里面存在一个问题:若项目中需要低版本的webpack怎么办?
  安装局部(本地)webpack : npm install webpack@3.6.0 --save-dev //有-dev意思为开发时依赖
在终端使用webpack命令会使用全局的webpack. 想访问本地需要输入 ./node_module/.bin/webpack

2.5 webpack.loader

loader作用
  将 less-->css ,TypeScript --> js ... 
  总的一句话:将其他文件打包为css、js、html这种浏览器认识的基本类型
loader的使用
  步骤一:npm 安转需要使用的loader;(不同文件打包,对应不同loader)

  步骤二:在webpack.config.js 中的module关键字下进行配置
2.5.1 打包CSS

1.npm install --save--dev css-lodeer style-loader

2.webpack.config.js 文件配置:

module:{
      rules:[
	{
            test:/\.css$/,
            use:['style-loader','css-loader']
            //css-loader 负责加载css文件,style-loader负责编译
            //为什么css-loader写在后面,因为node数据加载默认从右至左
	}
      ]
}
2.5.2 打包less

1.npm install --save-dev less-loader less //less负责转换less-->css

2.{test:/.less$/, use['style-loader','css-loader','less-loader']}

2.5.3 打包图片

1.npm install --save-dev url-loader

2.webpack.config.js文件中:

module:{
      rules:[
            {
                  test:/\.(png|jpg|jpeg)$/,
                  use:[
                        {
                              loader:'url-loader',
                              options:{limit:8192}
                              //小于limit大小的图片会被base64编码后替换图片url
                              //当加载大于limit的图片时需要file-loader 模块
			}
			]
	}
	]
}

3.若image的大小有大于limit限制的才有这步骤:
npm install --save-dev file-loader

!!!若运行程序入口网页index.html不在dist包中,可能会报路径加载错误

  原因:file-loader会将照片文件加载到打包文件中,这样源代码中的路径就会有问题。
	
  解决方法:使打包照片路径时候自动添加上dist路径,在webpack.config.js的output中加上:publicPath:'dist/'
	
  file-loader会用hash值命名图片,若需求希望打包后的文件有一定的规范:
  希望放在img文件夹中,原来文件名+hash的前8位+文件类型
  (为什么不直接用文件名字,在实际开发中项目中可能存在相同名字的图片被同时加载到img文件夹)

  操作:options中加上:name:'img/[name].[hash:8].[ext]'
2.5.4 ES6代码转为ES5代码

1.npm install --save-dev babel-loader@7 babel-core babel-preset-es2015

2.{test:/.js$/, exclude:/(node_modules|bower_components)/,use:{loader:'babel-loader',options:{presets:['es2015']}}}

2.6 配置vue环境

  1.npm install --save vue //安装运行时依赖,非开发时依赖!

  2.导入vue: import Vue from 'vue' 

  再运行 :npm run build 可能会报错

  原因:在使用vue的文件中存在 const app = new Vue({}),会被当作编译template,而runtime-only 版本不支持template

  解决方法:使用 runtime-compiler 的vue版本。

  操作:在webpack.config.js中配置中加入 resolve:{alias:{'vue$':'vue/dist/vue.esm.js'}}

  原理:将import Vue from 'vue'中的vue引入了另一个文件,vue.esm.js相当于使用runtime-compile
打包.vue文件
  1.npm install vue-loader vue-template-compiler --save-dev

  2.{test:/\.vue$/,user:['vue-loader']}

  打包时可能报错:vue-loader 缺少一个插件,14版本上的webpack需要配置一个插件

  解决方法:在package.json中修改 'vue-loader':'^13.0.0' 版本限制在13-14间,再执行 npm install

怎么省略输入文件类型?
在webpack.config.js的module.export中加入:

resolve:{//用来解决路径问题
      "extensions":['.js','.css','.vue']
      }

2.7 plugin 插件的使用

步骤一:通过npm安转需要应用的插件

步骤二:在webpack.config.js中的plugins中配置插件

loader和plugin区别:loader像一个加载器、转换器;plugin是一个扩展器。

plugin常用的有:给js添加一个版权声明,代码压缩(丑化)

·版权声明操作:

在webpack.config.js文件中

const path = require('path')
const webpack = require('webpack')
module.exports = {
	entry:'./src/main.js',
	output:{
	//__dirname 为node中上下文全局变量,值为当前路径,
	//path.resolve 进行路径拼接
	path:path.resolve(__dirname,'dist'),
	filename:'bundle.js'
	},
	mode:'development',
	resolve:{//用来解决路径问题
		"extensions":['.js','.css','.vue']
	},
	plugins:[
		new webpack.BannerPlugin('我的版权')
		]
}

·打包html的plugin

真实发布项目时,发布的dist文件夹中的内容需要index.html文件

执行:npm install html-webpack-plugin --save-dev
const HtmlWebpackPlugin = require(html-webpack-plugin)
--------------------------------------------------
plugins:[
	new HtmlWebpackPlugin(
	{template:'index.html'})//根据模板生成index.html
] 
  打包成功后会在dist文件夹下生成index.html文件

  文件中自动加入 <script type='text/javascript' src='dist/bundle.js'>

  这里存在一个问题:此时的bundle.js是和index.html同级的,所以我们需要去掉 配置文件中的publicPath

·js压缩

操作:npm uglifyjs-webpack-plugin@1.1.1 --save-dev //版本 一般采纳于后面使用的脚手架

const Uglify = require('uglifyjs-webpack-plugin')
--------------------------------------------------
new Ugligy()

2.8 webpack-dev-server 搭建本地服务器

  执行:npm install --save-dev webpack-dev-server@2.9.3 //版本和webpack有对应的关系的

在webpack.config.js中:

     devServer:{
	      contentBase:'./dist' , //服务的文件夹
	      inline:true ,		//是否实时更新
	      /*port:8080 ,*/
	      /*historyApiFallback*/
      }
  终端中执行指令:./node_modules/.bin/webpack-dev-server	

  也可以在 package.json中scripts中加入‘dev’:'webpack-dev-server',这样在终端可以:npm run dev

  如何自动打开浏览器呢? 
  修改:‘dev’:'webpack-dev-server --open'

2.9 配置文件抽离

需求:有些配置开发时需要,有些配置运行时需要,若写在一起就很混乱

建立文件夹/文件:

  • build:
    * base.config.js
    * prod.config.js
    * dev.config.js //分别公共 生产 开发

抽离webpack.config.js(下面仅为部分示例)

dev.config.js:

module.exports:{
      devSevers:{
      contentBase:'./dist' , //服务的文件夹
      inline:true 
      }
}

prod.config.js:

const Uglify = requrie('uglifyjs-webpack-plugin')
	module.exports:{
	      plugins:[new Ugligy()]
	}

为了配置文件合并,需要安装 webpack-merge:
npm install webpack-merge --save-dev

操作:在prod.config.js文件中:

const webpackMerge = require('webpack-merge')
const Uglify = requrie('uglifyjs-webpack-plugin')
const baseConfig = requrie('./base.config')
module.exports= webpackMerge(baseConfig,{
		plugins:[new Ugligy()]
		}

一切完成,还需要在package.json中 修改

'build':'webpack --config ./build/prod.config.js'

'dev':'webpack-dev-server --open --config ./build/dev.config.js'

再打包后会出问题,最初设置是当前路径下(配置文件所在的路径)的dist文件夹保存打包后的文件。
现在要修改成:

module.exports = {
	 entry:'./src/main.js',
	 output:{
	 	path:path.resolve(__dirname,'../dist'),//这里稍微改下
	 	filename:'bundle.js'
		}
	}

三、Vue CLI 的使用

CLI

  Command-line-interface 俗称为脚手架

作用

  搭建Vue 的开发环境,和配置webpack

安装

  npm instal -g @vue/cli //脚手架3的安转形式

项目创建

  脚手架3创建项目:vue create my-project

  如果需要按照Vue CLI 2初始化
  拉取2 的版本 npm install @vue-cli-init -g
	
  脚手架2创建项目:vue init webpack my-project

脚手架2配置说明

vue-cli2配置图

  1. vue init webpack
  2. 项目名
  3. 项目描述
  4. 作者
  5. 运行环境
  6. 是否安装 vue-router
  7. 是否使用ESLint (js规范)
    是:选择标准的,还是airbnd公司,还是自定义
  8. 是否下载单元测试
  9. 是否下载端到端测试
    它会使用selenium 进行测试,它可以操作浏览器
  10. 后面项目采用npm、yarn或自定义安装

四、Vue 代码优化

4.1 runtime-compile 版本

  流程:
  template --解析-->ast(抽象语法树) --编译-->
  render---->Viturl DOM-->UI

4.2 runtime-only 版本

  流程:
  render---->Viturl DOM-->UI
  优点:
  1.性能更高;2.代码更少.

4.3 vue实例对象:render

createElenment 函数

作用
  创建一个标签
使用
const cpn={
	template:`<div>{{message}}</div>`,
	data(){
            return {'message':'组件'}
	}
}
new Vue({
	el:'#app',
	//render 中创建的组件会替代#app
	render:function(createElement){
		//1.普通用法:createElement(标签,{标签的属性},[''])
		//return createElement('h2',{class:'box'},['hello world',createElement()])
		//2.传入组件
		//return createElement(cpn)
		//3.传入vue文件中的组件
		return createElement(app)
	}
	--------------------------------------------------
})
//.vue 文件中的template是由谁处理的呢?
//由vue-template-compiler 解析为了render函数
//vue-template-compiler为开发时依赖,也就是在生产环境中没有template了。

简写

new Vue({
	el:'#app',
	render:h=>h('app')
})
--------------------------------------------------
new Vue({
	render:h=>h('app')
}).$mount('#app')

五、参考链接

vue.js基础语法官方网站

六、学习视频

vue.js-vue-Vue-VUE2.X-VUE3.0-github

七、总结

首先特别感谢王红元老师的开源精神,和把视频搬到B站那位朋友。王老师讲的很好,面面俱到,这也就激发了我做笔记的冲动,起初是用.txt做的,后面就觉得不对劲了.txt没有结构,笔记多了后回过头自己都不愿意看自己写的笔记。我就转向了早有耳闻的markdwon,结果就爱上了,哈哈哈!越写越兴奋,结果就是在一个.md文件中写了1000多行,vue的技术点还有很多,但我想把这篇笔记做为我第一篇博客发布,再长估计就没人愿意看了,也不太符合博客短而精的特点,所以就到这里结束啦!
ps:vue挺有意思的,和我以前学的微信小程序有很多共同点,让人不经感慨:相见恨晚。
(博客园和Hbuilder X 上面的markdown排版不同,啊啊啊啊!)

有人完全根据视频做了些笔记,这里记录一下他的链接,以供参考:

  1. vue所有基础语法
  2. vuex核心内容及重点细节总结
  3. vue cli2 ,3详解
  4. vue router全面详细知识点
  5. axios框架核心知识
posted @ 2020-11-22 23:07  鲤鱼的探险历程  阅读(119)  评论(0)    收藏  举报