vue--知识点总结

vue--知识点总结:

目录

1. v-if与v-show的区别

2. Vue的双向数据绑定原理

3.  Vue的生命周期

4. 封装 vue 组件的过程

 5. 理解vuex

6.vue页面间传值


1. v-if与v-show的区别

相同点:v-if与v-show都可以动态控制dom元素显示隐藏

不同点:v-if显示隐藏是将dom元素整个添加或删除,而v-show隐藏则是为该元素添加css--display:none,dom元素还在。

注意:

  1. 手段:v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐;
  2. 编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;
  3. 编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;
  4. 性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;
  5. 使用场景:v-if适合运营条件不大可能改变;v-show适合频繁切换。

2. Vue的双向数据绑定原理

 答:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。 具体步骤:

  • 第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter 这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
  • 第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
  • 第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
  1. 在自身实例化时往属性订阅器(dep)里面添加自己
  2. 自身必须有一个update()方法
  3. 待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
  • 第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

3.  Vue的生命周期

答:总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。

  • 创建前/后: 在beforeCreated阶段,vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,$el还没有。
  • 载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
  • 更新前/后:当data变化时,会触发beforeUpdate和updated方法。
  • 销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在

 (上图是网上找的,忘了出处啦,侵删)

4. 封装 vue 组件的过程

答:首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。

