JavaScript原始功能
在网页开发的早期,js制作作为一种脚本语言,做一些简单的表单验证或者动画实现,代码量比较少,只要写在script标签里面就可以了
随着ajax异步请求的出现,慢慢形成了前后端分离,客户端需要完成的事情越来越多,代码量也越来越多。为了应对代码量的剧增,我们通常会把代码组织在多个js文件中,进行维护
但会出现一些问题:比如全局变量同名的问题
使用函数闭包可以解决变量冲突的问题,但是使用不了其他文件定义的变量
模块化有两个核心:导出和导入
CommonJS的导出
module.exports = {
flag:true,
test(a, b){
return a + b
},
demo(a, b){
return a + b
}
}
CommonJS的导入
let { test , demo } = required('module')
关键字export(导出) import(导入)
导出export
//aaa.js
let name ='jjj'
let age = 18
let height = 1.22
function sum(sum1,sum2){
return sum1+sum2
}
//导出方式一
export {name,age,height,sum}
//导出方式二
export var num1 = 1000
//在定义的时候直接导出
//导出函数/类
export function mul(num1,num2){
return num1 + num2
}
某些情况下,一个模块中包含某个功能,我们并不希望给这个功能命名,要让导入者来自己命名
就可以使用export default
只能默认导出一个,而且其他文件导入的时候可以自定义名称,不需要用{}括起来
const address = 'ss'
export default address
//只能默认一个
import jjj from "./aaa.js"
//可以自己命名,不要加{}
导入 import
//mmm.js
import { flag, sum } from "./aaa.js"
//统一全部导入
import * from "./aaa.js"
console.log(aaa.flag);
2021.11.4
从本质来讲,webpack是一个现代的js应用的静态模块打包工具
webpack让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系
webpack依赖node环境,node的工具npm( Node Packages Manager )
开发大型项目的时候才需要使用Vue CLI,Vue.js需要考虑代码目录结构,项目结构和部署,热加载,代码单元测试等事情,脚手架工具会帮助我们完成这些事情
CLI是command-Line-Interface,命令行界面,vue-cli可以快速搭建Vue开发环境以及对应的webpack配置
npm install -g @vue/cli
安装脚手架不成功的话
使用指令
npm clean cache -force
打开终端的时候使用管理员身份执行
如果仍然需要使用旧版本的vue init 功能,可以全局安装一个桥接工具
npm install -g @vue/cli-init
//cli2
vue init webpack 项目名称
vue cli2
每个指令的作用
只有main.js有区别
//runtime-compiler
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: ' '
})
//runtime-only
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h = > h(App)
})
runtime-compiler
先把template解析成ast(抽象语法树),编译成render函数,翻译成虚拟dom树,在生成真实dom
template -> ast -> render -> vdom -> UI
runtime-only
render -> vdom -> UI
runtime-only:将template在打包的时候,就已经编译为render函数
runtime-compiler:在运行的时候才去编译template
设计原则 0配置,移除了配置文件根目录下的,build和config等目录
提供了vue ui命令,提供了可视化配置
//cli3
vue create 项目名称
使用空格选择取消
可以使用vue ui指令进行配置
箭头函数this如何查找,向外层作用域一层层查找this,指到有this的定义
路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动
网站开发发展
早期的网站开发html页面是由服务器来渲染的(后端渲染),返回给客户端来展示
一个页面有对应的网址(url),url发送到服务器,进行匹配,controller进行处理,最终生成html或者数据,返回给前端,这就是后端路由
前后端分离阶段
随着Ajax的出现,有了前后端分离的开发模式
后端只提供API来返回数据,前端根据Ajax来获取数据,并且可以通过js将数据渲染到页面中
前后端的责任清晰,后端专注于数据,前端专注于交互和可视化上
SPA页面
单页面富应用,整个页面就只有一个html,不需要刷新页面
最主要的特点在前后端分离的基础上加了一层前端路由
由前端来维护这一套路由规则
//url的hash
location.hash='aaa'
//html
//类似于栈
history.pushState({},'','about')
history.replaceState({},'','replace')
history.go()
history.back()
history.forward()
步骤一:安装vue-router
npm install vue-router --save
步骤二:在模块化工程中使用它(因为是一个插件,所以可以通过Vue.use()安装路由功能)
1.导入路由对象,并且调用Vue.use(VueRouter)
2.创建路由实例,并且传入路由映射配置
3.在Vue实例中挂载创建的路由实例
//index.js
//配置路由相关的信息
import VueRouter from 'vue-router'
import Vue from 'vue'
import Home from '../components/Home'
import About from '../components/About'
//1.通过Vue.use(插件),安装插件
Vue.use(VueRouter)
//2.创建VueRouter对象
const routes = [
{
path:'/home',
component:Home
},
{
path:'/about',
component:About
}
]
const router = new VueRouter({
//配置路由和组件之间的应用关系
routes
})
//3.将router对象传入到Vue实例中
export default router
//main.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
components: { App },
template: ' '
})
2021.11.5
使用vue-router的步骤
1.创建路由组件
2.配置路由映射,组件和路径映射关系
3.使用路由:通过
和
创建了Home和About组件
导入组件
import Home from '../components/Home'
import About from '../components/About'
配置映射关系
const routes = [{
path: '/home',
component: Home
},
{
path: '/about',
component: About
}
]
在App.vue中使用
首页
关于
如果想要在点击进去默认显示一个组件的内容,设置redirect重定向
{
path: '/',
//redirect重定向
redirect: '/home'
},
有#不太像url
加上一个mode属性
还有其他属性
tag,指定
之后渲染成什么标签
replace,使用history.replaceState模式,replace不会留下history记录,返回按钮就没有效果了
active-class,当
对应的路由匹配成功时,会自动给当前元素设置一个router-link-active的class
如果不修改的话,默认的class就是router-link-active,但是如果想要修改这个class类就可以在标签用active-class='active',但如果要修改的router-link太多了,可以在router文件夹的index.js添加linkActiveClass,class就变成了active,在style里面用.active{}
直接使用button按钮标签,绑定事件
this.$router是自带的
想要拿到lisi
this.$route哪个路由活跃就拿到哪个路由
userId和上面path里面的相对应
当打包构建应用时,js包会变得非常大,影响页面加载
如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了
路由懒加载的主要作用是将路由对应的组件打包成一个个的js代码块
只有在这个路由被访问到的时候,才加载对应的组件
有两种编写方式
const Home = () => import('../components/Home')
const About = () => import('../components/About')
const routes = [
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
},
]
const routes = [
{
path: '/home',
component: () => import('../components/Home')
},
{
path: '/about',
component: () => import('../components/About')
},
]
一个懒加载在打包的时候会生成一个js文件
创建对应的子组件,并且在路由映射中配置对应的子路由
在组件内部使用
传递参数主要有两种类型params和query
params的类型
配置路由格式:/router/:id
传递的方式:在path后面跟上对应的值
传递后形成的路径:/router/123,/router/abc
query的类型
配置路由格式:/router,也就是普通配置
传递的方式:对象中使用query的key作为传递方式
传递后形成的路径:/router?id=123,/router?id=abc
$router 为VueRouter实例,想要导航到不同url,则使用$router.push方法
$route 为当前router跳转对象里面可以获取name、path、query、params等
想要实现跳转的时候标题改变,我们可以利用beforeEach来完成标题的修改
to 即将要进入的目标的路由对象
from 当前导航即将要离开的路由对象
next 调用该方法后,才能进入下一个钩子
2021.11.6
router-view也是一个组件,如果直接包在keep-alive里面,所有路径匹配到的视图组件都会被缓存
actived(){}
deactived(){}
//这两个函数只有在组件被保持状态,使用了keep-alive才有效
keep-alive有两个非常重要的属性
include-字符串或正则表达,只有匹配的组件会被缓存
exclude-字符串或正则表达,任何匹配的组件都不会被缓存
Promise是异步编程的一种解决方案
封装网络请求的函数,不能立即拿到结果,这个时候可以传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去
链式编程
什么情况下会用到promise?
一般情况下有异步操作时,使用promise对这个异步操作进行封装,成功的时候会调用resolve,去then那里执行,失败的时候调用reject,只要一个catch
语法糖形式
省略掉promise.resolve,会在return后自动加上一层Promise
2021.11.8 写实习报告
Vuex是一个专为Vue.js应用程序开发的状态管理模式
把需要多个组件共享的变量全部存储在一个对象里面,将这个对象放在顶层的Vue实例中,让其他组件可以使用
什么状态需要使用vuex?
比如用户的登录状态、用户名称、头像、地理位置信息
比如商品的收藏、购物车中的物品
这些状态信息,我们都可以放在统一的地方,对它们进行保存和管理,而且他们还是响应式的
复习一下父子组件通信
//App.vue
{{message}}
{{counter}}
//HelloVuex.vue
{{counter}}
vuex是插件
npm install vuex --save
创建文件夹store,文件index.js
引进Vue和Vuex
创建对象
在main.js挂载
在store对象声明变量,就可以到处用
$store.state.counter
但是官方不推荐用$store.state.counter++这么修改,要走流程
全局单例模式,将共享的状态抽取出来,交给vuex大管家,统一管理,必须要按照规定好的规定,进行访问和修改等操作
devtools浏览器插件,记录每次修改
action异步操作
2021.11.9
vue.js
index.js
vue state推荐单一状态树,数据再多也统一放在一个store里面
当给state中的对象添加新属性的时候,使用下面的方式
1.使用Vue.set(obj,'newProp',123)
2.用新对象给旧对象重新赋值
getters:{
powerCounter(state){
return state.counter * state.counter
}
}
{{$store.getters.powerCounter}}
类似于computed
getters里面有两个参数,一个是state,一个是getters,如果要传入参数进行筛选的话,可以返回一个函数
getters:{
moreAgeStu(state){
return function (age){
return state.student.filter(s = >s.age >age)
//这里就传入了参数age
}
}
}
vuex的store状态的更新唯一方式:提交mutation
mutation主要包括两部分
字符串的事件类型(type)
一个回调函数(handle),该回调函数的第一个参数就是state
mutation的定义方法
mutations:{
increment(state){
state.count++
}
}
通过mutation更新
increment:function(){
this.$store.commit('increment')
}
在要使用的组件中定义方法,通过this.$store.commit('mutations中要定义的名字')来调用mutations中定义的方法
mutation里面的操作都是同步操作
Vue.delete(state.info,'age')可以实现响应式
Action类似于Mutation,但是是用来替代Mutation进行异步操作的
Vuex要求我们Mutations中的方法必须是同步方法,主要原因是当我们使用devtools时,可以使用devtools帮我们捕捉mutations的快照,如果是异步操作,那么devtools将不能很好地跟踪这个操作什么时候会被完成
this.$store.dispatch('名字','我是payload')
npm install axios --save
很多参数在开发中都是固定的,这个时候就可以抽取一些,可以利用axios的全局配置
axios.defaults.baseURL = '123.123.132.12:8080'
axios.defaults.timeout = 5000
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
常见的配置选项
请求地址 url:'/user'
请求类型 method:'get'
请求根路径 baseURL:'http;//'
请求前的数据处理 transformRequest:[function(data){}]
请求后的数据处理 transformResponse:[function(data){}]
自定义的请求头 headers:{'x-Requested-With':'XMLHttpRequest'}
URL查询对象 params:{id:12}
const instance1 = axios.create({
baseURL:'http://123.21.321:8080',
timeout:5000
})
instance1({
url:'/home/multidata'
}).then(res => {
console.log(res);
})
instance1({
url:'/home/data',
params:{
type:'pop',
page:2
}
})
每个文件都要引进axios框架的话,就太麻烦了,如果以后框架不再维护了,不好修改。
创建一个network文件夹,创建request.js文件,
import axios from 'axios'
export function request(config,success,failure){
//创建axios的实例
const instance = axios.create({
baseURL:'http://13.123:8080',
timeout:5000
})
//发送真正的网络请求
instance(config)
.then(res =>{
console.log(res);
success(res)
})
.catch(err =>{
console.log(err);
failure(err)
})
}
export function request(config){
return new Promise((resolve,reject)=>{
const instance = axios.create({
baseURL:'http://13.123:8080',
timeout:5000
})
instance(config)
.then(res =>{
resolve(res)
})
.catch(err =>{
reject(err)
})
})
}
最简便的方法
export function request(config){
const instance = axios.create({
baseURL:'http://123:8080',
timeout:5000
})
return instance(config)
}
axios提供了拦截器,用于我们在发送每次请求或者得到响应后,进行相应的处理
import axios from 'axios'
export function request(config){
const instance = axios.create({
baseURL:'http://123:8080',
timeout:5000
})
//请求拦截
instance.interceptors.request.use(config =>{
console.log(config);
//config里面有一些信息不符合服务器要求
return config
},err =>{
console.log(err)
})
//响应拦截
instance.interceptors.response.use(res =>{
return res.data
},err =>{})
return instance(config)
}