vue基础

Vue

vue概述

渐进式JavaScript框架

声明式渲染–>组件系统–>客户端路由–>集中式状态管理–>项目搭建

官网:https://cn.vuejs.org/v2/guide/

vue基本使用

1.需要提供标签用于填充数据

2.引入vue.js库文件

3.可以使用vue的语法做功能了

4.把vue提供的数据填充到标签里面

实例参数分析:

el:元素的挂载位置(值可以是css选择器或者DOM元素)

data:模拟数据(值是一个对象)

methods:定义方法函数

插值表达式用法:

将数据填充到HTML标签中

插值表达式支持基本的计算操作

vue代码运行原理分析:

概述编程过程的概念(vue语法–>原生语法)

vue模板语法

概述

前端渲染方式

原生js拼接字符串

使用前端模板引擎

使用vue特有的模板语法

模板语法概览

差值表达式

指令

概念:本质就是自定义属性

格式:以v-开始(比如:v-cloak)

v-cloak指令用法

插值表达式存在的问题:“闪动”

使用v-cloak指令 原理是 先隐藏,替换好值之后再显示最终的值

数据绑定指令

v-text 填充纯文本

v-html 填充HTML片段

v-pre 填充原始信息

数据响应式

概念:数据的变化导致页面内容的变化

数据绑定:将数据填充到标签中

v-once 只编译一次 显示内容后不再具有响应式功能

双向数据绑定

v-model 指令用法:

<input type="text" v-model="uname"/>

事件绑定

v-on指令用法

<input type="button" v-on:click='num++'/>

v-on简写形式

<input type="button" @click='num++'/>

函数事件的调用方式

直接绑定函数名称

<button v-on:click='say'>hello</button>

调用函数

<button v-on:click='say()'>say hi</button>

事件函数参数传递

普通参数和事件对象

<button v-on:click='say("hi",$event)'>Say hi</button>

1.如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数

2.如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递,并且事件对象的名称必须是$event

事件修饰符

.stop 阻止冒泡

.prevent 阻止默认行为

按键修饰符

.enter 回车键

<input v-on:keyup.enter='submit'>

.delete 删除键

<input v-on:keyup.delete='handle'>

自定义按键修饰符

全局config.keyCodes对象

Vue.config.keyCodes.f1 = 112

自定义按键修饰符名字是自定义的,但是对应的值必须是按键对应event.keyCode值

属性绑定

v-bind 指令用法

<a v-bind:href='url'>跳转</a>

缩写形式

<a :href='url'>跳转</a>

v-model得底层实现原理分析

<input v-bind:value="msg" v-on:input="msg=$event.target.value">

样式绑定

class样式处理

<div v-bind:class="{ active: isActive }"></div>

数组语法

`<div v-bind:class="[aciveClass, errorClass]"></div>`

1.对象绑定和数组绑定可以结合使用

2.class绑定得值可以简化操作

3.默认得class会保留

style样式处理

对象语法

<div v-bind:style="{ color: activeColor,fontSize: fontSize}"></div>

数组语法

<div v-bind:style="]baseStyles, overrideingStyles"></div>

分支循环结构

分支结构

v-if

v-else

v-else-if

v-show

v-if与v-show的区别

v-if控制元素是否渲染到页面

v-show控制元素是否显示(已经渲染到了页面)

循环结构

v-for遍历数组

`<li v-for='item in list'>{{item}}</li>`

`<li v-for='(item,index) in list'>{{item}} + '---' +{{index}}</li> `

`<div v-for='(value,key,index) in object'></div>`

v-if 和 v-for结合使用

<div v-if='value==12' v-for='(value,key,index) in object'></div>

key的作用:帮助Vue区分不同的元素,从而提高性能

<li :key='item.id' v-for='(item,index) in list'>{{item}} + '---' {{index}}</li>

Vue常用特性

表单操作

表单域修饰符

number:转化为数值

trim:去掉开始和结尾的空格

tazy:将input事件切换为xhange事件

<input v-model.number="age" type="number">
自定义指令

语法:

`Vue.directive('focus', {inserted:function(el) { `

`//获取元素的焦点 `

`el.focus();`

`}})`

用法:

<input type="text" v-focus>

带参数的自定义指令(改变元素的背景色)

`Vue.directive('color',{`

`inserted: function(el, binding) {`

`el.style.backgroundColor = binding.value.color;}`

`})`

指令的用法:

<input type="text" v-color='{color:"orange"}'>

局部指令

`directives: {`

`	focus: {`	

`		//指令的定义`		

`	inserted: function (el) {`	

`	el.focus()`

`}}}`
计算属性

表达式的计算逻辑可能会比较复杂,使用计算属性可以使模板内容更加简洁

用法:

`computed: {`

`reversedMesssage: function () {`

`return this.msg.split('').reverse().join('')`

`}}`

计算属性与方法的区别

1.计算属性是基于它们的依赖进行缓存的

2.方法不存在缓存

过滤器

作用:格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定的格式等

Vue.filter('过滤器名称', function(value){
	//过滤业务逻辑
})

过滤器的使用

<div>
    {{msg | upper}}
</div>
<div>
    {{msg | upper | lower}}
</div>
<div v-bind:id="id | formatId">
</div>

局部过滤器

filters: {
	capitalize: function(){}
}

带参数的过滤器

Vue.filter('format', function(value,argl){
	//value就是过滤器传递过来的参数
})
侦听器

数据变化时执行异步或开销较大的操作

用法:

watch: {
	firstName: function(val){
		//val表示变化之后的值
		this.fullName = val + this.lastName;
	},
	lastName: funcion(val) {
		this.fullName = this.firstName + val;
	}
}
生命周期