然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。

 5. 理解vuex

 vuex的核心是:state,getter,actions,mutations

  • state就是根据你项目的需求,自己定义的一个数据结构,里面可以放些通用的状态。建议使用mutations来改变state里面的值,因为不通过mutations改变state,状态不会被同步。至于mutations下面会讲到。 
  • getter怎么理解呢?通俗的理解可以认为是getter里的函数就是vuex里的计算属性,类似于computed函数。                    getter函数怎么用呢?如果vuex里定义了一个getter函数addNum。我们可以在vue文件里的computed计算属性里引用,如下。先引入vuex的文件,然后在当前文件的computed中引入你在vuex的getter中定义的函数addNum。
  • 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutations 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:(需要注意:Mutations必须是同步函数。如果我们需要异步操作,Mutations就不能满足我们需求了,这时候我们就需要Actions了。
  • Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。(如果我在vue页面里想用action,我们可以分发 Action,Action 通过 store.dispatch 方法触发:)
  • mutations由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

总结:mutation 只管存,你给我(dispatch)我就存;action只管中间处理,处理完我就给你,你怎么存我不管(所有的改变state状态的都是mutation 来操作);Getter 我只管取,我不改的(类似计算属性)。 

6.vue页面间传值

一、父组件向子组件传递数据通过props

     父组件:使用v-bind传值

      子组件:使用props接收

父组件:
<header-box v-bind="message"></header-box>

子组件:
 props: {
      message: String
 },

二、子组件向父组件传值 (参考的vue组件之间的通信来完成,侵删)

子组件向父组件传递分为两种类型:

  1. 子组件改变父组件传递的props(你会发现通过props中的Object类型参数传输数据,可以通过子组件改变数据内容。这种方式是可行的,但是不推荐使用,因为官方定义prop是单向绑定)
  2. 通过$on和$emit
**父组件代码**
<template>
    <div id="counter-event-example">
      <p>{{ total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</template>
<script>
    import ButtonCounter from './buttonCounter'
    export default {
        name: 'index',
        components: {
            'button-conuter': ButtonCounter
        },
        data () {
            return {
                total: 0
            }
        },
        methods: {
            incrementTotal () {
                this.total++
            }
        }
    }
</script>
**子组件代码**
<template>
    <button @click="incrementCounter">{{counter}}</button>
</template>
<script>
    export default {
        name: 'button-counter',
        data () {
            return {
                counter: 0
            }
        },
        metheds: {
            incrementCounter () {
                this.$emit('increment')
                this.counter++
            }
        }
    }
</script>

三、同级传参的两种方式:

  1. query传参,或者params传参

 使用

this.$router.push({ path:'路径值' , query: { 参数名: '参数值' }})

this.$router.push({name: '路由名',params: {参数名: '参数值'}})

   注意1:使用params时不能使用path   

  接收:

var a = this.$route.query.参数名

var b = this.$route.params.参数名

  注意:接收传来的值时,最好把接收值的方法放在钩子函数中触发,或者在路由守卫beforeRouteEnter、beforeRouteLeave,  并且使用watch来监听(可以自己搜一下,在钩子函数和路由守卫中触发的区别)

代码示例:

watch: {
    // 监测路由变化,只要变化了就调用获取路由参数方法将数据存储本组件即可
    '$route': 'getParams'
},
beforeRouteEnter (to, from, next) {
    next(vm =>{
      vm.getParams();
    })
},
beforeRouteLeave(to, from, next) {
    next(vm =>{
      vm.getParams();
    });
}, 
methods: {
    getParams:function(){
      var pid = this.$route.query.pid;
    },
}

注意2:实用params去传值的时候,在页面刷新时,参数会消失,用query则不会有这个问题。

四、vue组件之间使用bus(总线/观察者模式)传值

  • 创建Bus.js
import Vue from 'vue'
 
const Bus = new Vue();
 
export default Bus
  • 在需要通信的两个组件中引入Bus
import Bus from '@/components/utils/Bus.js';
  • 发送消息
Bus.$emit('消息名', 消息值);
  • 接收消息

      接受组件的事件:写在钩子函数内:例如:mounted   created都可以

Bus.$on('msg', (e) => {
   this.num = e;
})

五、通过设置Session Storage缓存的形式进行传递

  •    两个组件A和B,在A组件中设置缓存orderData
const orderData = { 'orderId': 123, 'price': 88 }
sessionStorage.setItem('缓存名称', JSON.stringify(orderData))
  •    B组件就可以获取在A中设置的缓存了
const dataB = JSON.parse(sessionStorage.getItem('缓存名称'))

注意:了解一下 Session Storage(程序退出销毁) 和 Local Storage(长期保存) 的区别。

四、vuex

7. vue样式的切换及vue动态样式的使用

  1. vue中style与class绑定API
<div id="wrap" class="box">
  <div v-for="(list,index) in navLists" class="nav" 
       :class="{ red:changeRed == index}" 
       @click="reds(index)"
   >
        {{list.text}}
   </div>
</div>

css和js:

*{
    padding: 0;margin: 0;
 }
 .box{
    height: 40px;
    background: cyan;
 }
 .nav{
    line-height: 40px;
    display: inline-block;
    margin-left: 100px;
    cursor: pointer;
 }
 .red{
    color: red;
 }
  
//前提是必须引入vuejs哦!
var vm = new Vue({
      el:"#wrap",
      data:{
        navLists:[
          {
            "text":"首页"         
          },
          {
            "text":"组件"         
          },
          {
            "text":"API"          
          },
          {
            "text":"我们"         
          }
        ],
        changeRed:0
      },
      methods:{
        reds:function(index){
          this.changeRed = index;
        }
      }
    });

2. 动态样式的解决方法

  • 方法1
:class="{active: isActive}"

通过改变isActive是否为true和false来动态改变样式

  • 方法2
class="[lineStyle(courseClick)]"

lineStyle(isClick){
  if (isClick===true){
    return 'tab-items-current'
  }else {
    return 'class-tab-items'
  }
}

3. v-show和v-if来控制元素的显示、隐藏(上面有说明)

8. vue路由传参3种的基本模式

在vue路由中,支持3种传参方式:

<li v-for="info in indexInfo" @click="getIndexInfo(indexInfo.id)">
  • 方案一:
getIndexInfo(id) {
// 直接调用$router.push 实现携带参数的跳转
    this.$router.push({
     path: `/home/${id}`,
    })
 
// 方案一,需要对应路由配置如下:
  {
   path: '/home/:id',
   name: 'home',
   component: home
  }
// 很显然,需要在path中添加/:id来对应 $router.push 中path携带的参数。
 
// 在子组件中可以使用来获取传递的参数值。
$route.params.id

 

   

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章