vue几个常见的问题

前沿:这篇博客主要是写来梳理vue几个常见的问题和难点的。是我自己在学习阶段的的笔记。
首先就是vue和jquery的比较,以及vue和react等其他框架的比较。
然后就是vue全家桶的简单复习。
以上两点都是从vue的宏观来说的。
后面将针对vue的重难点,比如vue的生命周期,双向数据绑定原理,watch和computed原理,以及vue的插槽,父子组件间的传值等

1. vue和jquery以及react等比较

1.1 vue与jQuery

jQuery最主要的特点就是频繁的操作DOM,数据和页面是绑定在一起的
而vue则是通过vue对象将数据和视图分开了,减少DOM操作,也就是MVVM

1.2 vue与其他框架

几个框架的区别和选择,宏观上主要从以下方法:
(1)框架的使用场景,是否需要web和app
(2)团队的技能能力,学习新框架的成本和团队后期维护能力
(3)框架的性能,vue适合中小型,react和angular更适合大型
(4)框架的生态系统,使用者多不多,是否有繁荣的生态系统以供我们学习
(5)跨平台性。
Angular
对比于其他两个框架,最主要的特点就是一套完整的解决方案,不需要搭配其他库。有跨平台优势(ionic)。适合大型项目。
缺点就是学习成本较高,体积较大。
React
react和vue有很多相似之处,后面会着重分析其异同。
react和vue一样,核心库只关注视图层,其他的路由和状态管理交给其他相关的库,学习成本一般,也有跨平台优势(react native)
缺点就是官方文档不清晰等
vue
vue比较灵活(组件非常好用),构建项目可大可小,学习成本低,上手较快。
但是跨平台优势较差(虽然有weex但是与前两者还是有较大的差距)

1.3 vue和react比较

相同

vue和react有很多相似之处,比如

  • 两个框架都专注于视图层,其他功能如路由和全局状态管理交给相关的库
  • 都使用 “Virtual DOM”
  • 提供了响应式和组件化的视图组件

都使用虚拟DOM

Vue在2.0版本引入了vdom。其vdom是基于 snabbdom 库所做的修改。snabbdom是一个开源的vdom库。snabbdom的主要作用就是将传入的JS模拟的DOM结构转换成虚拟的DOM节点。先通过其中的 h函数 将JS模拟的DOM结构转换成虚拟DOM之后,再通过其中的 patch函数 将虚拟DOM转换成真实的DOM渲染到页面中。为了保证页面的最小化渲染,snabbdom引入了 Diff算法 ,通过Diff算法找出前后两个虚拟DOM之间的差异,只更新改变了的DOM节点,而不重新渲染为改变的DOM节点。

vue中的模板解析和渲染的核心就是:通过类似snabbdom的h()和patch()的函数,先将模板解析成vnode,如果是初次渲染,则通过patch(container,vnode)将vnode渲染至页面,如果是二次渲染,则通过patch(vnode,newVnode),先通过Diff算法比较原vnode和newVnode的差异,以最小的代价重新渲染页面。

react定义的一种类似于XML的JS扩展语法:XML+JS。
作用:用来创建react虚拟DOM(元素)对象。

不同

也有很多不同之处,比如

  • css/html
  • 生命周期
  • 构建工具
  • 路由
  • 状态管理
  • 数据绑定
  • 渲染性能
  • 数据更新

CSS/HTML
在react中,在 React 中,所有的组件的渲染功能都依靠 JSX。
在vue中,把html,css,js组合到一起,用各自的处理方式

构建工具
react使用create-react-app来快速脚手架

creat-react-app优点

无需配置:官方的配置堪称完美,几乎不用你再配置任何东西,就可以上手开发项目。
高集成性:集成了对React,JSX,ES6和Flow的支持。
自带服务:集成了开发服务器,你可以实现开发预览一体化。
热更新:保存自动更新,让你的开发更简单。
全兼容性:自动处理CSS的兼容问题,无需添加-webkit前缀。
自动发布:集成好了发布成品功能,编译后直接发布,并且包含了sourcemaps功能。

npm install -g create-react-app
create-react-app my-app(自己的项目名称)
cd my-app

