Vue 学习笔记(一)

123 阅读4分钟

Vue 学习笔记

Vue 是什么呢?

​ Vue.js 是一套构建用户界面的渐进式框架,只关注视图层,采用自底向上增量的开发设计,实现双向数据绑定及组件化设计。vue 中响应双向绑定数据实现是建立在Object.defineProperty方法上,通过访问器get set 进行属性数据拦截。

Vue执行的流程:

​ (html -> AST -> )生成渲染函数(Render) -> vNode -> DOM

​ Vue.js 为了给开发者提供便利,提供了一系列的内置指令,来实现数据的响应式,更新DOM。同时,开发者可根据自己需求进行自定义指令。那什么是指令呢,又该如何使用呢?

指令与自定义指令

​ 指令是带有 v- 前缀的特殊attribute。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式的作用于DOM。常用的指令有:v-text、v-html、v-bind、v-model、v-on、v-for、v-if、v-show 等等。

​ 指令的生命周期为:

  • bind: 绑定元素
  • inserted
  • update
  • componentUpdated
  • unbind

v-text: 更新元素的innerText内容信息

v-html: 更新元素的innerHtml内容

v-bind:属性 :用于响应式的更新 Attribute(Html Attribute / 自定义Attribute),也可以简写成 :属性,如v-bind:id 可以写成:id 。绑定数据(表达式/对象/)到指定的属性上,如<div v-bind:参数="值/表达式"></div>

<div id="app">
    <a v-bind:href="url">跳转</a>
    <a :href="url">简写跳转</a>
    <a v-bind:href="'url'">表达式跳转</a>
</div>
<script>
    new Vue({
        el: "#app",
        data: {
            url: "https://google.cn"
        }
    })
</script>

v-model: 表单元素上创建双向数据绑定,监听用户输入事件进行更新数据

<div id="app">
    <input v-model="message" placeholder="请输入">
	<p>Message is: {{ message }}</p>
</div>	

v-on: 绑定事件,语法如:

,可简写为:<div @:click="click">

<div id="app">
    <div v-on:click="click"></div>
</div>
<script>
    new Vue({
        el: "#app",
        methods: {
            click: function(){
                console.log('click,此处不能用箭头函数')
            }
        }
    })
</script>

v-if、v-show,条件渲染指令

v-if: 根据表达式值的真假,销毁或重建元素,适用于状态切换不频繁的情况

v-show: 根据表达式值的真假,切换元素的display css 属性,适用于状态切换比较频繁的情况

自定义指令

​ 当我们想对一些DOM元素进行低层操作时,这时候我们就可以用到自定义指令。

​ 通过 Vue.directive 或者 在 配置项 中添加directives配置,进行全局/局部指令注册。

​ 如:

Vue.directive('指令名称', {指令配置});

new Vue({
  el: '#app',
  directives: {
    '指令名称': {指令配置}
  }
});

​ 使用:

<div id="app">
    <input v-focus>
</div>
new Vue({
  el: '#app',
  directives: {
    'focus': function(el){
		el.focus()
	}
  }
});

Vue 中我们会使用不同的组件进行复用,比如头部,底部,侧边、dialog、modal 等组件,那么关于组件,我们又该了解什么呢?接下来我们来分析下Vue Componment 组件的使用。

Vue component 组件

Component 可以扩展HTML 元素,封装可重用的代码,一个组件系统可以用多个可复用的小组件来进行组合。

可以通过Vue.component 全局注册 或者 在Vue 根实例上加入components 属性进行局部注册。

如:

<div id="app">
    <login></login>
</div>
 
<script>
Vue.component('login', {
  template: '<h1>Login组件!</h1>'
})
new Vue({
  el: '#app'
})
</script>

或者:
<script>
    var Login = {
        template: '<h1>Login组件!</h1>'
    }
new Vue({
  el: '#app',
  components: {
      'login': Login
  }
})
</script>

而组件的生命周期跟Vue实例的生命周期是一样的:

  • 创建(前/后)

    • beforeCreate()
      • 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。初始化阶段,应用不多。
    • created()
      • 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),property 和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el property 目前尚不可用。
      • 常用于异步数据的获取、初始化数据
  • 挂载(前/后)

    • beforeMount()
      • 在挂载开始之前被调用:相关的 render 函数首次被调用。
    • mounted()
      • 该阶段执行完了模板解析,以及挂载。同时组件根组件元素被赋给了 $el 属性,该阶段可以通过 DOM 操作来对组件内部元素进行处理了。
      • 挂载元素dom节点的获取
  • 更新(前/后)

    • beforeUpdate()
      • 数据更新时调用,但是还没有对视图进行重新渲染,这个时候,可以获取视图更新之前的状态。
    • updated()
      • 由于数据的变更导致的视图重新渲染,可以通过 DOM 操作来获取视图的最新状态。
  • 卸载销毁(前/后)

    • beforeDestroy()
      • 实例销毁之前调用,移除一些不必要的冗余数据,比如定时器。
    • destroyed()
      • Vue 实例销毁后调用。
  • 其他

    • $nextTick()
      • 将回调延迟到下次dom更新循环之后执行。

