vue基础学习
一、vue基础
前端框架与库的区别?
- jquery 库 -> DOM(操作DOM) + 请求
- art-template 库 -> 模板引擎
- 框架 = 全方位功能齐全
- 简易的DOM体验 + 发请求 + 模板引擎 + 路由功能
- KFC的世界里,库就是一个小套餐, 框架就是全家桶
- 代码上的不同
- 一般使用库的代码,是调用某个函数,我们自己把控库的代码
- 一般使用框架,其框架在帮我们运行我们编写好的代码
- 框架: 初始化自身的一些行为
- 执行你所编写的代码
- 施放一些资源
- 框架: 初始化自身的一些行为
1.1 vue起步
- 1:引包
- 2:启动 new Vue({el:目的地,template:模板内容});
- options
- 目的地 el [string | DOM元素]
- 内容 template(模板一般需要被一个标签被包裹住,表示属于一块)
- 数据 data 保存数据属性,是一个函数,return一个对象,对象中的key 可以直接在页面中使用,在js中this.key名
- data中的属性,在dom中直接使用,在js中 this.xxx
- Components: key是组件名称,value是组件对象
- methods:一般用来配合 xxx事件
- props:子组件接收的参数设置[array]
new Vue({
el : '#app',
template : '<div>' +
'<h1>大家好 {{ text }}</h1>' +
'<div> 我是{{ name }}' +
'</div>',
data : function(){
return {
text : 'hello vue',
name : 'vue',
}
}
})
$属性:$refs 获取组件内的元素
$parent:获取当前组件对象的父组件
$children:获取子组件
$root:获取new Vue的实例
$el:组件对象的DOM元素$nextTick():在vue真正渲染DOM到页面以后才做的事情
插值表达式
- {{ 表达式 }}
- 对象 (不要连续3个{{ {name:‘jack’} }})
- 字符串 {{ ‘xxx’ }}
- 判断后的布尔值 {{ true }}
- 三元表达式 {{ true?‘是正确’:‘错误’ }}
- 可以用于页面中简单粗暴的调试
- 注意: 必须在data这个函数中返回的对象中声明
1.2 指令
1.2.1 什么是指令
- 在vue中提供了一些对于页面 + 数据的更为方便的输出,这些操作就叫做指令, 以v-xxx表示
- 比如html页面中的属性
<div v-xxx ></div>
- 比如html页面中的属性
- 比如在angular中 以ng-xxx开头的就叫做指令
- 在vue中 以v-xxx开头的就叫做指令
- 指令中封装了一些DOM行为, 结合属性作为一个暗号, 暗号有对应的值,根据不同的值,框架会进行相关DOM操作的绑定
1.2.2 vue中常用的v-指令演示
- v-text:元素的InnerText属性,必须是双标签 跟{{ }}效果是一样的 使用较少
- v-html: 元素的innerHTML
- v-if : 判断是否插入这个元素,相当于对元素的销毁和创建
- v-else-if
- v-else
- v-show 隐藏元素 如果确定要隐藏, 会给元素的style加上display:none。是基于css样式的切换
v-text 只能用在双标签中
v-text 其实就是给元素的innerText赋值
v-html 其实就是给元素的innerHTML赋值
v-if 如果值为false,会留下一个<!---->作为标记,万一未来v-if的值是true了,就在这里插入元素
如果有if和else就不需要单独占位了
如果全用上 v-if 相邻v-else-if 相邻 v-else 否则 v-else-if可以不用
v-if和v-else-if都有等于对应的值,而v-else直接写
v-if家族都是对元素进行插入和移除的操作
v-show是显示与否的问题
注意: 指令其实就是利用属性作为标识符,简化DOM操作,
看:v-model="xxx"
v-model 代表要做什么 xxx代表针对的js内存对象
写在那个元素上,就对哪个元素操作
1.2.3 v-if和v-show的区别 (官网解释)
v-if
是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show
较好;如果在运行时条件很少改变,则使用 v-if
较好。
1.2.4 v-bind使用(绑定属性值)
-
给元素的属性赋值
- 可以给已经存在的属性赋值 input value
- 也可以给自定义属性赋值 mydata
-
语法 在元素上
v-bind:属性名="常量||变量名"
-
简写形式
:属性名="变量名"
-
<div v-bind:原属性名="变量"></div> <div :属性名="变量"> </div>
1.2.5 v-on的使用(绑定事件)
- 处理自定义原生事件的,给按钮添加click并让使用变量的样式改变
- 普通使用
v-on:事件名="表达式||函数名"
- 简写方式
@事件名="表达式"
1.2.7 v-model
- 双向数据流(绑定)
- 页面改变影响内存(js)
- 内存(js)改变影响页面
1.2.8 v-bind 和 v-model 的区别?
input v-model="name"
- 双向数据绑定 页面对于input的value改变,能影响内存中name变量
- 内存js改变name的值,会影响页面重新渲染最新值
input :value="name"
- 单向数据绑定 内存改变影响页面改变
- v-model: 其的改变影响其他 v-bind: 其的改变不影响其他
- v-bind就是对属性的简单赋值,当内存中值改变,还是会触发重新渲染
1.2.9 v-for的使用
- 基本语法
v-for="item in arr"
- 对象的操作
v-for="item in obj"
- 如果是数组没有id
v-for="(item,index) in arr" :class="index"
- 各中v-for的属性顺序(了解)
- 数组 item,index
- 对象 value,key,index
1.2.10 关于对象内的this
- vue已经把以前this是window或者事件对象的问题搞定了
- methods和data本身是在同一个对象中的,所以在该对象中可以通过this.随意取
- this.xxx 取data中的值, this.xxxMethod调methods中的函数
1.3 组件
//1.声明入口组件
var App = {
template: '<h1>我是一个入口组件</h1>'
}
new Vue({
el: '#app',
components:{ //2.声明要用的组件们
//key(组件名):value(组件对象)
app:App
},
template:'<app/>' //3.入口组件
});
1.3.1 局部组件的使用
渲染组件-父使用子组件
- 1: 创建子组件(对象)
var Header = { template:'模板' , data是一个函数,methods:功能,components:子组件们 }
- 2: 在父组件中声明,根属性
components:{ 组件名:组件对象 }
- 3: 在父组件要用的地方使用
<组件名></组件名>
- 在不同框架中,有的不支持大写字母,用的时候
- 组件名 MyHeader
- 使用 my-header
- 在不同框架中,有的不支持大写字母,用的时候
- 总结: 有父,声子,挂子,用子
//声明子组件
var myHeader = {
template: '<div>我是头部</div>'
}
var myBody = {
template : '<div>我是中部</div>'
}
// //等价于上一个,且较多使用上一个
// var myBody = Vue.extend({
// template : '<div>我是函数调用方式的中部</div>'
// })
var myFooter = {
template : '<div>' +
'我是底部<button @click="showNum(123)">click</button>' +
'</div>',
methods : {
showNum: function(num){
alert(num);
}
}
}
//1.声明入口组件
var App = {
components:{
'my-header': myHeader,
'my-body' : myBody,
'my-footer' : myFooter
},
template: '<div>' +
'<my-header></my-header>' +
'<my-body></my-body>' +
'<my-footer></my-footer>' +
'</div>'
}
new Vue({
el: '#app',
components:{ //2.声明要用的组件们
app:App //key(组件名):value(组件对象)
},
template:'<app/>' //3.入口组件,只有在new vue中可以使用单标签
});
1.3.2 父子组件传值(父传子)
- 1:父用子的时候通过属性Prop传递
- 2:子要声明props:[‘属性名’] 来接收
- 3:收到就是自己的了,随便你用
- 在template中 直接用
- 在js中 this.属性名 用
- 总结:父传,子声明,就是子的了
- 小补充: 常量传递直接用,变量传递加冒号
var son = {
template: '<div>' +
'接收到父组件的数据时:{{title}}<br/>' +
'接收的是一个常量:{{consts}}' +
'<h1 v-if="xxx">1</h1>' +
'<h1 v-show="xxx">2</h1>' +
'<ul>' +
'<li v-for="name in [\'lisi\',\'zhangsan\']">' +
'{{name}}' +
'</li>' +
'</ul>' +
'<button @click="changedd">改变现实</button>' +
'</div>',
data: function(){
return {
xxx: true
}
},
methods:{
changedd:function(){
return this.xxx = !this.xxx;
}
},
props:['title', 'consts'],
}
var App = {
components:{
'son': son,
},
template: '<div>' +
'<son :title="xxx" consts="22"></son>' +
'</div>',
data: function(){
return {
xxx:'我是xxx数据',
}
}
}
new Vue({
el:'#app',
components:{
app: App,
},
template:'<app/>'
})
1.3.3 总结父传子
- 父用子 先声子,挂子,用子
- 父传子 父传子(属性),子声明(收),子直接用(就是自己的一样)
1.3.4 子传父
-
1.子要绑定原生事件,在原生事件函数中通过this.$emit(‘自定义的事件名’,arg1);触发父组件中子组件自定义的事件名
-
2.父组件中的子组件
v-bind:自定义事件的名字 = 'fn'
绑定自定义的事件 -
3.父组件 就可以触发fn的函数 数据就可以从子组件中传过来了
-
注册全局组件
- 应用场景: 多出使用的公共性功能组件,就可以注册成全局组件,减少冗余代码
- 全局API
Vue.component('组件名',组件对象);
//全局组件
Vue.component('my-btn',{
template:'<button>beautiful button</button>'
})
MyHeader={
template:'<div>' +
'我是header组件' +
'<my-btn/>' +
'</div>',
}
MyFooter = {
template:'<div>' +
'我是footer组件' +
'<my-btn/>' +
'</div>',
}
var App = {
components:{
'my-header': MyHeader, //非全局组件的使用需要在调用处申明
'my-footer': MyFooter,
},
template: "<div>" +
"<my-header/><hr/>" +
"<my-footer/><hr/>" +
"<my-btn/>" +
"</div>"
}
new Vue({
el: '#app',
components:{
'app': App,
},
template: '<app/>',
})
1.3.5 附加功能:过滤器&监视改动
-
filter
- 将数据进行添油加醋的操作
- 过滤器分为两种
- 1:组件内的过滤器(组件内有效)
- 2:全局过滤器(所有组件共享)
局部过滤器的使用
- 先注册,后使用
- 组件内
filters:{ 过滤器名:过滤器fn }
最终fn内通过return产出最终的数据 - 使用方式是
{{ 原有数据 | 过滤器名 }}
- 需求
- 页面input框输入字符串, 另一边显示其反转的内容
- 过滤器fn:
- 声明
function(data,argv1,argv2...){return 结果}
- 使用
{{ 数据 | 过滤器名(参数1,参数2) }}
- 声明
全局过滤器的使用
语法:
Vue.component('过滤器的名字',fn)
调用:跟局部组件调用方式一样
- watch 监视单个
watch:{ //监视复杂类型,无法监视的原因是因为监视的是对象的地址 // obj:function(newV,oldV) { // console.log(newV,oldV); // }, // key是属于data属性的属性名,value是监视后的行为 fn中的参数(新值,旧值) msg:function (newV,oldV) { console.log(newV,oldV); if (newV==='alex') { console.log('sb'); } }, // 深度监视 :object ||array stus:{ deep:true,//深度监视 handler:function (newV,oldV) { console.log(newV[0].name) } }
基本数据类型 简单监视,复杂数据类型深度监视
- computed 同时监视多个属性
- Computed:{监视业务名:function(){ return 显示内容}}
- 使用:{{ 计算属性的名称 }}
- 默认computed只有getter方法
- Computed:{监视业务名:function(){ return 显示内容}}
1.3.6 slot(传递dom)
- 内置的组件
- slot就是子组件里给DOM留下的占位
- <子组件>DOM</子组件>
- slot动态的DOM、props是动态的数据
注:传递数据用props,传递dom用slot
1.4 获取DOM元素
- 救命稻草, document.querySelector
- 1: 在template中标识元素 ref=“xxxx”
- 2: 在要获取的时候, this.$refs.xxxx 获取元素
- 创建组件,装载DOM,用户点击按钮
- ref在DOM上获取的是原生DOM对象
- ref在组件上获取的是组件对象
- $el 是拿其DOM
- 这个对象就相当于我们平时玩的this,也可以直接调用函数
二 生命周期
1.1 定义:
每个 Vue 实例在被创建时都要经过从创建倒挂载再到更新、卸载的一系列过程,同时在这个过程中也会运行一些叫做生命周期钩子的函数,可以让我们用自己注册的js方法控制整个大局,在这些事件响应方法中的this直接指向的是vue的实例。
1.2 钩子函数的执行时间
beforeCreate 在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。
created 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用。
mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。
beforeUpdate 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。
还有两个特殊的(配合使用keep-alive):activated、deactivated
activated keep-alive组件被激活时调用
deactivated keep-alive组件被停用时调用
1.3 钩子函数中该做的事情
created 实例已经创建完成,因为它是最早触发的原因可以进行一些数据,资源的请求。
mounted 实例已经挂载完成,可以进行一些DOM操作
beforeUpdate 可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
updated 可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
destroyed 可以执行一些优化操作
keep-alive 在使用vue-router时有时需要使用来缓存组件状态,这个时候created钩子就不会被重复调用了,如果我们的子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发。
三 路由
3.1 路由原理
- 传统开发方式 url改变后 立刻发起请求,响应整个页面,渲染整个页面
- SPA 锚点值改变后 不会发起请求,发起ajax请求,局部改变页面数据,页面不跳转 用户体验更好
//haschange 事件 url上的部分锚点数据(#xxx)改变,可以获取到这个事件。
window.addEventListener('hashchange', function(){
console.log(location.hash);
})
3.2 SPA
- single page application(单页应用程序)
- 前端路由
- 锚点值监视
- ajax获取动态数据
- 核心点是锚点值
- 前端框架 Vue/angular/react都很适合开发单页应用
3.3 基本使用
- vue-router
- 其是vue的核心插件
- 1:下载
npm i vue-router -S
- 1.2(重要):安装插件
Vue.use(VueRouter);
- 2:在main.js中引入vue-router对象
import VueRouter form './x.js';
- 3:创建路由对象
var router = new VueRouter();
- 4:配置路由规则
router.addRoutes([路由对象]);
- 路由对象
{path:'锚点值',component:要(占位)显示的组件}
- 路由对象
- 5:将配置好的路由对象交给Vue
- 在options中传递-> key叫做 router
- 6:占位(使用组件)
<router-view></router-view>
3.4 router-link
- to
- 帮助我们生成a标签的href
- 锚点值代码维护不方便,如果需要改变锚点值名称
- 则需要改变 [使用次数 + 1(配置规则)] 个地方的代码
3.5 命名路由
- 1:给路由对象一个名称
{ name:'home',path:'/home',component:Home}
- 2:在router-link的to属性中描述这个规则
<router-link :to="{name:'home'}></router-link>"
- 通过名称找路由对象,获取其path,生成自己的href
- 大大降低维护成本,锚点值改变只用在main.js中改变path属性即可
var Login = {
template: '<div>我是登录页面</div>',
created: function(){
console.log(this.$route.query)
}
}
var Register = {
template: '<div>我是注册页面</div>',
created: function(){
console.log(this.$route.params)
}
}
//1. 安装插件
Vue.use(VueRouter);
//2.创建并配置一个路由对象
var router = new VueRouter({
routes:[
{name:'login', path : '/login',component:Login},
{name:'register', path : '/register/:name',component:Register},
],
});
// 3. 指定路由改变局部的位置
//router-link传参,query方式不需要在路由规则中占位,但是params方式就需要在路由规则中先占位
var App = {
template: '<div>' +
'<router-link :to="{name:'login',query:{id:1}}">登录去</router-link>' +
'<router-link :to="{name:'register',params:{name:'abc'}}">注册去</router-link>' +
'<router-view></router-view>' +
'</div>'
}
//4. 将配置好的路由对象关联到vue实例中
new Vue({
el: '#app',
router: router, //不加这一步,将会导致运行的时候出现 undefined对象中取不到matched
components:{
app: App,
},
template:'<app/>'
});
3.6 总结
3.6.1 vue-router使用步骤
1:引入 2:安装插件 3:创建路由实例 4:配置路由规则 5:将路由对象关联vue 6:占位
3.6.2 router-link :to="/xxx" 命名路由
在路由规则对象中 加入name属性
在router-link中 :to="{ name:"xxx’} "
3.6.3 生僻API梳理:
Vue.use(插件对象); // 过程中会注册一些全局组件,及给vm或者组件对象挂在属性
给vm及组件对象挂在的方式 :
Object.defineProperty(Vue.prototype,'$router',{
get:function () {
return 自己的router对象;
}
})
3.6.4 参数router-link
Vue.prototype.xxx = {add:fn}
- 所有组件中,使用this.xxx就能拿到这个对象
- 查询字符串
- 1:配置
:to="{name:'detail',query:{id:hero.id} }"
- 2:规则
{name:'detail',path:'/detail',component:Detail}
- 3:获取
this.$route.query.id
- 4:生成
<a href="/detail?id=1">
- 1:配置
- path方式
- 1:配置
:to="{name:'detail',params:{id:hero.id} }"
- 2:规则
{ name:'detail',path:'/detail/:id'}
- 3:获取
this.$route.params.id
- 1:配置
- 查询字符串配置参数
- router-link一次
- 获取的时候一次
- path方式配置参数
- router-link一次
- 规则配置的时候声明位置
- 获取的时候一次
- 总结书写代码注意事项
- path方式需要在路由规则中声明位置
3.6.5 vue-router中的对象
- $route 路由信息对象,只读对象
- $router 路由操作对象,只写对象
3.6.6 嵌套路由
多个组件,按照不同的锚点值部分设置不懂的占位
- 市面上所谓的用单页应用框架开发多页应用
- 嵌套路由
- 案例
- 进入我的主页显示:电影、歌曲
- 代码思想
- 1:router-view的细分
- router-view第一层中,包含一个router-view
- 2:每一个占位要对应单独的组件
- 1:router-view的细分
- 使用须知: 1:router-view包含router-view 2:路由children路由
var Login = {
template: '<div>' +
'我是login显示的内容,接下来是子路由显示的内容' +
'<router-view></router-view>' +
'</div>',
created: function(){
console.log(this.$route.query)
}
}
var Woman = {
template:'<div>' +
'这是女生登录' +
'</div>'
}
var Man = {
template:'<div>' +
'这是男生登录' +
'</div>'
}
var Register = {
template: '<div>' +
'我是register显示的内容,接下来是子路由显示的内容' +
'<router-view></router-view>' +
'</div>',
created: function(){
console.log(this.$route.params)
}
}
Vue.use(VueRouter);
var router = new VueRouter({
routes:[
{name:'register', path : '/register/:name',component:Register},
{name:'login', path : '/login/',component:Login,
children:[
{name:'login.woman', path:'woman', component: Woman},
{name:'login.man', path:'man', component: Man}
],
},
],
});
var App = {
template: '<div>' +
'<router-link :to="{name:\'login\'}">登录</router-link>' +
'<router-link :to="{name:\'login.woman\'}">女生登录</router-link>' +
'<router-link :to="{name:\'login.man\'}">男生登录</router-link>' +
'<router-view></router-view>' +
'</div>'
}
new Vue({
el: '#app',
router: router,
components:{
app: App,
},
template:'<app/>'
});
知识点介绍
- 路由meta元数据 -> meta是对于路由规则是否需要验证权限的配置
- 路由对象中 和name属性同级
{ meta:{ isChecked:true } }
- 路由对象中 和name属性同级
- 路由钩子 -> 权限控制的函数执行时期
- 每次路由匹配后, 渲染组件到router-view之前
router.beforeEach(function(to,from,next) { } )
练习
- 1: 使用koa 编写一个服务器…
- a. /login的请求… ctx.body = { msg:‘ok’}
前端用jq发送ajax请求
- a. /login的请求… ctx.body = { msg:‘ok’}
- 2: 客户端接收响应以后.如果是ok. localStroage中保存该值
- 3: 在全局路由守卫中,区分/login 不验证(meta), /show 要验证, 验证条件就是从localStorage中获取
编程导航
- 1: 跳到指定的锚点,并显示页面
this.$router.push({ name:'xxx',query:{id:1},params:{name:'abc'} });
- 2: 配置规则
{name:'xxx',path:'/xxx/:name'}
- 3: 根据历史记录.前进或后退
this.$router.go(-1|1);
- 1代表进一步,-1是退一步
四、axios
https://www.kancloud.cn/yunye/axios/234845
4.1 基本使用
Axios.method('url',[,..data],options)
.then(function(res){ })
.catch(function(err) { } )
4.2 合并请求
-
this.$axios.all([请求1,请求2]) .then( this.$axios.spread(function(res1,res2){ }) )
4.3 拦截器
- 单请求配置options:
axios.post(url,data,options);
- 全局配置defaults:
this.$axios.defaults
- config :
请求拦截器中的参数
- response.config
响应拦截器中的参数
- options
- baseURL 基础URL路径
- params 查询字符串(对象)
- transformRequest 转换请求体数据
- transformResponse 转换响应体数据
- headers 头信息
- data 请求体数据
- timeout 请求超时,请求多久以后没有响应算是超时(毫秒)
五 模块化
- webpack命令
npm init -y
npm install webpack@2.2.1 --save-dev --registry https://registry.npm.taobao.org
- package.json文件
"scripts": { "test": "webpack ./main.js ./build.js" },
- 命令行运行
npm run test
5.1 ES6模块
- 导入和导出只能存在顶级作用域
- require引入是代码执行的时候才加载
- import 和export 都是提前加载 ,加载在代码执行之前
导入导出
//index.html
import App from './app.js';
import {num1, num2} from './app.js';
//app.js
var app = {
template:'<h1>111</h1>'
}
export default app; //导出方式1
export var num1 = 11; //导出方式2
var num2 = 2;
export {num2}; //导出方式3
5.2 箭头函数和function
- 一方面箭头函数是种简写形式
- 应用场景: 由于箭头函数本身没有this和arguments,通常用在事件类的回调函数上,让其向上级function绑定this,而非事件对象
- 箭头函数不可以作为构造函数
<script>
var vueComponent = {
name :'jack',
created: function(){ //指向当前object对象,
console.log(this)
},
created2(){ //指向当前Object对象,代码更简洁
console.log(this)
},
created3:()=>{ //this会向上级function绑定,window
console.log(this);
}
}
<script>
5.3 ES6函数简写
- 用在对象的属性中
fn3() { //干掉了:function,用在对象的属性中
console.log(this);
},
5.4 key
- 使用子组件循环输出一堆数据
- 不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
- 建议v-for就写,提升性能,避免vue运算,key就是记录元素与dom间的位置关系
<son v-for="(item,index) in persons" :key="index" ></son>
5.5 slot
- slot就是子组件里给DOM的占位
- <子组件>DOM</子组件>
- slot动态的DOM、props是动态的数据
5.6 组件生命周期
- 需要频繁的创建和销毁组件
- 比如页面中部分内容显示与隐藏,但是用的是v-if
- 组件缓存
- 内置组件中
- 被其包裹的组件,在v-if=false的时候,不会销毁,而是停用
- v-if=“true” 不会创建,而是激活
- 避免频繁创建组件对象的性能损耗
- 成对比较
- created 和 beforeCreate
- A 可以操作数据 B 数据没有初始化
- mounted 和 beforeMount
- A 可以操作DOM B 还未生成DOM
- updated 和 beforeUpdate
- A 可以获取最终数据 B 可以二次修改
- 频繁销毁创建的组件使用内置组件包裹
- created 和 beforeCreate
activated(){ //激活的 keep-alive v-if="true"
console.log('activated')
},
deactivated(){ //停用的 keep-alive v-if="false"
console.log('deactivated')
},
beforeDestroy(){ //销毁前 v-if="false"
console.log('beforeDestroy')
},
destroyed(){//销毁后 v-if="false"
console.log('destroyed')
},
5.7 获取DOM元素
- 救命稻草, document.querySelector
- 1: 在template中标识元素 ref=“xxxx”
- 2: 在要获取的时候, this.$refs.xxxx 获取元素
- 创建组件,装载DOM,用户点击按钮
- ref在DOM上获取的是原生DOM对象
- ref在组件上获取的是组件对象
- $el 是拿其DOM
- 这个对象就相当于我们平时玩的this,也可以直接调用函数