vue使用vue-cli脚手架

路由
react使用react-router
vue使用vue-router

状态管理
react使用redux
在这里插入图片描述redux
 可以看看:https://www.cnblogs.com/yangyangxxb/p/10047648.html
 
vue使用vuex
在这里插入图片描述
 可以看看:https://www.cnblogs.com/yangyangxxb/p/10096540.html
数据绑定
vue是双向数据绑定,vue最核心的功能有两个,一个是响应式的数据绑定系统,二是组件系统。
react是单向数据流,数据绑定操作比较复杂

渲染性能
 React 的渲染建立在 Virtual DOM 上——一种在内存中描述 DOM 树状态的数据结构。当状态发生变化时,React 重新渲染 Virtual DOM,比较计算之后给真实 DOM 打补丁。
 在超大量数据的首屏渲染速度上,React 有一定优势,因为 Vue 的渲染机制启动时候要做的工作比较多,而且 React 支持服务端渲染。

Vue 通过建立一个虚拟 DOM 对真实 DOM 发生的变化保持追踪。vue渲染的过程如下:
 new Vue,执行初始化
 挂载$mount方法,通过自定义Render方法、template、el等生成Render函数
 通过Watcher监听数据的变化
 当数据发生变化时,Render函数执行生成VNode对象
  通过patch方法,对比新旧VNode对象,通过DOM Diff算法,添加、修改、删除真正的DOM元素

2. vue全家桶

2.1 vue-cli

