请永远牢记vue是单向数据流javascript
自定义组件:css
建立子组件的文件,创建组件的模板,把架子搭起来,也就是在子组件中写好<template>视图层,<script>逻辑层<style>css样式层。而后定义好props里面的数据,实现子组件须要的逻辑代码后,也就封装好了,而后直接调用便可。调用的花import引入,同时在父组件<script>(逻辑层)中的components这个对象中写入组件名称,最后挂载到父组件的template中便可。html
组件通讯:前端
①props / $emitvue
父组件经过props的方式向子组件传递数据,而经过$emit子组件能够向父组件通讯。java
②$children / $parentnode
this.$children[0].msg = "hello world" //父组件修改子组件data中的数据
this.$parent.mag //子组件拿到父组件data中的数据
$children的值是数组,$parent的值是个对象复制代码
注意:$parent,$children它们的目的是做为访问数组的应急方法,更推荐用props和events实现父子组件通讯。react
③provide / injectwebpack
这是vue2.2.0新增的api,简单来讲就是父组件中经过provide来提供变量,而后再子组件中经过inject来注入变量。ios
//父组件
export default{
name:"A",
provide:{
for:"demo"
},
components:{
comB
}
}
//子组件
export default{
name:"B",
inject:["for"],
data(){
demo:this.for
}
}复制代码
④ref / refs
ref:若是在普通的DOM元素上使用,引用指向的就是DOM元素;若是用在子组件上,引用就指向组件实例,可经过实例直接调用组件的方法或访问数据。
//父组件
<template>
<component-a ref="comA"></component-a>
</template>
<script>
export default{
mounted(){
const comA = this.$refs.comA;
console.log(comA.name)//Vue.js
comA.sayHello() //hello
}
}
</script>复制代码
//子组件
export default{
data(){
return {
name:"Vue.js"
}
},
methods:{
sayHello(){
console.log("hello")
}
}
}复制代码
⑤eventBus(Bus总线):
//首先在src中建立一个Bus文件夹 => index.js
import Vue from "vue";
export default new Vue({
})
//子组件1(发送数据的组件)
<button @click="add()">点击</button>
import Bus from "@/Bus"
add(){
Bus.$emit("add",this.content);
}
//子组件2(接受数据的组件)
<p>{{tit}}</p>
import Bus from "@/Bus";
created(){
Bus.$on("add",(data) => {
this.tit = data;
})
}复制代码
⑥Vuex;
⑦LocalStorage;
⑧$attrs / $listeners
将数据挂在到子组件的标签上去后,在子组件中使用this.$attrs直接获取到全部挂载的数据,返回的是一个对象。
使用nextTick的缘由:Vue是异步修改DOM的,而且不鼓励开发者直接接触DOM,可是有时候须要必须对数据更改后的DOM元素作相应的处理,可是获取到的DOM数据并非更改后的数据,这时候就须要this.$nextTick();
原理:Vue经过异步队列控制DOM更新和nextTick回调函数前后执行的方式。
使用:
//HTML
<button @click="change()">按钮</button><h1 ref="gss">{{msg}}</h1>
//JS
export default{
name:"app",
data(){
return {
msg:"123"
}
},
methods:{
change(){
this.msg = "456";
console.log(this.refs["gss"].innerHTML)//123
this.$nextTick(function(){
console.log(this.refs["gss"].innerHTML)//456
})
}
}
}
复制代码
补充:
patch方法patch(container, vnode)patch(vnode, newVnode)复制代码
replacechildrencreateElement复制代码
数据劫持:当咱们访问或设置对象的属性的时候,都会触发相对应的函数,而后在这个函数里返回或设置属性的值。咱们能够在触发函数的时候动一些手脚作点咱们本身想作的事情,这也就是“劫持”操做。
Vue3.0摒弃了Object.defineProperty,改成基于Proxy的观察者机制探索。
首先说一下Object.defineProperty的缺点:
而要取代它的Proxy有如下两个优势:
补充:
virtual-dom(简称vdom)的概念大规模的推广仍是得益于react的出现,virtual-dom也是react这个框架的很是重要的特性之一。相比于频繁的手动去操做dom而带来性能问题,vdom很好的将dom作了一层映射关系,进而将在咱们本须要直接进行dom的一系列操做,映射到了操做vdom,而vdom上定义了关于真实dom进行的建立节点,删除节点,添加节点等一系列复杂的dom操做,并将这些操做放到vdom中进行,这样就经过操做vdom来提升直接操做的dom的效率和性能。
在vue的整个应用生命周期当中,每次须要更新视图的时候便会使用vdom,vdom算法是基于snabbdom算法所作的修改。
实现:
①用js对象构造一个虚拟的dom树,插入到文档中;❄ 单页面路由跳转的方式:
①hash(哈希默认)模式:使用 URL hash 值来做路由。默认模式。
②history(mode:history)模式: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
③abstract模式(严格模式):支持全部 JavaScript 运行环境,如 Node.js 服务器端。
根据mode参数来决定采用哪种方式。
vue-router的实现原理(核心):更新视图但不从新请求页面。
❄ vue-router登录权限的判断
vue-router的登录权限判断主要是在全局钩子函数中进行的,咱们在router.js文件中的定义路由里,将须要登录权限的页面加上meta属性,值是对象的形式,而后在该对象中自定义一个属性,属性值就是一个Boolean值,这时候在main.js文件的全局钩子函数中进行判断,若是须要跳转的页面的自定义属性值为true,那么将进行判断其是否登陆,若是没有登陆,则告诉用户登陆,若是有登陆,那么进行页面跳转。
routes:[
{
path:"/home",
name:"Home",
components:Home
meta:{requireAuth:true}
}
]复制代码
router.beforeEach((to,from,next) => {
if(to.meta.requireAuth){//判断该路由是否须要登陆权限
if(store.state.token){//经过vuex的state获取当前的token是否存在
next()
}else{
next({
path:"/one",
query:{redirect:to.fullPath}//将跳转的路由path做为参数,登录成功后跳转到该路由
})
}
}else{
next();
}
})复制代码
❄ 路由嵌套
routes:[
{
path:"/home",
name:"Home",
components:Home,
children:[
{
path:"child",
name:"Child",
components:"Child"
}
]
}
]复制代码
定义:Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式储存管理应用的全部组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
使用场景:须要构建一个中大型单页应用,您极可能会考虑如何更好的在组件外部管理状态,Vuex将会成为天然而然的选择。
Vuex的运行机制:Vuex提供数据(state)来驱动试图(vue components),经过dispath派发actions,在其中能够作一些异步的操做,而后经过commit来提交mutations,最后mutations来更改state。
核心:
①state:定义初始数据。Vuex的映射:
computed:{
...mapState([
"list",
])
}
methods:{
...mapMutations([
"changes",
])
}复制代码
当一个Vue实例建立时,vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter而且在内部追踪相关依赖,在属性被访问和修改时通知变化。 每一个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程当中把属性记录为依赖,以后当依赖项的 setter 被调用时,会通知 watcher 从新计算,从而导致它关联的组件得以更新。
原理:vue异步组件技术:异步加载,vue-router配置路由 , 使用vue的异步组件技术 , 实现按需加载。
component:(resolve) => {
require(["@/components/HelloWorld"],resolve);
}复制代码
const info = () => import("@/components/info");复制代码
const info = (resolve) => {
import("@/components/info").then(modul => {
resolve(modul);
})
}复制代码
const info = r => require.ensure([],() => r(
require("@/components/info")
),"info");复制代码
Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有很是容易上手的API;Vue.js是一套构建用户界面的 渐进式框架。与其余重量级框架不一样的是,Vue 采用自底向上增量开发的设计。Vue的核心库只关注视图层,而且很是容易学习,很是容易与其它库或已有项目整合。数据驱动+组件化的前端开发。经过尽量简单的 API实现响应的数据绑定和组合的视图组件。核心是一个响应的数据绑定系统。
补充:
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。若是数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每一个元素,而且确保它在特定索引下显示已被渲染过的每一个元素。key 的做用主要是为了高效的更新虚拟DOM。
使用Object.assign(),vm.$data能够获取当前状态下的data,vm.$options.data能够获取到组件初始化状态下的data。
Object.assign(this.$data, this.$options.data())复制代码
route
是“路由信息对象”,包括path
,params
,hash
,query
,fullPath
,matched
,name
等路由信息参数。
router
是“路由实例对象”,包括了路由的跳转方法(push
、go
),钩子函数等。
①把不常改变的库放到index.html中,经过cdn引入
而后找到 build/webpack.base.conf.js 文件,在 module.exports = { } 中添加如下代码:
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'element-ui': 'ELEMENT',
},复制代码
②vue路由懒加载
③不生成map文件,找到config/index.js文件,修改成productionSourcceMap:false
④vue组件尽可能不要全局引入
⑤使用更轻量级的工具库
⑥开启gzip压缩:这个优化是两方面的,前端将文件打包成.gz文件,而后经过nginx的配置,让浏览器直接解析.gz文件。
⑦首页单独作服务端渲染:若是首页真的有瓶颈,能够考虑用 node 单独作服务端渲染,而下面的子页面仍用 spa 单页的方式交互。这里不推荐直接用 nuxt.js 服务端渲染方案,由于这样一来增长了学习成本,二来服务端的维护成本也会上升,有时在本机测试没问题,在服务端跑就有问题,为了省心,仍是最大限度的使用静态页面较好。
大体有三个点,第一个是关于提出的新API setup()
函数,第二个说了对于Typescript的支持,最后说了关于替换Object.defineProperty
为 Proxy 的支持。详细说了下关于Proxy代替带来的性能上的提高,由于传统的原型链拦截的方法,没法检测对象及数组的一些更新操做,但使用Proxy又带来了浏览器兼容问题。
vue-cli是基于 Vue.js 进行快速开发的完整系统,也能够理解成是不少 npm 包的集合。
vue-cli完成的功能:
若是开发者须要补充或修改默认设置,须要在 package.json 同级下新建一个 vue.config.js 文件
⑴v-bind:给元素绑定属性
⑵v-on:给元素绑定事件
⑶v-html:给元素绑定数据,且该指令能够解析html标签
⑷v-text:给元素绑定数据,不解析标签
⑸v-model:数据双向绑定
⑹v-for:遍历数组
⑺v-if:条件渲染指令,动态在DOM内添加或删除DOM元素
⑻v-else:条件渲染指令,必须跟v-if成对使用
⑼v-else-if:判断多层条件,必须跟v-if成对使用
⑽v-cloak:解决插值闪烁问题
⑾v-once:只渲染元素或组件一次
⑿v-pre:跳过这个元素以及子元素的编译过程,以此来加快整个项目的编译速度
⒀v-show:条件渲染指令,将不符合条件的数据隐藏(display:none)
v-for比v-if优先,若是每一次都须要遍历整个数组,将会影响速度,尤为是当之须要渲染很小一部分的时候。
//响应拦截
axios.interceptors.response.use(function(response){
//对响应数据作点什么
return response.data
},function(error){
//对错误响应作点什么
return Promise.reject(error)
})复制代码
//请求拦截
axios.interceptors.request.use(function(config){
//在发送请求以前作些什么
return config
},function(error){
//对请求错误作些什么
return Promise.reject(error)
})复制代码
使用babel-polyfill插件