笔记
-
- Vue.js的概念
- 下面是MVC和MVVM的关系图解
- vue.js的组件化思想是什么?
- 注册组件的基本步骤
Vue.js的概念
- Vue.js是目前比较火的前端框架,React是比较流行前端框架(React除了开发网站,还可以开发手机APP,Vue语法也是可以用于进行收集App开发的,需要借助Weex)
- Vue.js是前端的主流框架之一,和Angular.js、React.js一起,并成为前端三大主流框架!
- Vue.js是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
- 前端的主要工作?主要负责MVC中的V这一层(主要工作就是和界面打交道,来制作前端页面的效果)
下面是MVC和MVVM的关系图解
vue.js的组件化思想是什么?
- 他提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。
- 任何的应用都会被抽象成一颗组件树。
注册组件的基本步骤
- 创建组建构造器
调用Vue.extend()方法 - 注册组件
调用Vue.component()方法 - 使用组件
在Vue实例的作用范围内使用组件
<!-- 最基本的理解 -->
<div id="app">
<my-cpn></my-cpn>
</div>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
//ES6 `abc`可以换行
//1.创建组件构造器对象
const cpnC = Vue.extend({
template:`
<div>
<h2>我是标题</h2>
<p>我是内容</p>
<p>我是内容,哈哈哈哈哈哈</p>
</div>`
})
//2.注册组件
Vue.component('my-cpn',cpnC)
const app = new Vue({
el:'#app',
data:{
message:'你好啊'
},
methods:{}
})
</script>
全局组件: 意味着可以在多个Vue的实例下面使用
局部组件: 直接挂载在vue实例下面
const app = new Vue({
el:'#app',
data:{
message:'你好啊'
},
methods:{},
//2.注册组件(局部组件)
components:{
//cpn使用组件时的标签名
cpn:cpnC
}
})
父组件和子组件
组件与组件之间存在层级关系
而其中一种非常重要的关系就是父子组件的关系
注册组件语法糖
- 在上面注册组件的方式,可能会有些繁琐
- Vue为了简化这一过程,提供了注册的语法糖
- 主要是省去了调用Vue.extend()的步骤,而是可以直接使用一个对象来代替。
<body>
<div id="app">
<cpn1></cpn1>
<cpn2></cpn2>
</div>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
//1.全局组件注册的语法糖
//1.创建组建构造器
//const cpnC1 = Vue.extend()
//2.注册全局组件(语法糖)
Vue.component('cpn1',{
template:`
<div>
<h2>我是标题1</h2>
<p>我是内容,全局</p>
</div>`
})
//2.注册局部组件的语法糖
const app = new Vue({
el:'#app',
data:{},
components:{
'cpn2':{
template:`
<div>
<h2>我是标题1</h2>
<p>我是内容,局部</p>
</div>`
}
}
})
</script>
</body>
模板的分离写法
- 语法糖简化了Vue组件的注册过程,另外还有一个地方的写法比较麻烦,就是template模块的写法。
- 如果我们能将其中的html分离出来写,然后挂载到对应的组件上,必然结构会变得非常清晰。
- Vue提供了两种方案来定义HTML模块的内容:
(1)使用<script type="text/x-template"></script>
(2)使用<template>
标签
组件可以访问Vue实例数据吗
- 组件是一个单独功能模块的封装(这个模块有属于自己的HTML模块,也应该有属于自己的数据data)
- 组件中不能直接访问Vue实例中的data
- Vue组件应该有自己保存数据的地方(组件对象也有一个data属性,也可以有methods等属性,只是这个data属性必须是一个函数,而且这个函数返回一个对象,对象内部保存着数据)
为什么组件data属性必须是一个函数
- 如果不是函数他们之间就会相互造成很多影响。
父组件向子组件传递数据(props)
props的值有两种方式:
- 字符串数组,数组中的字符串就是传递时的名称。
- 对象,对象可以设置传递时的类型,也可以设置默认值等。
子组件向父组件传递数据(自定义事件)
- 当子组件需要向父组件传递数据时,就要用到自定义事件。
- v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件。
自定义事件的流程:
- 在子组件中,通过$emit()来触发事件。
- 在父组件中,通过v-on来监听子组件事件。
条件判断
1. v-if/v-else-if/v-else
2. v-show和v-if的区别
- v-show是改变css属性,v-if是决定标签存不存在
父子组件的访问方式:$children
- 父组件访问子组件:使用
$children
或者$refs
reference(引用) - 子组件访问父组件:使用
$parent
this.$children
是一个数组类型,它包含所有子组件对象。- 我们这里通过一个遍历,取出所有子组件的message状态
插槽(slot)
- 组件的插槽:是为了让我们封装的组件更加具有扩展性。
- 让使用者可以决定组件内部的一些内容到底可以展示什么
- 例如:移动网站中的导航栏,移动开发中,几乎每个页面都有导航栏。导航栏我们必然会封装成一个插件,比如nav-bar组件。一旦有了这个组件,我们就可以在多个页面中复用了。
- 最好的封装方式是将共性抽取到组件中,将不同暴露为插槽
- 一旦我们预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容
- 是搜索框,还是文字,还是菜单。由调用者自己来决定
具名插槽
- 插槽的基本使用
<slot></slot>
- 插槽的默认值
<slot>button</slot>
- 如果有多个值,同时放入到组件进行替换时,一起作为替换元素
编译作用域
- 官方给出来一条准则:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
作用域插槽:准备
- 父组件替换插槽的标签,但是内容由子组件来提供。
常见的模块化规范:
CommonJS、AMD、CMD,也有ES6的Moudules
ES6(export 导出 /import 导入)
ES6的模块化实现
- 在HTML代码中引入两个js文件,并且类型需要设置为module
- 在a.js中导出
var name = '小明'
var age = 18
var flag = true
function sum(num1,num2) {
return num1+num2;
}
if (flag){
console.log(sum(20, 10));
}
//1.导出方式一
export {
flag,sum
}
//2.导出方式二:
export var num1 = 1000;
export var height = 1.88;
//3.导出函数/类
export function mul(num1,num2) {
return num1+num2
}
export class Person {
run(){
console.log('在蹦包');
}
}
// class Perosn {
//
// }
//默认导出(default)
const a = '北京'
export default a
- 在b.js中导入
//1.导入的是{
}中的定义的变量
import {
flag,sum} from "./aaa.js";
if (flag){
console.log('小明是天才,哈哈哈哈哈哈');
console.log(sum(20, 30));
}
//2.直接导入export定义的变量
import {
num1,height} from "./aaa.js";
console.log(num1);
console.log(height);
//3.导入 export的function
import {
mul,Person} from "./aaa.js";
console.log(mul(30, 50));
const p = new Person();
p.run();
//4.默认的导入
import aa from "./aaa.js";
console.log(aa);
//5.统一全部导入
import * as aaa from './aaa.js'
console.log(aaa.mul(10, 2));
什么是Webpack?
从本质上来讲,Webpack是一个现代的JavaScript应用的静态模块打包工具。
从两个点来理解:模块和打包
在ES6之前,我们要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化的开发。
并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。
而Webpack其中一个核心就是让我们可以进行模块化开发,并且帮助我们处理模块之间依赖关系。
而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当作模块来使用。
这就是webpack中模块化的概念。
grunt/gulp和webpack有什么不同呢?
grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。
webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是他附带的功能。
webpack安装
- webpack模块化打包,webpack为了可以正常运行,必须依赖node环境,node环境为了可以正常的执行很多代码,必须其中包含各种依赖的包npm工具(node packages manager)
- 安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm
用到的命令 - webpack ./src/main.js -o ./dist/bundle.js
- npm init (初始化项目并且生成一个pakeage.json文件)
- npm run build(打包[需要在pakeage.json配置一个脚本 “build”:“webpack”])
- npm install [email protected] --save-dev(开发时依赖)
- npm install --save-dev css-loader(安装后还需要在webpack.config.js配置)
- npm install --save-dev style-loader(安装后还需要在webpack.config.js配置)
- npm install --save-dev url-loader
env(环境)
把ES6的语法转成ES5,那么就需要使用babel
在webpack中,我们直接使用babel对应的loader就可以了
npm install -save-dev babel-loader@7 babel-core babel-preset-es2015
配置webpack.config.js文件
重新打包,查看bundle.js文件,发现其中的内容变成了ES5的语法
el与template的区别
el用于指定Vue要管理的DOM,可以帮助解析其中的指令、事件监听等等。而如果Vue实例中同时指定了template,那么template模板的内容会替换掉挂载的对应el的模板。
安装vue-loader和vue-template-compiler
npm install vue-loader vue-template-compiler --save-dev
修改webpack.config.js的配置文件:…
将index.html文件打包到dist文件夹中,这个时候就可以使用HtmlWebpackPlugin插件
HtmlWebpackPlugin插件可以为我们做这些事情:
-自动生成一个index.html文件(可以指定模板来生成)
-将打包的js文件,自动通过script标签插入到body中
安装HtmlWebpackPlugin插件:
npm install html-webpack-plugin --save-dev
修改webpack.config.js文件中plugins:…
js压缩的Plugin
-这里我们使用一个第三方的插件uglifyjs-webpack-plugin,并且版本号指定1.1.1,和CLI2保持一致
-npm install [email protected] --save-dev
搭建本地服务器
npm install --save-dev [email protected]
devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:
-contentBase:为那一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist
-port:端口号
-inline:页面实时刷新
-historyApiFallback:在SPA页面中,依赖HTML5的history模式
-我们可以再配置另外一个scripts:–open参数表示直接打开浏览器
什么是Vue CLI
- 如果只是简单写几个Vue的Demo程序,那么你不需要Vue CLI.如果你在开发大型项目,那么你需要,并且必然需要使用Vue CLI
- 使用Vue.js开发大型应用时,我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情;如果每个项目都要手动完成这些工作,那无疑效率比较低效,所以通常我们会使用一些脚手架工具来帮主完成这些事情
- CLI是Command-Line-Interface,翻译为命令行界面,但是俗称脚手架
- Vue CLI是一个官方发布vue.js项目脚手架
- 使用vue-cli可以快速搭建Vue开发环境以及对应的webpack配置
- Webpack的全局安装:npm install webpack -g
vue-cli 卸载安装指令
//卸载3.0之前的版本
npm uninstall -g vue-cli
yarn global remove vue-cli
//卸载3.0之后的版本(可以统一使用此指令卸载)
npm uninstall -g @vue/cli
yarn global remove @vue/cli
安装最新版本:
npm install -g @vue/cli
或者
yarn global add @vue/cli
查看所有版本号:
//查询3.0之前的版本
npm view vue-cli versions --json
//查询3.0之后的版本
npm view @vue/cli versions --json
安装指定版本:
//安装2.9.6版本
npm install -g [email protected]
yarn global add [email protected]
//安装4.0.5版本
npm install -g @vue/[email protected]
yarn global add @vue/[email protected]
查看当前版本号和帮助信息:
vue -V 或 vue --version
vue -h 或 vue --help
安装Vue CLI3的版本,如果需要想按照Vue CLI2的方式初始化项目,可以全局安装一个桥接工具
npm install @vue/cli-init -g
Vue CLI2初始化项目
vue init webpack my-project
Vue CLI3初始化项目
vue create my-project
vue全家桶: VueCore(vue核心)+vue-router+vuex
Runtime-Compiler和Runtime-only的区别
在之后的开发中,你依然使用的是template,就需要选择Runtime-Compiler
如果之后的开发中,使用的是.vue文件夹开发,那么可以选择Runtime-only
认识Vue CLI3
vue-cli 3与2版本有很大的区别
vue-cli 3是基于webpack 4打造,vue-cli 2还是 webpack 3
vue-cli 3的设计原则是‘0配置’,移除的配置文件根目录下的,build和config等目录
vue-cli 3提供了vue ui命令,提供了可视化配置,更加人性化
移除了static文件夹,新增了public文件夹,并且index.html移动到public中
Vue CLI3的配置去哪里了?可以通过 vue ui 查看修改
ES6 箭头函数
箭头函数中的this是如何查找的?
向外层作用域中一层层查找this,直到有this的定义。
箭头函数没有this,他里面的this是指向定义时所在的作用域。
普通函数的this是由动态作用域决定,它总指向于它的直接调用者。如果函数没有直接调用者,this为window。在严格模式下,如果函数没有直接调者,this为undefined。
使用that,就不用担心是使用的函数还是箭头函数还是其它,很好的一个方法,也不用担心浏览器this指向差异问题。
什么是路由(Vue Router)?
- 路由是一个网络工程里面的术语。
- 路由(routing) 就是通过互联的网络把信息从源地址传输到目的地址的活动。—维基百科
- 额,啥玩意?没听懂
- 路由器提供了两种机制:路由和传送
- 路由是决定数据包从来源到目的地的路径
- 转送将输入端的数据转移到合适的输出端
- 路由中有一个非常重要的概念叫路由表
- 路由表本质上就是一个映射表,决定了数据包的指向。
- 路由是根据不同的 url 地址展示不同的内容或页面
- 前端路由的核心是:改变URL,但是页面不进行整体的刷新。
- 后端路由:后端处理URL和页面之间的映射关系。
什么是前端渲染?什么是后端渲染(服务端渲染)?
前端渲染:浏览器中显示的网页中的大部分内容,都是由前端写的 js 代码在浏览器中执行,最终渲染出来的网页。(也可以说:后端返回JSON数据,前端利用预先写的html模板,循环读取JSON数据,拼接字符串,并插入页面。)
后端渲染:服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示。 比如:jsp页面
前后端分离:随着Ajax的出现,有了前后端分离的开发模式;后端只提供API来返回数据,前端通过Ajax获取数据,并且可以通过JavaScript将数据渲染到页面中;并且当移动端(ios/Android)出现后,后端不需要进行任何处理,依然使用之前的一套API即可
$router
和$route
之间的区别
$router
为VueRouter
实例 想要导航到不同的URL 则使用$router.push
方法
$route
为当前router跳转对象里面可以获取path、query、name 、params
keep-alive遇见vue-router
keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
它们有两个非常重要的属性:
include - 字符串或正则表达,只有匹配的组件会被缓存
exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
router-view 也是一个组件,如果直接被包在keep-alive里面,所有路径匹配到的视图组件都会被缓存。
什么是Promise呢?
ES6中有一个非常好用的特性就是Promise
Promise是异步编程的一种解决方案
一般情况下是有异步操作时使用Promise这个异步操作进行封装,new -> 构造函数(1.保存一些状态信息 2.执行传入的函数)
在执行传入的回调函数时,会传入两个参数,resolve,reject,本身又是函数。
Promise三种状态
promise异步操作后会有三种状态,分别是
Pending(等待状态),比如正在进行网络请求或者定时器没有到时间。
fullfill(满足状态),当我们主动回调了resolve时,就处于该状态,并且会回调.then()
reject : 拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()
回调函数
把某一个函数作为参数传入到另外一个函数里面,传过去之后反过来回调这个函数
Vuex 组成和原理
- 组成: 组件间通信, 通过store实现全局存取
- 修改: 唯一途径, 通过commit一个mutations(同步)或dispatch一个actions(异步)
- 简写: 引入mapState、mapGetters、mapActions
官方解释: Vuex是一个专门为Vue.js应用程序开发的状态管理模式。
它采用
集中式存储管理
应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex也集成到Vue的官方调试工具devtools extension
,提供了诸如零配置的time-travel调试、状态快照导入导出等高级调试功能。
Devtools是一个浏览器插件
- 提取出一个公共的store对象,用于保存在多个组件中共享的状态
- 将store对象放置在new Vue对象中,这样可以保证在所有的组件中都可以使用到
- 在其他组件中使用store对象中保存的状态即可(通过
this.$store.state.
属性的方法来访问状态 通过this.$store.commit('mutation中方法')
来修改状态)
Vuex核心概念
State(数据 单一状态树)
Getters(当组件中的数据经过变化之后再给其他组件使用,getters默认是不能传递参数的,如果希望传递参数,那么只能让getters本身返回另一个函数)
Mutations(状态更新:Vuex状态的更新唯一方式(提交Mutation))主要包括两部分:1.字符串的事件类型(type)2.一个回调函数handler,该回调函数的第一个参数就是state。
Actions(异步操作(Promise))
Modules
Mutation响应规则
Vuex的store中的state是响应式的,当state中的数据发生改变时,Vue组件会自动更新。
这要求我们必须遵守一些Vuex对应的规则:
提前在store中初始化好所需的属性
在给state中的对象添加新属性的时候,使用下面的方式:
方式一(使用Vue.set(obj, ‘newProp’, 123))
方式二(用新对象给旧对象重新赋值)
Mutation同步函数
通常情况下,Vuex要求我们Mutation中的方法必须是同步方法。
主要的原因是当我们使用devtools时,devtools可以帮助我们捕捉mutation的快照。
但是如果是异步操作,那么devtools将不能很好的追踪这个操作什么时候会被完成。
Axios是什么?
Axios 是一个基于 promise 的 HTTP 库,简单的讲就是可以发送get、post请求。
Axios特性
- 可以在浏览器中发送 XMLHttpRequests
- 可以在 node.js 发送 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 能够取消请求
- 自动转换 JSON 数据
- 客户端支持保护安全免受 XSRF 攻击
Axios用在什么场景?
在特性里面已经有提到,浏览器发送请求,或者Node.js发送请求都可以用到Axios。像Vue、React、Node等项目就可以使用Axios,如果你的项目里面用了Jquery,此时就不需要多此一举了,jquery里面本身就可以发送请求。
谈到的CSS
display: flex; flex-wrap: wrap;
(包裹:根据一行的宽度决定到底显示多少个,默认是nowrap 不包裹)justify-content: space-around;
(均等分)
v-on(@)的修饰符
- .native修饰符:在我们需要监听一个组件的原生事件时,必须给对应的事件加上.native修饰符,才能进行监听
Better-Scroll可滚动区域的问题
- Better-Scroll在决定有多少区域可以滚动时,是根据scrollerHeight属性决定的
- 监听每一张图片是否加载完成,只要一张图片加载完成了,执行一次refresh()
- 如何监听图片加载完成啦?原生的js监听图片:img.onload = function() {}
- Vue中监听:@load = ‘方法’
- 调用scroll的refresh()
防抖debounce/节流
防抖debounce/节流throttle
防抖函数起作用的过程:
如果我们直接执行refresh,那么refresh函数会被执行30次
可以将refresh函数传入到debounce函数当中生成一个新的函数
吸顶效果
获取到
tabControl的offsetTop
必须知道滚动到多少时,开始有吸顶效果