是vue官方提供的快速搭建项目的工具
(1)首先全局安装webpack,然后全局安装vue-cli
npm install --global vue-cli
(2)新建一个文件夹,进入文件夹目录。在命令行输入:
vue init webpack demo
demo是自定义的项目名称,执行命令之后会在当前文件夹目录生成一个以该名称命名的项目文件夹。然后输入命令以后会有一些选项:
①Project name (baoge): -----项目名称,直接回车,按照括号中默认名字(注意这里的名字不能有大写字母
②Project description (A Vue.js project): ----项目描述,也可直接点击回车,使用默认名字
③Author (): ----作者
④Runtime + Compiler: recommended for most users 运行加编译,既然已经说了推荐
⑤Install vue-router? (Y/n) 是否安装vue-router,这里就输入“y”后回车即可
⑥Use ESLint to lint your code? (Y/n) 是否使用ESLint管理代码,ESLint是个代码风格管理工具,是用来统一代码风格的,一般项目中都会使用
⑦Setup unit tests with Karma + Mocha? (Y/n) 是否安装单元测试,我选择安装y回车
⑧Setup e2e tests with Nightwatch(Y/n)? 是否安装e2e测试 ,我选择安装y回车
(3)配置完成以后,目录下多了一个文件夹demo,然后cd进入这个文件夹安装依赖
npm install(或者切换成cnpm i)
(4)启动项目 npm run dev
(5)打包上线,自己的项目文件都需要放在src文件夹下,在项目开发完成之后,输入npm run build来打包。打包完成后,会生成 dist 文件夹,如果已经修改了文件路径,可以直接打开本地文件查看。
项目上线时,只需要将 dist 文件夹放到服务器就行了。

2.2 vue-router

 后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应到相应的资源
 前端路由:对于单页面应用程序来说,主要是通过URL中的hash(#)来实现不同页面间的切换,同时,hash有一个特点,HTTP请求中不会包含hash的相关内容,所以,单页面程序中页面跳转主要用hash实现
 在单页面应用程序中,这种通过hash改变切换来切换页面的方式,称作为前端路由(区别于后端路由)

(1)首先引入vue-router包,创建login和register两个对象模板

(2)然后创建一个路由对象,当导入包之后,在window全局对象中,就有了一个路由的构造函数,叫做VueRouter,在new路由对象的时候,可以为构造函数传递一个配置对象
在这里插入图片描述

(3)将路由规则对象,注册到vm实例上,用来监听URL地址变化,然后展示对应组件
在这里插入图片描述
(4)在HTML结构中用routerView来作为一个占位符,展示router对象对应组件;用routerLink来替代a标签,作为切换按钮
在这里插入图片描述
(5)路由显示组件高亮可以对路由的.router-link-active类在css中进行设置;
也可以在路由中定义属性linkActiveClass:‘myactive’,然后在css中设置. myactive

2.3 vue-resource(或axios)

除了vue-resource之外,还可以使用axios第三方包来实现。

methods:{
			getInfo(){
				// 发起get请求,通过then来设置成功的回调函数
				this.$http.get('http://vue.studyit.io/api/getlunbo').then(function(result){
				// 通过result.body拿到服务器成功返回的数据
					console.log(result.body);
				})

			},
			postInfo(){
				// 发起post请求,当前服务器只接受表单格式的请求,手动发起的post请求,默认没有表单格式,所以有的服务器处理不了
				// application/x-www-form-urlencoded
				// 通过设置post方法的第三个参数,这是提交内容为表单格式
				this.$http.post('http://vue.studyit.io/api/getlunbo',{},{emulateJSON:true}).then(result=>{
					console.log(result.body);
				})
			}

2.4 vuex

1、定义
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
Vuex是Vue配套的公共数据管理工具,它可以把一些共享的数据保存到vuex中,方便整个程序或者任何组件修改我们的公共数据
Vuex是一个全局的共享数据存储区域。就相当于一个数据的仓库。
2、Vuex的安装
(1)标签引入
(2)NPM
装包
import引入
Vue.use(Vuex)
3、创建一个Store实例
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
4、将store挂载到vm实例中
var vm = new Vue({
el:’#app’,
render:c=>c(app),
router,
store
})
5、使用方法
总结:
(1)state中的数据,不能直接被修改,必须通过mutation
(2)如果组件想要直接从state中获取数据。需要this. s t o r e . ∗ ∗ ∗ ( 3 ) 如 果 组 件 想 要 修 改 数 据 , 必 须 使 用 m u t a t i o n 提 供 的 方 法 , 需 要 通 过 t h i s . store.*** (3)如果组件想要修改数据,必须使用mutation提供的方法,需要通过this. store.3使mutationthis.store.commit(‘方法名字’,唯一的一个参数)
(4)如果store中的state上的数据,在对外提供的时候,需要一层包装,那么推荐使用getters,使用方法$store.getters.**

2.5 vue-preview

2.6 ElementUI(或Mint-UI等)

3. vue生命周期

vue生命周期是必须掌握的一个知识点。
在这里插入图片描述
生命周期钩子:是指生命周期函数,生命周期事件。
每个vue实例在被创建的时候都要经过一系列初始化,例如-需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM,同时在这个机会过程中也会运行一些叫做生命周期钩子的函数,这给用户在不同阶段添加自己代码的机会。
主要是有三个时期:
创建时期;
运行期间;
销毁期间;
创建其期间的生命周期函数:
(1)beforeCreated:实例在内存中创建出来,data和methods还没有被初始化
(2)created:实例在内存中已经创建ok,此时data和methods已经创建ok,此时还没有开始编译模板
(3)beforeMounted:此时已经完成好了模板的编译,挂载到了页面指定的容器中显示
(4)mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
运行期间的生命周期函数:
(1)beforeUpdate:状态更新之前执行此函数,此时data中的状态值是最新的,但是界面上显示的数据仍然是旧的,因为此时还没有开始重新渲染DOM节点
(2)updated:实例更新完毕之后调用此函数,此时data中的状态值和界面显示的数据都已经完成了更新,界面已经被重新渲染好了。
销毁期间的生命周期函数:
(1)beforeDestroy:实例销毁之前调用,这一步实例仍然完全可用。
(2)destroyed:vue实例销毁后调用,调用后,实例指示的所有东西都会解绑,所有的时间监听器会被移除,所有的子实例也会被销毁。

4. vue原理

4.1 数据绑定原理

数据绑定分为单向数据绑定和双向数据绑定

单向数据绑定

单向数据绑定指的是我们先帮模板写好,然后把模板和后台数据整合到一起形成HTML代码,然后把这段代码插入到文档流中。
在这里插入图片描述
单向数据绑定的特点就是,html代码一旦生成以后,就没办法再改变,如果有新的数据来了,必须把之前的html代码去掉,再重新把新的数据和模板一起整合后插入到文档流之中

双向数据绑定

数据模型和视图之间的双向数据绑定就是界面的操作可以反映到数据,数据的变更也能实时展现到页面。
在这里插入图片描述
双向数据绑定最常应用的场景就是表单了。当用户在前端页面完成输入后,不用任何操作,我们就可以拿到数据存放到数据模型之中了。
vuejs则使用Object.defineProperty()方法,监控数据的操作,从而可以触发数同步。

双向数据绑定原理

vue的双向数据绑定主要是需要解决以下两个问题:
1、如何知道数据更新。
2、数据更新后,如何通知变化
第一个问题采用数据劫持来实现,第二个问题结合发布者-订阅者模式。

大佬的解释:【然鹅并看不懂】
1.实现一个监听者Oberver来劫持并监听所有的属性,一旦有属性发生变化就通知订阅者

2.实现一个订阅者watcher来接受属性变化的通知并执行相应的方法,从而更新视图

3.实现一个解析器compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相对应的订阅者

简单点说,实现MVVM的双向数据绑定,采用数据劫持结合发布者-订阅者模式的方式。通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
在这里插入图片描述

实现简单的双向数据绑定

	<input type="text" id="inp">
	<div id="box"></div>
	<script type="text/javascript">
	let box=document.getElementById("box");
	let inp=document.getElementById("inp");
	let obj={
		name:''
	};
	// 监听事件
	inp.addEventListener('input', function(e){
		obj.name=e.target.value;
	}, false);
	// 数据劫持
	Object.defineProperty(obj,'name',{
		get:function(){
			console.log(111);
			return val;
		},
		set:function(newVal){
			inp.value=newVal;
			box.innerHTML=newVal;
		}
	})
	</script>

数据劫持

ES5中有Object.defineProperty()方法,它能监听各个属性的set和get方法
首先可以获取对象上的所有属性Object.keys()
然后对所有属性进行遍历,为每个属性增加监听,实现数据劫持

let data ={name:'tcy',age:'20'}
function observe(data){
	//获取所有的data数据对象中的所有属性进行遍历
    const keys = Object.keys(data)
    for (let i = 0; i < keys.length; i++) {
    	let val = data[keys[i]];
       defineReactive(data, keys[i],val)//为每个属性增加监听
    }
}
function defineReactive(obj,key,val){
   Object.defineProperty(obj, key, {
    enumerable: true,//可枚举
    configurable: true,//可配置
    get: function reactiveGetter () {
      //模拟get劫持
      console.log("get劫持");
      return val;
    },
    set: function reactiveSetter (newVal) {
       	//模拟set劫持
     console.log("set劫持,新值:"+newVal);
     val = newVal;
    }
  })
}
observe(data);
data.name="fyn";//set劫持,新值:fyn
console.log(data.name);//get劫持,fyn

data模拟vue.data对象,observer中对data的属性进行遍历,调用defineReactive对每个属性的get和set方法进行劫持。

由此,data数据的任何属性值变化,都可以监听和劫持,上述的第一个问题就解决了。

那view端的数据变化是如何知道的呢,view端改变数据的组件无外乎input,select等,可以用组件的onchange事件监听,这里就不再重点描述。

发布-订阅

vue在双向绑定的设计中,采用的是观察-订阅模式,前面所讲的数据劫持,其实就是为属性创建了一个观察者对象,监听数据的变化。接下来就是创建发布类和订阅类,如下:
在这里插入图片描述
observer,创建数据监听,并为每个属性建立一个发布类。
Dep是发布类,维护与该属性相关的订阅实例,当数据发生更新时,会通知所有的订阅实例。
Watcher是订阅类,注册到所有相关属性的Dep发布类中,接受发布类的数据变更通知,通过回调,实现视图的更新。
【我还是云里雾里的没看明白代码,理解一下前面写的简单版的吧。源码真心看不懂啊,哎】

4.2 watch和computed

计算属性computed

【依赖其他属性计算得出最后的值】
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护,为了简化插值表达式中的表达。
基础例子

<div id="example">
  <p>Original message: "{{ msg }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm=new Vue({
	el:'#example',
	data:{
		msg:'hello'
	},
	computed:{
		reversedMessage: function(){
			return this.msg.split('').reverse().join('')
		}
	}
})

你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage 依赖于 vm.msg,因此当 vm.msg 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。

侦听器watch

【监听一个值的变化,然后执行相对应的函数】
侦听属性的作用是侦听某属性值的变化,从而做响应的操作,侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是函数,当你侦听的元素发生变化时,需要执行的函数,这个函数有两个形参,第一个是当前值,第二个是变化后的值

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})
计算属性vs方法

