1.vue使用虚拟DOM减少真实DOM
虚拟dom本质就是内存中的一个对象 ,该对象和dom结构相对应
操作提高页面的渲染效率
###实例
new vue({
el:'#app',
data:{
},
methods:{
}
})
###数据绑定
将data里的数据通过{{}}绑定到视图上
###指令
内置指令
v-for 列表渲染 v-for = '数组里的每一项 in/of 要循环的数据'
v-on @ 事件绑定 v-on:事件名 处理函数写在实例里的methods里面
在事件中 处理函数默认参数是实践对象
在事件里传递参数 就没有事件对象 如果需要通过$event 手动传递
$event 在vue中表示事件对象
v-if 条件渲染 true/false v-if='true/false' true 渲染 false 不渲染
v-show
v-bind:要绑定的属性='变量或者表达式'
v-bind:src = :src
v-text:会把标签显示出来
v-html:会解析标签
2.父子组件在生命周期执行顺序
1.1.挂载阶段
该过程主要涉及 beforeCreate、created、beforeMount、mounted 4 个钩子函数。执行顺序为: 父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted 一定得等子组件挂载完毕后,父组件才能挂在完毕,所以父组件的 mounted 在最后。
1.2.更新阶段
该过程主要涉及 beforeUpdate、updated 2 个钩子函数。注意,当父子组件有数据传递时,才有这个更新阶段执行顺序的比较。执行顺序为: 父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated
1.3.销毁阶段
该过程主要涉及beforeDestroy、destroyed 2 个钩子函数。执行顺序为: 父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
1.4.总结 Vue 父子组件生命周期钩子的执行顺序遵循:从外到内,再从内到外。
3.vue的生命周期
这里介绍常用的 8 个。
1.beforeCreate:实例创建前执行。
el 和 data 都为 undefined,还未初始化。methods、computed 以及 watch 上的数据或方法均不能被访问。
2.created:实例初始化完成后执行。
页面还没开始渲染,不可访问 DOM 节点。el 仍然为 undefined。但可以操作 data 与 methods 等。可以做一些初始数据的获取,在当前阶段无法与 DOM 进行交互,如果需要,可以通过 $nextTick 来访问 DOM。
3.beforeMount:挂载前执行。
el 和 data 都初始化了,虚拟 DOM 已经创建完成,即将开始渲染。
4.mounted:页面渲染完毕时执行。
真实的 DOM 挂载完成,可访问 DOM 节点。可使用 refs 对 DOM 进行操作。也可以向后台发送请求。
5.beforeUpdate:数据发生更新时执行。
此时 Vue 实例中的数据是最新的了,但是页面中的数据还是旧的,可以在此时进一步更改数据,而不会造成重新渲染。
6.updated:数据发生更新导致的 DOM 重新渲染完成时执行。
此时 DOM 已经更新,可以执行 DOM 相关操作。
7.beforeDestroy:实例销毁前执行。
实例仍然完全可以使用。在此阶段一般进行善后工作,如清除计时器、解除绑定等。
8.destroyed:实例销毁完成。
实例绑定的所有东西都会被解除,如解除事件监听和对 DOM的数据绑定,所有子实例也统统被销毁,组件被拆解将无法使用。改变 data 也不会再重新渲染,但是 DOM 结构依然存在。
4.自定义指令
全局自定义指令
vue.directive('指令名',{
inserted(el){ //
e.innerHTML='全部'
}
})
局部自定义指令
局部在哪些哪有用
directives:{'指令名':{
inserted(el){
e.innerHTML='局部'
}
}}
5.自定义组件
全局组件
1,创建组件 vue.extend({配置项})
2,注册组件
3,使用组件 将组件名当成标签使用
创建注册组件, 将组件名当成标签名使用
vue.component('组件名',{
template:'
这里是组建
'})
let component = Vue.extend({
• template:'<h1>哈哈哈哈</h1>'
• })
• Vue.component('hehe',component)
局部组件
1,创建组件
2,注册组件
3,使用组件
注册到配置项里的components里
{
el:'',
components:{
'组件名':'组件'
}
}
let component = Vue.extend({
• template:'<h1>哈哈哈哈</h1>'
• })
• components:{
• hehe:component
• }
6.vue脚手架工具安装
npm install @vue/cli -g
vue -V 监测版本号
vue create 项目名字
进入项目目录下 npm run serve
7.全局组件嵌套
全局组件没有固定的嵌套关系 随着书写方式不同嵌套关系也不一样
<body>
<div id="app1">
• <son></son>
• </div>
• <!-- 组件模版 -->
• <template id="tp1">
<div id="tp1">
• 这是组件1
• </div>
• </template>
• <template id="tp2">
<div id="tp2">
• 这是组件2
• <father></father>
• </div>
• </template>
• <!-- 全局组件没有固定的嵌套关系 随着书写方式不同嵌套关系也不一样 -->
<script>
• Vue.component('father',{
• template:'#tp1',
• })
• Vue.component('son',{
• template:'#tp2',
• })
• let vm1 = new Vue({
• el:'#app1',
• data:{
• name:'实例1'
• }
• })
• </script>
</body>
8.局部组件
<body>
<div id="app1">
• <tp1></tp1>
• </div>
• <!-- 组件模版 -->
• <template id="tp1">
<div id="tp1">
• 这是组件1
• <tp2></tp2>
• </div>
• </template>
• <template id="tp2">
<div id="tp2">
• 这是组件2
• </div>
• </template>
• <!-- 局部组件在注册的同时已经确认了嵌套关系 -->
<script>
• let vm1 = new Vue({
• el:'#app1',
• data:{
• name:'实例1'
• },
• components:{
• tp1:{template:"#tp1",
• components:{
• tp2:{template:"#tp2"}
• }
• },
• // tp2:{template:"#tp2"}
• }
• })
• </script>
</body>
9.组件通信
1父传子
通过props 自定义属性 将父组件的数据传递给子组件 子组件可以使用父组件的的数据
父组件的数据发生改变之后 子组件也会更新
props 传递的数据 子组件不能修改只能使用7
2子传父 自定义事件
子组件控制父组件的数据
子组件的$emit 可以触发绑定在组件身上的自定义事件
this.$emit('自定义事件名',传递的参数)
3亲兄弟
可以状态提升
将要改变的数据 和 改变数据的方法 放在共用的父级上
通过自定义属性 和 自定义事件结合实现通信
4非亲兄弟
事件总线 eventbus vuex
1.创建一个空的vue实例对象
2.通过vue 里的$on 可以注册一个事件
3.通过vue 里的$emit 可以触发注册的事件
<body>
<div id="app">
• <tp1></tp1>
• <tp2></tp2>
• </div>
• <!-- 组件模板 -->
• <template id="tp1">
<div>
<div class="demo" v-if="show">
• </div>
• </div>
• </template>
• <template id="tp2">
<div >
• <button @click="toggle">toggle</button>
• </div>
• </template>
<script>
• let vm = new Vue()
• Vue.component('tp1',{
• template:'#tp1',
• data(){
• return{
• show:true,
• }
• },
• methods:{
• toggle1(){
• this.show =!this.show
• }
• },
• created(){
• console.log(vm);
• vm.$on('hehe',this.toggle1)
• },
• })
• Vue.component('tp2',{
• template:'#tp2',
• methods:{
• toggle(){
• vm.$emit('hehe')
• }
• }
• })
• new Vue({
• el:'#app',
• data:{
• }
• })
• /*
• 事件总线 eventbus
• 1.创建一个空的vue实例对象
• 2.通过vue 里的$on 可以注册一个事件
• 3.通过vue 里的$emit 可以触发注册的事件
• */
• </script>
</body>
10.过滤器
全局过滤器:
Vue.filter('过滤器名字',(data)=>{
data 要过滤的数据
数据处理
返回数据
})
使用过滤器
{{过滤数据|过滤器的名字}}
局部过滤器:
eg:
<body>
<div id="app">
• {{time|hehe}}
• <hr>
• {{time|hehe('/')}}
• <hr>
• {{time|hehe('-')}}
• </div>
<script>
• // 全局过滤器
• Vue.filter('hehe',(data,tag)=>{
• var tag= tag || '.'
• let y =(new Date(data)).getFullYear()
• let m =(new Date(data)).getMonth()+1
• let d =(new Date(data)).getDate()
• console.log(data)
• return `${y}${tag}${m}${tag}${d}`
• })
• new Vue({
• el:'#app',
• data:{
• time:(new Date()).getTime()
• },
• //局部过滤器
• filters:{
• hehe:(data,tag)=>{
• var tag= tag || '.'
• let y =(new Date(data)).getFullYear()
• let m =(new Date(data)).getMonth()+1
• let d =(new Date(data)).getDate()
• console.log(data)
• return `${y}${tag}${m}${tag}${d}`
• }
• }
• })
• /*
• 过滤器:
• 全局过滤器:
• Vue.filter('过滤器名字',(data)=>{
• data 要过滤的数据
• 数据处理
• 返回数据
• })
• 使用过滤器
• {{过滤数据|过滤器的名字}}
• 局部过滤器:
• */
• </script>
</body>
11.计算属性
computed
计算属性是一个对象
对象里的key值可以直接当成data的数据使用
计算属性一般和data里的数据建立联系
关联发生改变 计算属性会重新计算
计算属性的缓存性 只有相关联的数据发生改变计算属性才会重新执行
watch
监听某一个数据改变
参数1 改变之后的值 参数2 改变之前的值
watch 内部 所有dom元素都是改变之前
Watch 和 computed的区别
1.computed支持缓存,只有依赖数据发生改变,才会重新进行计算;而watch不支持缓存,数据变,直接会触发相应的操作
2.computed不支持异步,当computed内有异步操作时无效,无法监听数据的变化,而watch支持异步
3.computed属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值;而watch监听的函数接收两个参数,第一个参数是最新的值,第二个参数是输入之前的值
4.computed:一个属性受到多个属性影响,如:购物车商品结算。
watch:一个数据影响多条数据,如:搜索数据。数据变化响应,执行异步操作,或高性能消耗的操作,watch为最佳选择
\