主要阶段

1.挂载(初始化相关属性)

beforeCreate

在实例初始化之后,数据观测和事件匹配之前被调用

created

在实例创建完成后被立即调用

beforeMount

在挂载开始之前被调用

mounted

el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子

2.更新(元素或组件的变更操作)

beforeUpdate

数据更新时调用,发生在虚拟DOM打补丁之前

updated

由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子

3.销毁(销毁相关属性)

beforeDestroy

实例销毁之前调用

destroyed

实例销毁之后调用

补充

变异方法(修改原有数据)

push() pop() shift() unshift() splice() sort() reverse()

替换数组(生成新的数组)

filter() concat() slice()

修改响应式数据

Vue.set(vm.items,indexOfltem,newValue)

vm.$set(vm.items,indexofltem,newValue)

参数一表示要处理的数组的名称

参数二表示要处理的数组的索引

参数三表示要处理的数组的值

图书管理案例

常用特性应用场景

过滤器(格式化日期)

自定义指令(获取表单焦点)

计算属性(统计图书数量)

侦听器(验证图书存在性)

生命周期(图书数据处理)

vue组件化开发

组件化思想的体现

标准 分治 重用 组合

组件化规范:Web Components

我们希望尽可能多的重用代码

自定义组件的方式不太容易

多次使用组件可能导致冲突

Web Components通过创建分装好功能的定制元素解决上述问题

组件注册
Vue.comonent(组件名称, {
	data:组件数据,
	template:组件模板内容
})
//定义一个名为button-counter的新组件
Vue.component('button-counter',{
	data:function(){
		return {
		count:0
		}
	},
	template:'<button v-on:click="count++">点击了{{count}}次.</button>'
})
组件用法
<div id="app">
    <button-counter></button-counter>
</div>
<div id="app">
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
</div>
组件注册注意事项

1.data必须是一个函数

分析函数与普通对象的对比

2.组件模板内容必须是单个跟元素

分析演示实际的效果

3.组件模板内容可以是模板字符串

模板字符串需要浏览器提供支持

4.组件的命名方式

短横线式 驼峰式

如果使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板中用驼峰的方式使用组件,但是在普通的标签模板中,必须使用短横线的方式使用组件

局部组件注册
var ComponentA = {/*...*/}
var ComponentB = {/*...*/}
var ComponentC = {/*...*/}
new Vue({
	el:'#app'
	components: {
		'component-a': ComponentA,
		'component-b': ComponentB,
		'component-c': ComponentC,
	}
})
Vue调试工具

工具安装

1.克隆仓库

2.安装依赖包

3.构建

4.打开Chrome扩展页面

5.选中开发者模式

6.加载已解压的扩展,选择shells/chrome

组件间数据交互

父组件向子组件传值

1.组件内部通过props接受传递过来的值

Vue.component('menu-item', {
	props: {'title'},
	template: '<div>{{title}}</div>'
})

2.父组件通过属性将值传递给子组件

<menu-item title="来自父组件的数据"></menu-item>
<menu-item :title="title"></menu-item>

3.props属性名规则

在props中使用驼峰形式,模板中需要使用短横线的形式

字符串形式的模板中没有这个限制

Vue.component('menu-item', {
	//在javaScript中是驼峰式的
	props: {'menuTitle'},
	template: '<div>{{menuTitle}}</div>'
})
<--在html中是短横线方式的-->
<menu-item menu-title="nihao"></menu-item>

4.props属性值类型

字符串String

数值Number

布尔型Boolean

数组Array

对象Object

子组件向父组件传值

1.子组件通过自定义事件向父组件传递信息

<button v-on:click='$emit("enlarge-text")'>
    扩大字体
</button>

2.父组件监听子组件的事件

<menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>

3.子组件通过自定义事件向父组件传递信息

<button v-on:click='$emit("enlarge-text",0.1)'>
    扩大字体
</button>

4.父组件监听子组件的事件

<menu-item v-on:enlarge-text='fontSize += $event'></menu-item>

非子父组件间传值

单独的事件中心管理组件间的通信

var eventHub = new Vue()

监听事件与销毁事件

eventHub.$on('add-todo',addTodo)
eventHub.$off('add-todo')

触发事件

eventHub.$emit('add-todo',id)
组件插槽

作用

父组件向子组件传递内容

1.插槽位置

Vue.component('alert-box', {
	template:'
		<div class="demo-alert-box">
			<strong>Error!</strong>
			<slot></slot>
		</div>
	'
})

2,插槽内容

<alert-box>Something bad happened.</alert-box>

3.具名插槽用法

插槽定义

<div class="container">
    <header>
        <slot name="header"></slot>
    </header>
    <main>
        <slot></slot>
    </main>
    <footer>
        <slot name="footer"></slot>
    </footer>
</div>

插槽内容

<base-layout>
    <h1 slot="header">
        标题内容
    </h1>
    <p>
        主要内容
    </p>
    <p>
        主要内容
    </p>
    <p slot="footer">
        底部内容
    </p>
</base-layout>

4.作用域插槽

应用场景父组件对子组件的内容进行加工处理

插槽定义

<ul>
    <li v-for="item in list" v-bind:key="item.id">
        <slot v-bind:item="item">
            {{item.name}}
        </slot>
    </li>
</ul>

插槽内容:

<fruit-list v-bind:list="list">
	<template slot-scope="slotProps">
    	<strong v-if="slotProps.item.current">      			{{slotProps.item.text}}
        </strong>
    </template>
</fruit-list>

前后交互

前后端交互模式