我们也可以在插值表达式中调用相同的方法来达到同样的效果

<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在vm中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数

计算属性vs侦听属性

计算属性代码重复性较侦听属性小,代码更便捷
若一个值依赖多个值,用计算属性更加方便,即多对一,若一个值变化后引起一系列操作或者一系列值的改变,用watch更加方便。
此外,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
watch还能监听路由的变化

5. vue组件

5.1 vue插槽

5.2 vue组件传值

5.2.1 父子组件传值
父组件向子组件传值

通过props向子组件传值,在子组件上绑定属性
<subCom :info=“hhh”></subCom>
在子组件内部使用props接收
props:[“info”]

子组件向父组件传值(父组件向子组件传methods方法)

子组件向父组件传值,通过methods方法
原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传来的方法,同时要把发送给父组件的数据,在调用方法的时候作为参数传递出去
首先定义com2组件和它的模板对象
(1)在父组件内部定义show(num)方法
在这里插入图片描述
(2)在HTML结构子组件中绑定父组件的方法show,注意只绑定show而不加(),表示传递的是函数的引用在这里插入图片描述

(3)在子组件的方法内部,用$emit()来接收函数,并进行传参在这里插入图片描述

(4)最后因为方法是在父组件(子组件身上)调用的。可以在方法内部获取函数的实参。