data 作为组件内部的私有属性,必须是函数。并且该函数必须返回一个对象。

很多时候,为了提供函数的复用性,我们的子组件需要接收外部的数据,那么我们可以通过Props 选项来接收(父组件到子组件的内部数据传递)。在使用中,我们在使用组件时候,通过标签属性的方式进行传参,用v-bind="key" 进行传值。

<div id="app">
    <login v-bind:name="name" v-bind:length="passwordLen"></login>
</div>
 
<script>
Vue.component('login', {
  template: '<h1>Login组件!</h1>',
    props: ['name', 'length']
})
new Vue({
  el: '#app',
  data: {
  	"name": "Mark",
    "passwordLen": "6"
  }
})
</script>

同时,我们可以对props的属性值进行数据类型必要的验证及默认值设定。

如:

<div id="app">
    <login v-bind:name="name" v-bind:length="passwordLen"></login>
</div>
 
<script>
Vue.component('login', {
  template: '<h1>Login组件!</h1>',
    props: {
        name: {
            type: String,
            default: "测试"
        },
        length: {
            type: Number,
            default: 6
        },
        types: {
            validator: function(value) {
                return ['man', 'women'].indexOf(value) !== 1
            }
        }
    }
})
new Vue({
  el: '#app',
  data: {
  	"name": "Mark",
    "passwordLen": "6"
  }
})
</script>

在很多时候,有些数据我们需要通过几个属性或者执行计算逻辑才能得出结果,这时,Computed 及 watch 就很有用了。

Computed

computed 中每个key对应一个data中的属性,该属性通过getter/setter的方式进行定义。

如:

<div id="app">
  <p>fullName (computed):{{ fullName }}</p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    firstName: 'Mark',
    lastName: 'Yuan',
  },
  computed: {
    fullName: {
      get: function() {
        return this.firstName + ' ' + this.lastName;
      },
      set: function(newValue) {
        var name = newValue.split(' ');
        this.firstName = name[0];
        this.lastName = name[name.length - 1];
      },
    },
  },
});

当我们更改fullName的值时,firstName 及 lastName 同时也会更改。

vm.fullName= 'Jay Zhou', 则 vm.firstName 就变成了 Jay 而 vm.lastName 则为Zhou

当然,method 也能实现 Computed 的效果,但是computed是根据关联数据监听改变时才进行计算,计算结果会被缓存起来,而method则不管有没有关联数据监听,都会进行重新计算。

所以,如果需要每次更新,则就用method,而只需要在某个数据更新时才要更新,则用computed

而同样,watch 也能实现跟computed同样的效果。

watch

watch 选项是对指定的响应式数据进行观察,进行处理一些逻辑事务。跟computed 实现有些类似。

<div id="app">
  <p>fullName (computed):{{ fullName }}</p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    firstName: 'Mark',
    lastName: 'Yuan',
	fullName: 'Mark Yuan'
  },
  watch: {
    firstName: function(val){
       this.fullName = this.firstName + ' ' + this.lastName
    },
	firstName: function(val){
       this.fullName = this.firstName + ' ' + this.lastName
    },
  },
});

watch 更像是data数据的监听回调。当依赖data的数据变化后,执行回调,在方法中传入newVal 和 oldVal。Vue实例将会在实例化时调用$watch(),遍历watch对象中的每一个属性,当某个数据变化时,则就会触发watch。

但是computed跟watch看是乎很相似,那么各自的运用场景在哪比较合适呢?

watch:

  • 当在data中某个数据发生变化时,我们需要做一些操作,或者当需要在数据变化时进行异步执行/开销比较大的操作时,可以使用watch来进行监听。
  • 一对多的数据更新

computed:

  • 使用于一些重复使用的数据或复杂及费时的运算,可以利用computed的缓存特性,下次就可以直接获取了。
  • 依赖于其他的数据

以上是我个人见解,如有错误,请多指示。(部分概念从官网摘录)