接口调用方式

原生ajax , fetch , axios

Promise用法

异步调用

定时任务

Ajax

事件函数

多次一部调用的依赖分析:

多次异步调用的结果顺序不确定

异步调用结果如果存在依赖需要嵌套

$.ajax({
success:function(data){
	if(data.status == 200){
		$.ajax({
			success:.function(data){
				if(data.status == 200){
					$.ajax({
						success.function(data){
							if(data.status == 200){}
						}
					})
				}
			}
		})
	}
}
})
Promise用法

概述:

promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获得异步操作的消息

使用其有以下好处:

1.可以避免多层异步调用嵌套问题(回调地狱)

2.Promise对象提供了简洁的API,使得控制异步操作更加容易

官网:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Promise

Promise基本用法:

实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务

resolvereject两个参数用于处理成功和失败两种情况,并通过p.then获取处理结果

var p = new Promise(function(resolve,reject){
	//成功时调用resolve()
	//失败时调用reject()
});
p.then(function(ret){
	//从resolve得到正常结果
}function(ret){
	//从reject得到错误信息
})
基于Promise处理Ajax请求

处理原生

function queryData(){
	return new Promise(function(resolve,reject){
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function(){
	if(xhr.readyState != 4) return;
	if(xhr.status == 200){
		reslove(xhr.responseText)
	}else{{
		reject('出错了');
		}
	}
	xhr.open('get','/data');
	xhr.send(null);
	})
}

发送多次ajax请求

queryData()
.then(function(data){
	return queryData();
})
.then(function(data){
	return queryData();
})
.then(function(data){
	return queryData();
});

then参数中的函数返回值

1.返回Promise实例对象

​ 返回的该实例对象会调用下一个then

2.返回普通值

​ 返回的普通值会直接传递给下一个then,通过then参数中函数接受该值

Promise常用的API

1.实例方法

p.then() 得到异步任务的正确结果

p.catch() 获取异常信息

p.finally() 成功与否都会执行(尚且不是正式标准)

queryData()
.then(function(data){
	console.log(data);
})
.catch(function(data){
	console.log(data);
})
.finally(function(){
	console.log('finished');
});

2.对象方法

Promise.all() 并发处理多个异步任务,所有任务都执行完成才能得到结果

Promise.race() 并发处理多个异步任务,只要有一个任务完成就能得到结果

Promise.all([p1,p2,p3]).then((result) => {
    console.log(result)
})

Promise.race([p1,p2,p3]).then((result) => {
    console.log(result)
})
接口调用-fetch用法

更加简单的数据获取方式,功能更加强大,更灵活,可以看作事xhr的升级版

基于Promise实现

fetch(url).then(fn2)
		  .then(fn3)
 		  ...
          .catch(fn)

官网:https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

fetch的基本用法
fetch('/abc').then(data=>{
    return data.text();
}).then(ret=>{
    //注意这里得到的才是最终的数据
    console.log(ret);
});
fetch请求参数

常用配置选项

method(String):HTTP请求方法,默认为GET(GET,POST,PUT,DELETE)

body(String):HTTP的请求参数

headers(Object):HTTP的请求头,默认为{}

fetch('/abc',{
    method:'get'
}).then(data=>{
    return data.text();
}).then(ret=>{
    //注意这里得到的才是最终的数据
    console.log(ret);
});

2.GET请求方式的参数传递

fetch('/abc?id=123').then(data=>{
    return data.text();
}).then(ret=>{
    //注意这里得到的才是最终的数据
    console.log(ret);
});
fetch('/abc/123',{
    method:'get'
}).then(data=>{
    return data.text();
}).then(ret=>{
    //注意这里得到的才是最终的数据
    console.log(ret);
});

3.DELETE请求方式的参数传递

fetch('/abc/123',{
    method:'delete'
}).then(data=>{
    return data.text();
}).then(ret=>{
    //注意这里得到的才是最终的数据
    console.log(ret);
});

4.POST请求方式的参数传递

fetch('/books',{
    method:'post',
    body:'uname=listi&pwd=123',
    headers:{
        'Content-Type':'application/x-www-form-urlencoded',
    }
}).then(data=>{
    return data.text();
}).then(ret=>{
    console.log(ret);
});
fetch('/books',{
    method:'post',
    body:JSON.stringify({
        uname:'list',
        age:12
    })
    headers:{
    	'Content-Type':'application/json',
	}
}).then(data=>{
    return data.text();
}).then(ret=>{
    console.log(ret);
});

5.PUT请求方式的参数传递

fetch('/books/123',{
    method:'put',
    body:JSON。stringify({
        uname:'list',
        age:12
    })
    headers:{
    	'Content-Type':'application/json',
	}
}).then(data=>{
    return data.text();
}).then(ret=>{
    console.log(ret);
});
fetch响应结果

响应数据格式

text() :将返回体处理成字符串类型

json() : 返回结果和JSON.parse(responseText)一样

fetch('/abc'then(data=>{
      //return data.text();
      return data.json();
}).then(ret=>{
    console.log(ret);
});
接口调用-axios用法
axios的基本特性

官网:https://github.com/axios/axios

axios是一个基于Promise用于浏览器和node.js的HTTP客户端

它具有如下特性:

1.支持浏览器和node.js

2.支持promise

3.能拦截请求和响应

4.自动转换JSON数据

axios.get('/adata')
	.then(ret=>{
    	//data属性名称是固定的,用于获取后台响应数据
    	console.log(ret.data)
	})
axios的常用API

get:查询数据

post:添加数据

put:修改数据

delete:删除数据

axios的参数传递

GET传递参数

通过URL传递参数

通过params选项传递参数

axios.get('/adata?id=123')
	.then(ret=>{
    	console.log(ret.data)
	})
axios.get('/adata/123')
	.then(ret=>{
    	console.log(ret.data)
	})
axios.get('/adata',{
	params:{
		id:123
	}
})
.then(ret=>{
    console.log(ret.data)
})

DELETE传递参数

参数传递方式于GET类似

axios.delete('/adata?id=123')
	.then(ret=>{
    	console.log(ret.data	)
	})
axios.delete('/adata/123')
	.then(ret=>{
    	console.log(ret.data)
	})
axios.delete('/adata',{
    params:{
        id:123
    }
})
.then(ret=>{
      console.log(ret.data)
})

POST传递参数

通过选项传递参数(默认传递的是json格式的数据)

axios.post('/adata',{
    uname:'tom',
    pwd:123
}).then(ret=>{
    console.log(ret.data)
})

通过URLSearchParams传递参数(applikcation/x-www-form-urlencoded)

const params = new URLSearchParams();
params.append('param1','value1');
params.append('param2','value2');
axios.post('/api/test',params).then(ret=>{
    console.log(ret.data)
})

PUT传递参数

参数传递方式与POST类似

axios.put('/adata/123',{
    uname:'tom',
    pwd:123
}).then(ret=>{
    console.log(ret.data)
})
axios的响应结果

响应结果的主要属性

data:实际响应回来的数据

headers:响应头信息

status:响应状态码

statusText:响应状态信息

axios.post('/axios-json').then(ret=>{
    console.log(ret)
})
axios的全局配置

axios.defaults.timeout = 3000; //超时时间

axios.defaults.baseURL = ‘http://localhost:3000/app’; //默认地址

axios.defaults.headers[‘mytoken’] = ‘apwerwqwerqwer23eresdf23’ //设置请求头

axios拦截器

请求拦截器

在请求发出之前设置一些信息

//添加一个请求拦截器
axios.interceptors.request.use(function(config){
    //在请求发出之前进行一些信息设置
    return config;
},function(err){
    //处理响应的错误信息
})

响应拦截器

在获取数据之前对数据做一些加工处理

//添加一个响应拦截器
axios.interceptors.response.use(function(res){
    //在这里对返回的数据进行处理
    return res;
},function(err){
    //处理响应的错误信息
})
接口调用-async/await用法(重点)
async/await的基本用法

async/await是ES7引入的新语法,可以更加方便的进行异步操作

async关键子用于函数上(async函数的返回值是Promise实例对象)

await关键字用于async函数当中(await可以得到异步的结果)

async function queryData(id){
    const ret = await axios.get('/data');
    return ret;
}
queryData.then(ret=>{
    console.log(ret)
})
async/await处理多个异步请求
async function queryData(id){
    const info = await axios.get('/asyncl');
	const ret = await axios.get('async2?info='+info.data);
    return ret;
}
queryData.then(ret=>{
    console.log(ret)
})

前端路由

路由:路由的本质就是对应关系

后端路由:根据不同用户的URL请求,返回不同的内容,本质就是URL地址与服务器之间的对应关系

前端路由:根据不同的用户事件,显示不同的页面内容,本质就是用户事件处理函数之间的对应关系

实现简单的前端路由
//监听window的onhashchange事件,过呢据获取到的最新的hash值,切换要显示的组件的名称
window.onhashchange = function(){
    //通过location.hash获取到最新的hash值
}
Vue Router

官网:https://router.vuejs.org/zh/ 是vue.js官方的路由管理器它和Vue.js的核心深度集成,可以非常方便的用于SPA应用程序的开发

Vue Router包含的功能:

1.支持HTMLS历史模式或hash模式

2.支持嵌套路由

3.支持路由参数

4.支持编程式路由

5.支持命名路由

Vue rRouter 的基本使用
引入相关的库文件
<!--导入vue文件,为全局window对象挂载Vue构造函数-->
<script src="./lib/vue_2.5.22.js"></script>
<!--导入vue-router文件,为全局window对象挂载VueRouter构造函数-->
<script src="./lib/vue-router_3.0.2.js"></script>
添加路由链接
<!--router-link 是 vue中提供的标签,默认会被渲染为a标签-->
<!--to 属性默认会被渲染为href属性-->
<!--to 属性的值默认会被渲染为#开头的hash地址-->
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
添加路由填充位
<!--路由填充位(也叫作路由占位符) -->
<!--将来通过路由规则匹配到的组件,将会被渲染到 router-view 所在的位置-->
<router-view></router-view>
配置路由规则并创建路由实例
//创建路由实例对象
var router = new VueTouter({
    //router是路由规则数组
    router:[
        //每一个路由规则都是一个配置对象,其中至少包含hash 和 component两个属性:
        //path表示当前路由规则匹配的hash地址
        //component表示当前路由规则对应要展示的组件
        {path:'/user',component:User},
        {path:'/register',component:Register}
    ]
})
把路由挂载到Vue根实例中
new Vue({
    el:'#app',
    //为了能够让路由规则生效,必须把路由对象挂载到vue实例对象上
    router  //router:router
});
路由重定向

路由重定向指的是:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面;

通过路由规则的redirect属性,指定一个新的路由地址,可以很方便地设置路由地重定向;

var router = new VueRouter({
    routers: [
        //其中,path表示需要被重定向地原地址,redirect表示将要被重定向到地新地址
        {path:'/',redirect:'/user'},
        {path:'/user',componenet:User},
        {path:'/register',component:Register}
    ]
})
vue-router嵌套路由

嵌套路由功能分析:

1.点击父级路由链接显示模板内容

2.模板内容中又有子级路由链接

3.点击子级路由链接显示子级模板内容

嵌套路由用法

父路由组件模板

父级路由链接

父组件路由填充位

<p>
    <router-link to="/user">User</router-link>
    <router-link to="/register">Register</router-link>
</p>
<div>
    <!--控制组件的显示位置-->
    <router-view></router-view>
</div>

子级路由模板

子级路由链接

子级路由填充位

const Register = {
    template:<div>
    <h1>Register 组件</h1>
    <hr/>
    <router-link to="/register/tab1">Tab1</router-link>
    <router-link to="/register/tab2">Tab2</router-link>
    
    <!--子路由填充位-->
    <router-view/>
   </div>
}

嵌套路由配置

父级路由通过children属性配置子级路由

const router = new VueRouter({
    routes: [
        {path:'/user',component:User},
        {
            path:'/register',
            component:Register,
            //通过children属性,为/register添加子路由规划
            children: [
                {path:'/register/tab1',component:Tab1},
                {path:'/register/tab2',component:Tab2}
            ]
        }
    ]
})
vue-router动态路由匹配
动态匹配路由的基本用法

思考:

<!--有如下3个路由链接-->
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
{path:'/user/1',component:User}
{path:'/user/2',component:User}{path:'/user/3',component:User}

应用场景:通过动态路由参数的模式进行路由匹配

var router = new VueRouter({
    routes: [
        //动态路径参数 以冒号开头
        {path:'/user/:id',component:User}
    ]
})
const User = {
    //路由组件中通过$route.params获取路由参数
    template:'<div>User{{$route.params.id}}</div>'
}
路由组件传递参数

$route与对应路由形成高度耦合,不够灵活,所以可以使用props将组件和路由解耦

1.props的值为布尔类型

const router = new VueRouter({
 	routes:[
        //如果props被设置为true.route.params将会被设置为组件属性
        {path:'/user/:id',component:User,props:true}
    ]   
})

const User = {
    props:['id'],//使用props接收路由参数
    template:'<div>用户ID:{{id}}</div>'//使用路由参数
}

2.props的值为对象类型

const router = new VueRouter({
    routes:[
        //如果props是一个对象,它会被按原样设置为组件属性
        {path:'/user/:id',component:User,props:{uname:'list',age:12}}
    ]
})

const User = {
    props:['uname','age'],
    template:'<div>用户信息:{{uname + '----' + age}}</div>'
}

3.props的值为函数类型

const router = new VueRouter({
    routes:[
        //如果props是一个函数,则这个函数接收route对象为自己的形参
        { path:'/user/:id',
          component:User,
          props:route => ({uanme:'zs',age:20,id:route.params.id})}
   ]
})

const User = {
    props:['uname','age','id'],
    template:'<div>用户信息{{uname + '-----' + 'id'}}</div>'
}
vue-router命名路由
命名路由的配置规则

为了更加方便地表示路由的路径,可以给路由规则起一个别名,即为“命名路由”。

const router = new VueRouter({
    routes: [
       {
            path:'/user/:id',
        	name:'user',
        	component:User
       }
    ]
})
<router-link :to="{name:'user',params:{id:123}}">User</router-link>
router.push({name:'user',params:{id:123}})
vue-router编程时导航
页面导航的两种方式

声明式导航:通过点击链接实现导航的方式,叫做声明式导航

例如:普通网页中的链接或者vue中的

编程式导航:通过调用JavaScript形式的API实现导航的方式,叫做编程式导航

例如:普通网页中的location.href

编程式导航基本用法

常用的编程式导航API如下:

this.$router.push(‘hash地址’)

this.$router.go(n)

const User = {
    template:'<div><button @click="goRegister">跳转到注册页面<button></div>',
    method:{
        goRegister:function(){
            //用编程的方式控制路由跳转
            this.$router.push('/register');
        }
    }
}
编程式导航参数规则

router.push()方法的参数规则

//字符串(路径名称)
router.push('/home')
//对象
router.push({path:'/home'})
//命名的路由(传递参数)
router.push({name:'/user',params:{userId:123}})
//帮查询参数,变成 /register?uname=lisi
router.push({path:'/register',query:{uname:'lisi'}})

前端工程化

传统开发主要问题:
1.命名冲突 2.文件依赖

通过模块化解决上述问题

模块化就是把单独的一个功能封装到一个模块(文件)中,模块之间相互隔离,但是可以通过特定的接口公开内部成员,也可以依赖别的模块

模块化开发的好处:方便代码的重用,从而提升开发效率,并且方便后期的维护

模块化相关规范
浏览器端模块化规范

1.AMD

Requier.js (http://www.requirejs.cn/)

2.CMD

Sea.js (htttps://seajs.github.io/seajs/docs/)

服务器端模块化规范

1.CommonJS

模块分为单文件

模块成员导出:module.exportsexports

模块成员导入:require(‘模块标识符’)

大一统的模块化规范-ES6模块化

在ES6模块化规范诞生之前,Javascript社区已经尝试并提出了AMD,CMD,CommonJS,等模块化规范

但是,这些社区提出的模块化标准,还是存在一定的差异性局限性,并不是浏览器与服务器通用的模块化标准,例如:

AMD和CMD适用于浏览器端的Javascript模块化

CommonJS适用于服务器的JavaScript模块化

因此,ES6语法规范中,在语言层面上定义了ES6模块化规范,是浏览器端与服务器端通用的模块化开发规范

ES6模块化规范中定义:

每个js文件都是一个独立的模块

导入模块成员使用import关键字

暴露模块成员使用export关键字

Node.js中通过babel体验ES6模块化

1.npm install --save-dev @babel/core @babel/cli @ba el/preset-env @babel/node

2.npm install --save @babel/polyfill

3.项目根目录创建文件babel.config.js

4.babel.config.js文件内容如下代码

const presets = {
    ["@babel/env",{
        targets:{
            edge:'17',
            firefox:'60',
            chrome:'67',
            safari:'11.1'
        }
    }]
};
module.exports = {presets};
ES6模块化的基本语法
默认导出 与 默认导入

默认导出语法 export default默认导出的成员

//当前文件模块为m1.js

//定义私有成员a和c
let a = 10
let c = 20
//外界访问不到变量d,因为它没有被暴露出去
let d = 30
function show(){}

//将本模块中的私有成员暴露出去,供其他模块使用
export default {
    a,
    c,
    show
}

默认导入语法import接收名称from“模块标识符”

//导入模块成员
import m1 from "./m1.js"

console.log(m1)
//打印输出的结果为:
//{a:10,c:20,show:{Function:show}}

注意:每个模块中,只允许使用唯一的一次 export default,否则会报错!

按需导出 与 按需导入

按需导出语法 export let s1 = 10

按需导入语法 import {s1} from ‘模块标识符’

//当前文件模块为m1.js

//向外按需导出变量 s1
export let s1 = "aaa"
//向外按需导出变量 s2
export let s2 = "ccc"
//向外按需导出方法say
export function say = function(){}
//导入模块成员
import {s1,s2 as ss2,say} from './m1.js'

console.log(s1) //打印输出aaa
console.log(ss2) //打印输出ccc
console.log(say) //打印输出{Function:say}

注意:每个模块中,可以使用多次按需导出!

直接导入并执行模块代码

有时候,我们只想单纯执行某个模块中的代码,并不需要得到模块中向外暴露的成员,此时,可以直接导入并执行模块代码

//当前文件模块为m2.js

//在当前模块中执行一个for循环操作
for(let i = 0;i < 3;i++){
    console.log(i);
}
//直接导入并执行模块代码
import './m2.js'
webpack

webpack概述

webpack是一个流行的前端项目构建工具(打包工具),可以解决当前web开发中所面临的困境

webpack提供了友好的模块化支持,以及代码压缩混淆,处理js兼容问题,性能优化等强大的功能,从而让程序员把工作的重心放到具体的功能实现上,提供了开发效率和项目的可维护性

目前绝大多数企业中的前端项目,都是基于webpack进行打包构建的

webpack的基本使用

创建列表隔行变色项目

1.新建项目空白目录,并运行npm init -y命令,初始化包管理配置文件package.json

2.新建src源代码目录

3.新建src ->index.html首页

4.初始化首页基本的结构

5.运行npm install jquery -s 命名,安装jQuery

6.通过模块化的形式,实现列表隔行变色效果

在项目中安装和配置webpack

1.运行npm install webpack webpack-cli -D命令,安装webpack相关的包

2.在项目根目录中,创建名为webpack.config.js的webpack配置文件

3.在webpack的配置文件中初始化如下基本配置:

module.export = {
	mode:'development' //mode用来指定构建模式
}

4.在package.json配置文件中的scripts节点下,新增dev脚本如下:

"scripts":{
    "dev":"webpack" //script节点下的脚本,可以通过npm run 执行
}

5.在终端中运行npm run dev 命令,启动webpack进行项目打包

配置打包的入口与出口

webpack的4.x版本中默认约定:

打包的入口文件为src -> index.js

打包的输出文件为 dist -> main.js

如果要修改打包的入口与出口,可以在webpack.config.js中新增如下配置信息:

const path = require('path') //导入node.js中专门操作路径的模块
module.exports = {
    entry:path.join(__dirname,'./src/index.js'),//打包入口文件的路径
  output:{
      path:path.join(__dirname,'./dist'),//输出文件的存放路径
 filename:'bundle.js' //输出文件的名称
  }
}
配置webpack的自动打包功能

运行npm install webpack-dev-server -D命令,安装支持项目自动打包的工具

修改package.json -> scripts中的dev命令如下:

"scripts":{
    "dev":"webpack-dev-server" //script节点下的脚本,可以通过npm run执行
}

将src -> index.html中,script脚本的引用路径,修改为"/buldle.js"

运行npm run dev 命令,重新进行打包

在浏览器中访问http://localhost:8000 地址,查看自动打包效果

**注意:**webpack-dev-server 会启动一个实时打包的http服务器

webpack-dev-server打包生成的输出文件,默认放到了项目根目录中,而且是虚拟的,看不见的

配置html-webpack-plugin生成预览页面

运行npm install html-webpack-plugin -D命令,安装生成预览页面的插件

修改webpack.config.js文件头部区域,添加如下配置信息:

//导入生成预览页面的插件,得到一个构造函数
const HtmlWebpackPlugin = require('html-webpack-plugin')
const htmlPlugin = new HtmlWebpackPlugin({
    template:'./src/index.html',//指定要用到的模板文件
    filename:'index.html'//指定生成的文件的名称,该文件存在于内存中,在目录中不显示
})

修改webpack.config.js文件中向外暴露的配置对象,新增如下配置节点:

module.exports = {
    plugins:[htmlPlugin] //plugins数组是webpack打包期间会用到的一些插件列表
}
配置自动打包相关的参数
//package.json中的配置
//--open打包完成后自动打开浏览器页面
//--host配置IP地址
//--port配置端口
"scripts":{
    "dev":"webpack-dev-server --open --host 127.0.0.1 --port 0000"
},
webpack中的加载器
通过loader打包非模块

在实际开发中,webpack默认只能打包处理以 .js后缀名结尾的模块,其他非.js后缀名结尾的模块,webpack默认处理不了,需要调用loader加载器才可以正常打包,否则会报错

loader加载器可以协助webpack打包处理特定的文件模块比如:

1.less-loader可以打包处理.less相关的文件

2.sass-loader可以打包处理。scss相关的文件

3.url-loader可以打包处理css中与url路劲相关的文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

webpack中加载器的基本使用

1.打包处理css文件

运行npm i style-loader css-loader -D命令,安装处理css文件的loader

在webpack.config.js的module ->rules数组中,添加loader规则如下:

//所有第三方文件模块的匹配规则
module:{
    rules:{
        {text:/\.css$/,use:['style-loader','css-loader']}
    }
}

其中,test表示匹配的文件类型,use表示对应要调用的loader

**注意:**use数组中指定的loader顺序是固定的,多个loader的调用是:从后往前调用

打包处理less文件

运行npm i less-loader less -D命令

在webpack.config.js的module -> rules数组中,添加loader规则如下:

//所有第三方文件模块的匹配规则
module:{
    rules:{
        {test:/\.less$/,use:['style-loader','css-loader','less-loader']}
    }
}

打包处理scss文件

运行npm i sass-loader node-scss -D命令

在webpack.config.js的module -> rules数组中,添加loader规则如下:

//所有第三方文件模块的匹配规则
module:{
    rules:[
        {test:/\.scss$/,use:['style-loader','css-loader','sass-loader']}
    ]    
}
配置postCSS自动添加css的兼容前缀

运行mpm i postcss-loader autoprefixer -D命令

在项目根目录中创建postcss的配置文件postcss.config.js,并初始化如下配置:

const autoprefixer = require('autoprefixer')//导入自动添加前缀的插件
module.exports = {
    plugins:[autoprefixer]//挂载插件
}

在webpack.config.js的module -> rules 数组中,修改css的loader规则如下:

module:{
    rules:[
        {text:/\.css$/,use:['style-loader','css-loader','postcss-loader'}
    ]
}
打包样式表中的图片和字体文件

运行npm i url-loader file-loader -D命令

在webpack.config.js的module -> rules数组中,添加loader规则如下:

module:{
    rules:[
        {
            test:/\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
            use:'url-loader?limit=16940'
        }
    ]
}

其中?之后的是loader的参数项,

limit用来指定图片的大小,单位是字节,只有小于limit大小的图片,才会被转为base64图片

打包处理js文件中的高级语法

1.安装babel转换器相关的包:npm i babel-loader @babel/core @babel/runtime -D

2.安装babel语法插件相关的包:npm i @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D

3。在项目根目录中,创建babel配置文件 babel.config.js并初始化基本配置如下:

module.exports = {
    presets:{'@babel/preset-env'},
    plugins:{'@babel/plugin-transform-runtime','@babel/plugin-proposal-class-properties'}
}

4.在webpack.config.js的module -> rules数组中,添加loader规则如下:

//exclude为排除项,表示babel-loader不需要处理node_modules中的js文件
{test:/\.js$/,use:'babel-loader',exclude:/node_modules/}
Vue单文件组件
传统组件问题和解决方案

问题:

1.全局定义的组件必须保证组件的名称不重复

2.字符串模板缺乏语法高亮,在HTML有多行的时候,需要用到""转义

3.不支持CSS意味着当HTML和JavaScript组件化时,CSS明显被遗漏

4.没有构建步骤限制,只能使用HTML和ESS JavaScript,而不能使用预处理器(如:Babel)

解决方案:

针对传统组件的问题,Vue提供了一个解决方案—使用Vue单文件组件

单文件组件的组成结构

template:组件的模板区域**

script:业务逻辑区域

style:样式区域

<template>
    <!--这里用于定义Vue组件的模板内容-->
</template>

<script>
    //这里用于定义Vue组件的业务逻辑
    export default{
data:(){return {}},//私有数据
    methods:{}//处理函数
//...其他业务逻辑
}
<script>

<style scoped>
    /*这里用于定义组件的样式*/
</style>
webpack中配置vue组件的加载器

1.运行npm i vue-loader vue-template-compiler -D命令

2.在webpack.config.js配置文件中,添加vue-loader的配置项如下:

const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
    module:{
        rules:[
            //...其他规则
            {test:/\.vue$/,loader:'vue-loader'}
        ]
    },
 	plugins:[
        //...其他插件
        new VueLoaderPlugin()//请确保引入这个插件!
    ]
}
在webpack项目中使用vue

1.运行npm i vue -S安装vue

2.在src->index.js入口文件中,通过import Vue from 'vue’来导入vue构造函数

3.创建vue的实例对象,并指定要控制的el区域

4.通过render函数渲染App根组件

//1.导入Vue构造函数
import Vue from 'vue'
//2.导入App根组件
import App from './components/App.vue'

const vm = new Vue({
    //3.指定vm实例要控制的页面区域
    el:'#app',
    //4.通过render函数,把指定的组件渲染到el区域中
    render:h=>h(App)
})
webpack打包发布

上线之前需要通过webpack将应用进行整体的打包,可以通过package.json文件配置打包命令:

//在package.json文件中配置webpack打包命令
//该命令默认加载项目根目录中的webpack.config.js配置文件
"scripts":{
    //用于打包的命令
    "build":"webpack-p",
    //用于开发调试的命令
    "dev":"webpack-dev-server --open --host 127.0.0.1 --port 3000",
},

Vue脚手架

Vue脚手架的基本用法

Vue脚手架用于快速生成Vue项目基础架构,器官网地址为:https://cli.vuejs.org/zh/

使用步骤

1.安装3.x版本的Vue脚手架:

npm install -g @vue/cli

基于3.x版本的脚手架创建vue项目

//1.基于交互式命令行的方式,创建新版的vue项目
vue create my-project

//2.基于图形化界面的方式,创建新版vue项目
vue ui

//3.基于2.x的旧模板,创建旧办vue项目
npm install -g @vue/cli-init
vue init webpack my-project
//1.基于交互式命令行的方式,创建新版vue项目
vue create my-project

//2.基于图形化界面的方式,创建新版vue项目
vue ui

//3.基于2.x的旧模板,创建旧版vue项目
npm install -g @vue/cli-init
vue init webpack my-project
Vue脚手架生成的项目结构分析

node_modules 依赖包目录

public 静态资源目录

src 组件源码目录

babel.config.js Babel配置文件

Vue脚手架的自定义配置

1.通过package.json配置项目

//必须是符合规范的json语法
"vue":{
    "devserver"{
        "port":"0000",
        "open":true
    }
},

注意:不推荐使用这种配置方式,因为package.json主要用来管理包的配置信息;为了方便维护,推荐将vue脚手架相关的配置,单独定义到vue.config.js配置文件中。

2.通过单独的配置文件配置项目

1.在项目的根目录创建文件vue.config.js

2.在该文件中进行相关配置,从而覆盖默认配置

//vue.config.js
module.exports = {
    devServer:{
        port:0000
    }
}

Element-UI的基本使用

Element-UI:一套为开发者,设计师和产品经理准备的基于Vue 2.0的桌面端组件库

官网地址为:http://element-cn.eleme.io/#/zh-CN

1.基于命令行方式手动安装

1.安装依赖包npm i element-ui -S

2.导入Element-UI相关资源

//导入组件库
import ElementUI from 'element-ui';
//导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css';
//配置Vue插件
Vue.use(ElementUI);
基于图形化界面自动安装

1.运行vue ui 命令,打开图形化界面

2.通过Vue项目管理器,进入具体的项目配置面板

3.点击插件->添加插件,进入插件查询面板

4.搜索vue-cli-plugin-element并安装

5.配置插件,实现按需导入,从而减少打包后项目的体积

import Vue from 'vue’来导入vue构造函数

3.创建vue的实例对象,并指定要控制的el区域

4.通过render函数渲染App根组件

//1.导入Vue构造函数
import Vue from 'vue'
//2.导入App根组件
import App from './components/App.vue'

const vm = new Vue({
    //3.指定vm实例要控制的页面区域
    el:'#app',
    //4.通过render函数,把指定的组件渲染到el区域中
    render:h=>h(App)
})
webpack打包发布

上线之前需要通过webpack将应用进行整体的打包,可以通过package.json文件配置打包命令:

//在package.json文件中配置webpack打包命令
//该命令默认加载项目根目录中的webpack.config.js配置文件
"scripts":{
    //用于打包的命令
    "build":"webpack-p",
    //用于开发调试的命令
    "dev":"webpack-dev-server --open --host 127.0.0.1 --port 3000",
},

Vue脚手架

Vue脚手架的基本用法

Vue脚手架用于快速生成Vue项目基础架构,器官网地址为:https://cli.vuejs.org/zh/

使用步骤

1.安装3.x版本的Vue脚手架:

npm install -g @vue/cli

基于3.x版本的脚手架创建vue项目

//1.基于交互式命令行的方式,创建新版的vue项目
vue create my-project

//2.基于图形化界面的方式,创建新版vue项目
vue ui

//3.基于2.x的旧模板,创建旧办vue项目
npm install -g @vue/cli-init
vue init webpack my-project
//1.基于交互式命令行的方式,创建新版vue项目
vue create my-project

//2.基于图形化界面的方式,创建新版vue项目
vue ui

//3.基于2.x的旧模板,创建旧版vue项目
npm install -g @vue/cli-init
vue init webpack my-project
Vue脚手架生成的项目结构分析

node_modules 依赖包目录

public 静态资源目录

src 组件源码目录

babel.config.js Babel配置文件

Vue脚手架的自定义配置

1.通过package.json配置项目

//必须是符合规范的json语法
"vue":{
    "devserver"{
        "port":"0000",
        "open":true
    }
},

注意:不推荐使用这种配置方式,因为package.json主要用来管理包的配置信息;为了方便维护,推荐将vue脚手架相关的配置,单独定义到vue.config.js配置文件中。

2.通过单独的配置文件配置项目

1.在项目的根目录创建文件vue.config.js

2.在该文件中进行相关配置,从而覆盖默认配置

//vue.config.js
module.exports = {
    devServer:{
        port:0000
    }
}

Element-UI的基本使用

Element-UI:一套为开发者,设计师和产品经理准备的基于Vue 2.0的桌面端组件库

官网地址为:http://element-cn.eleme.io/#/zh-CN

1.基于命令行方式手动安装

1.安装依赖包npm i element-ui -S

2.导入Element-UI相关资源

//导入组件库
import ElementUI from 'element-ui';
//导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css';
//配置Vue插件
Vue.use(ElementUI);
基于图形化界面自动安装

1.运行vue ui 命令,打开图形化界面

2.通过Vue项目管理器,进入具体的项目配置面板

3.点击插件->添加插件,进入插件查询面板

4.搜索vue-cli-plugin-element并安装

5.配置插件,实现按需导入,从而减少打包后项目的体积

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值