5.2.2 组件间传值–事件总线方式

平级间的组件间的传值需要一个中间截止作为中央事件线。
(1)首先创建中央事件线,在组件的文件夹下创建一个eventBus,js

import Vue from 'Vue'

export default new Vue;

eventBus中只创建了一个vue的实例,承担起组件之间通讯的桥梁,也就是中央事件总线
(2)创建一个firstChild组件,引入事件总线,接着添加一个按钮绑定一个点击事件

<template>
	<div  id="firstChild>
		<h2>firstChild组件</h2>
		<button @click="SendMsg">点击我向组件传值</button>
	</div>
</template>
<script>
	import bus from '@comps/eventBus';
	export default{
		data(){
			return{
				msg:'this is a firstChild msg'
			}
		},
		methods:{
			sendMsg:function(){
				bus.$emit("userDefineEvent",this.msg
			}
		}
	}
</script>

我们在响应点击事件的sendMsg函数中用$emit触发了一个自定义的userDefineEvent事件,并传递了一个字符串参数。
PS:$emit实例方法触发当前实例(这里的当前实例就是bus)上的事件,附加参数都会传给监听器回调
(3)我们再创建一个secondChild组件,引入eventBus事件总线,并用一个p标签来显示传递过来的值

<template>
	<div id="secondChild">
		<h2>secondChild组件</h2>
		<p>从firstChild传过来的字符串:{{msg}}</p>
	</div>
	<script>
		import bus from '@comps/eventBus';
		export default{
			data(){
				return {
					msg:''
				}
			},
			mounted(){
				var self=this;
				bus.$on("userDefineEvent",function(msg){
					self.msg=msg;
				}
			}
		}
	</script>
</template>

我们在mounted中,监听了userDefinedEvent,并把传递过来的字符串参数传递给了$on监听器的回调函数
$on:监听当前实例上的自定义事件(此处当前实例为bus)。事件可以由 e m i t 触 发 , 回 调 函 数 会 接 收 所 有 传 入 事 件 触 发 函 数 ( emit触发,回调函数会接收所有传入事件触发函数( emit(emit)的额外参数
(4)在父组件中,注册这两个组件

5.2.3 vuex公共数据管理

集中存储管理
(1)state: 存储状态也就是存储变量
(2)getters:派生状态,也就是set、get中的get,有两个可选参数state、getters,分别可以获取state中的变量和其他的getters。外部调用方式,store.getters.personInfo(),类似vue中的computed
(3)mutations:提交状态修改,也就是set和get中的set,这是vuex中唯一修改state的方式,但不支持异步操作。第一个默认参数是state,外部调用方式:store.commit(‘SET_AGE’, 18)。和vue中的methods类似。
(4)actions:和mutations类似,不过 actions支持异步操作,第一个默认参数是和store具有相同参数属性的对象,外部调用方式:store.dispatch(‘nameAsyn’)
(5)modules:store的子模块,内容就是相当于store的一个实例,调用方式和前面介绍的相似,只是要加上当前的子模块名。如store.a.getters.xxx();

5.2.4 provide和inject

provide / inject 是 2.2 新增的方法,可以以一个祖先组件向所有子孙后代注入依赖(一个内容)。
provide/inject:简单来说就是在父组件中通过provider来提供变量,然后在组件中通过inject来注入变量
二者不仅限于父子组件的数据交互,只要在上一层声明的provide,下一级都能够深入访问到数据
父组件中

provide:{
            for:'test'
        }

子组件中:

inject:['for'],//得到父组件传递过来的数据
data(){
            return {
                mymessage:this.for
            }
        }

5.3 vue组件缓存

5.3.1 vue组件切换

点击哪个按钮显示对应的组件 (其中存在组件的销毁)每次切换都会走一遍created mounted钩子函数

<div id="app">
   
    <div class="container">
        <div @click="comp='zujian1'">显示组件1</div>
        <div @click="comp='zujian2'">显示组件2</div>
    </div>
    <div :is="comp"></div>
</div>
...
//关键是-----------------   :is用于绑定组件
var app=new Vue({
        el:'#app',
        data:{
            comp:'zujian2',
        },
       mounted(){
            alert('子组件挂载完,父组件才会挂载完')
        },
        components:{
            zujian1:{
                template:'<h1>组件1</h1>',
                mounted(){
                  alert('重新渲染dom')
                },
                beforeDestroy(){
                  alert('销毁了')
                }
            },
            zujian2:{
                template:'<h1>组件2</h1>',
                mounted(){
                  alert('重新渲染dom')
                },
                beforeDestroy(){
                  alert('销毁了')
                }
            }
        }
    })

5.3.2 keep-alive缓存

不会再走mounted,beforeDestroy函数,因为组件被缓存,不用销毁重新渲染,性能比较好

<div id="app">
    <div class="container">
        <div @click="comp='zujian1'">显示组件1</div>
        <div @click="comp='zujian2'">显示组件2</div>
    </div>
    <keep-alive><!--一般用作缓存:为的是后面的路由做准备,如果缓存了就不会再走created mounted钩子函数-->
    <div :is="comp"></div>
    </keep-alive>
</div>
...
var app=new Vue({
        el:'#app',
        data:{
            comp:'zujian2',
        },
        //需要等待子组件挂载完成后再触发父组件的挂载
       mounted(){
            alert('子组件挂载完,父组件才会挂载完')
        },
        components:{
            zujian1:{
                template:'<h1>组件1</h1>',
                mounted(){
                  alert('重新渲染dom')
                },
                beforeDestroy(){
                  alert('销毁了')
                }
            },
            zujian2:{
                template:'<h1>组件2</h1>',
                mounted(){
                  alert('重新渲染dom')
                },
                beforeDestroy(){
                  alert('销毁了')
                }
            }
        }
    })

6 条件渲染v-if和v-show的区别

v-if创建和移除元素;
v-show是操作display:none
也就是说,v-if有较高的切换性能消耗,v-show有较高的初始性能消耗

参考文献

https://blog.csdn.net/wangjie962311/article/details/72829029
https://www.cnblogs.com/yangyangxxb/p/10105856.html
https://www.jianshu.com/p/23180880d3aa
https://blog.csdn.net/tcy83/article/details/80959725
https://www.cnblogs.com/alongup/p/9022180.html
https://www.jianshu.com/p/5c6df9b469d0
https://www.cnblogs.com/yszblog/p/10135969.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值