吐血整理-Vue学习笔记

学习一个新内容时,最好的方式就是跟随官方文档来进行学习。
以下的学习也是基于Vue的官方文档:https://cn.vuejs.org/v2/guide/

文章目录

      • 概述
      • 1、引入
      • 2、基本使用
      • 3、vue的页面标签
      • 4、组件
      • 5、实例属性与方法
      • 6、生命周期-主要有几个周期相关的方法
      • 7、模板语法
      • 8、计算属性
      • 9、对象语法
      • 10、条件渲染
      • 11、列表渲染
      • 12、监听事件
      • 13、表单控件绑定
      • 14、深入原理
      • 15、注册自定义指令
      • 待续

概述

现在说到前端三大框架,一般都是指这三个:AngularReactVue
其中,Angular是一整套的前端解决方法,相比ReactVue要厚重得多,所以相对来说学习成本也就更高。但熟悉了之后的Angula仍是很多大型前端的很好的一个选择。
ReactVue,相对来说,React更接近原生、更易于理解。
Vue相对而言封装了更多的方法,提供了更便捷的使用。而且Vue的学习曲线相对于这三大框架来说,可以说是最简单的。这可能与Vue是国内作者开发,更加贴近国人使用习惯也有一定关系吧。

注:
	Angular是Google开发
	React是FaceBook开发

之前项目用到了Vue,当时学习Vue的时候做了笔记并进行了分享,故现将当时的笔记稍微整理一下发上来回顾一下,互相学习。

1、引入

2、基本使用

界面上定义标签

	<div id="app">
	  {{ message }}
	div>

js里定义Vue,以操作vue实体的方式操纵页面元素。

	var app = new Vue({
	  el: '#app', //用字段代表页面标签
	  data: { //数据实体,以下数据直接通过{{}}引用
		message: 'Hello Vue!', //对应界面上的{{message}}
		seen: true,
		test1: 1,
		todos: [{a:1,b:2},{a:1,b:2},{a:1,b:2}],
		isActive: true,
		hasError: false,
		activeClass: 'active',
		errorClass: 'text-danger'
	  },
	  method: {  //方法体
			reverseMessage: function () {
				this.message = this.message.split('').reverse().join('');
			}
	  },
	  computed: { //计算属性,可以作为根实体属性一样引用
			active: function(){
				return true;
			},
			message2: function(){
				return this.message + "_2";
			}
	  },
	  watch: { //监控实体元素的值变动 val当前新值, oldVal 改变前的值
		message: function (val, oldVal) {
                this.clearData();
                this.refresh();
            }
	  }

	});

3、vue的页面标签

  • v-bind:title="message":绑定标签的title事件,message即为上面定义的message,此种方式可以直接引用。无法这么使用:title={{message}}
  • v-if="[表达式]":vue的if 语句,直接替换[表达式]即可,如: v-if="seen"v-if="test1 == 1", 表达式通过,则显示该标签,否则不显示
  • v-for="todo in todos":循环,使用如下:
    • {{ todo.a }}
    • :带上了for所在的标签进行循环
    • :循环template内的内容
  • v-on:绑定一个事件监听器, 如
  • v-model:实现表单输入和应用状态之间的双向绑定,如:

    {{ message }}

    (修改input内的值,对应message的值就修改,于是

    内容就会改变)

  • v-once:一次性地插值,当数据改变时,插值处的内容不会更新, 如:

    {{ message }}

  • v-html:直接替换html,而不是数据值,如:

4、组件

组件是可复用的 Vue 实例,且带有一个名字。在这个例子中是

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: ''
})
语法为:Vue.component([组件名], [组件参数], template),其中 template 即为组件的内容填充模板。

我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用,且与 new Vue 接收相同的选项:


<div id="components-demo">
  <button-counter>button-counter>
div>
调用标签,就会自动写入上面定义里模板template里的内容
//js中使用自定义组件
new Vue({ el: '#components-demo' })

注:

  • 组件可以复用,产生多个实例
  • data必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。(即组件设置的值是全局的,通过方法返回的,则可以生成多个副本)

5、实例属性与方法

vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $,以便与代理的 data 属性区分。
如:app.$el:获取Vue实例关联的页面标签元素(详情参照步骤2)。
app.$el === document.getElementById('app') (输出结果为:true)

//示例代码:
var app = new Vue({
	  el: '#app', //用字段代表页面标签
	  data: { //数据实体,以下数据直接通过{{}}引用
		message: 'Hello Vue!', //对应界面上的{{message}}
	  }
});

6、生命周期-主要有几个周期相关的方法

beforeCreate: 初始化标签、方法前
在实例初始化之后,数据观测(data observer)和event/watcher 事件配置之前调用
created: 初始化标签、方法后
实例已经创建完成之后被调用,在这一步,实例已经完成以下的配置:数据观测(data observer)、属性和方法运算、watch/event 事件回调
beforeMount: 创建了vue实体的el标签前
在挂载开始之前被调用,相关的 render 函数首次被调用
mounted
el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
beforeUpdate
(数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。)
updated
(由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。)
activated: (keep-alive 组件激活时调用。)
deactivated: (keep-alive 组件激活时调用。)
beforeDestroy:vm.$destroy()调用前
(实例销毁之前调用。在这一步,实例仍然完全可用)
destroyed
(Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。)

7、模板语法

  1. 绑定数据:任意位置使用{{}}, 如

    {{message}}

    :将数据解释为纯文本
  2. 输出真正的 HTML,如:
    :div的内容会被替换成为rawHtml,直接作为HTML。注意,你不能使用 v-html 来复合局部模板
  3. 标签属性绑定,如:
    即为:

    即为:
    等等
  4. 正常的JavaScript表达式都可以,如: {{ message.split('').reverse().join('') }}
    等。
    有个限制就是,每个绑定都只能包含单个表达式:
    {{ if (ok) { return message } }} 不会生效,
    {{ok ? message : ""}}才可以
  5. 缩写: v-bind:id="1" --> :id="1" v-on:click="test" -->
    @click="test"

8、计算属性

就是调用一个有返回值的方法,将这个方法名当为一个参数来使用。这个方法名的使用,就是计算属性。
如:{{message}}是直接用data绑定的一个值,但假设现在message需要通过一些实时计算等,来生成最终值,那就可以用到计算属性。
计算属性关键字为:computed
写法为:在声明Vue的时候进行定义,每个计算属性,都用写方法的方式进行定义,如下:
message2在界面上类似message的方式进行调用:{{message2}},这个message2会实时根据message的变化而变化。)

//示例代码:
var app = new Vue({
	  el: '#app', //用字段代表页面标签
	  data: { //数据实体,以下数据直接通过{{}}引用
		message: 'Hello Vue!', //对应界面上的{{message}}
	  },
	  computed: { //计算属性,可以作为根实体属性一样引用
			active: function(){
				return true;
			},
			message2: function(){
				return this.message + "_2";
			}
	  },
});

9、对象语法

  • v-bind:class: 通过[class名]:[true/false],动态添加class。
    :前的class根据:后的true/false决定是否加载, 还可以与前面的正常class并存,如:

    等同于

    (注:active是数据值,也可以是计算属性)
  • :语法数组,
    v-bind:class=""里面可以通过一个式子带入多个class
  • 组件-例子:(参考4)
    Vue.component('my-component', {template: '

    Hi

    '})

    component声明,第一个参数my-component为模板上的标签名,第二个参数里的template字段,代表需要替换上模板里的具体内容,且替换后原本模板上的属性也会保留,如class等。
    示例:
	//界面上
	<my-component class="baz boo"></my-component>

	//js里 		
	Vue.component('my-component', {
		template: '

Hi

'
}) //最终界面被渲染为 <p class="foo bar baz boo">Hi</p>
  • v-bind:style:绑定style, 类似class。且,使用需要特定前缀的 CSS 属性时,如transform,Vue.js 会自动侦测并添加。
    可以使用data绑定,也可以使用计算属性,都是直接写入就可以,不需要带上{{}}
    示例:
	
	<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">div>
	
	
	<div v-bind:style="styleObject">div>` 	

10、条件渲染

  • v-if:用法如下:
<h1 v-if="ok">Yesh1> 		
<h1 v-else>Noh1>
<div v-if="type === 'A'">Adiv> 	
<div v-else-if="type === 'B'">Bdiv> 		
<div v-else>Not A/B/Cdiv>

注:
v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

  • key管理可复用元素:
    如下,只显示其中一个template,但对于input已输入的值,不管切换显示哪个template,已经输入的input的值都会传承下来,只会替换inputplaceholder值。
    换句话说,就是template里面相同的标签不会重新渲染,只会相应的替换掉里面的不同。
    key的作用,就是给Vue去区分两个templateinput是不是同一个。这样,切换template的时候,不同的input就会重新渲染,即删除了原来的input,重新写了一个input
<template v-if="loginType === 'username'">
	<label>Usernamelabel>
	<input placeholder="Enter your username"> 		
template> 		

<template v-else>
	<label>Emaillabel>
	<input placeholder="Enter your email address"> 		
template> 	
	
 		
<template v-if="loginType === 'username'">
	<label>Usernamelabel>
	<input placeholder="Enter your username" key="t1"> 		
template> 	
	
<template v-else>
	<label>Emaillabel>
	<input placeholder="Enter your email address" key="t2">
template>
  • v-show:类似v-if,通过条件控制后面内容显不显示。
    v-show=false,是将控件设置为 display:none
    v-if=false,是直接不执行那一块的代码了。
    所以:
    v-if 有更高的切换开销,因为每切换一次,就得渲染 / 删除一次元素。
    v-show有更高的初始渲染开销,即初始化的时候就已经渲染好了元素,只是根据v-show的结果来设置display而已,此后的切换,也只是修改display值。
    因此:
    如果需要非常频繁地切换,则使用 v-show 较好;
    如果在运行时条件不太可能改变,则使用 v-if 较好。

  • v-for:具有比 v-if 更高的优先级

11、列表渲染

  • v-for="(item, index) in items"item是当前元素,index是当前序号,items是列表内容,也可以是计算属性,还可以是带返回值的方法.
  • 同前面所说的,直接标签内含 v-for,标签本身也一起循环,如:

    {{item.a}}


    使用template,则里面的内容才进行循环,如:
  • {{ todo }}
  • forif可以在同一标签内使用,且for优先级高于if
  • key值: 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。
    为了给 Vue 一个提示,以便它能跟踪每个节点的身份,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有唯一 id。
    示例:
	<div v-for="item in items" :key="item.id">
		
	div>
  • 由于 JavaScript 的限制, Vue 不能检测以下变动的数组:
    1、当你利用索引直接修改一个值时,例如:vm.items[indexOfItem] = newValue
    2、当你直接修改数组的长度时,例如:vm.items.length = newLength
    为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue相同的效果, 同时也将触发状态更新:

    • Vue.set方法:Vue.set(items, indexOfItem, newValue)
    • Array.prototype.splice方法:items.splice(indexOfItem, 1, newValue)

    为了解决第二类问题,你可以使用

    • splice方法:items.splice(newLength)

12、监听事件

  • click:直接在引号中可以书写方法,如:
  • $event:当前事件,类似this的使用。如:
  • 一些其他的事件监听:keyup.enterkeyup.tabkeyup.esc
    写法示例:

13、表单控件绑定

使用v-model在元素上指定,可以与其他地方创建数据绑定,即修改一个地方的值,其他地方也对应会更新最新值。

  • 单个勾选框,绑定字段为: checked。根据勾选状态,checked值对应为true/false,在label里面,对应显示true/false。示例如下:
 <input mtype="checkbox" id="checkbox" v-model="checked"> 	
 <label for="checkbox">{{ checked}}label>
  • 如果是多个复选框之类的,v-model=[数组],如:checkedNames是数组,勾选返回为checkBox 的value
   		<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
   		<label for="jack">Jacklabel> 		
   		<input type="checkbox" id="john" value="John" v-model="checkedNames">
   		<label for="john">Johnlabel>
  • 下拉: 返回value,如果没有显式设置value,返回text
   		  <select v-model="selected"> 			
   		  	<option disabled value="1">请选择option> 			
   		  	<option value="11">Aoption> 			
   		  	<option value="12">Boption> 			
   		 	 <option value="13">Coption>
   		  select>
  • 动态选项,用 v-for 渲染option选项,数组设置好value和text, selected为当前选中值
		<select v-model="selected">
   		  <option v-for="option in options" v-bind:value="option.value">{{ option.text }}option> 		
		select> 		
		<span>Selected: {{ selected }}span>
   		new Vue({
   		  el: '...',
   		  data: { 			
   		  	selected: 'A', 			
   		  	options: [
   			  { text: 'One', value: 'A' },
   			  { text: 'Two', value: 'B' },
   			  { text: 'Three', value: 'C' } 			
   			  ]
   		  }
   		  });
  • 通过v-bind绑定动态值到标签下:
  
  
 <input type="checkbox" -model="toggle" v-bind:true-value="a" v-bind:false-value="b">
  • 修饰符:lazynumbermsg,例:(msg为绑定的字段)
    v-model.lazy="msg":在 “change” 事件时更新msg值,而不是平时跟着"input" 填写内容而更新
    v-model.number="msg:自动将msg值转为 Number 类型
    v-model.trim="msg":自动过滤msg值的首尾空格

14、深入原理

  • 把一个普通 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并把这些属性全部转为 getter/setter
  • 每个组件实例都有相应的 watcher 实例对象,当依赖项的 setter 被调用时,会通知 watcher 重新计算
  • Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在
    data 对象上存在才能让 Vue转换它,这样才能让它是响应的
   var vm = new Vue({
   		  data:{a:1} 		
   		  }) 		
	vm.b = 2; //可行的
	vm.data.b=2; //是不行的 		
	Vue.set(vm.someObject, 'b', 2); //但可以调用:Vue.set(object, key, value)
	this.$set(this.someObject,'b',2); //或调用:this.$set(object, key, value)
  • 异步DOM更新:如果同一个 watcher 被多次触发,只会一次推入到队列中。
    如果你想在 DOM 状态更新后做点什么,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数在 DOM 更新完成后就会调用。
//组件内使用 vm.$nextTick()
Vue.nextTick(function () {
   		  vm.$el.textContent === 'new message'; // true 		
   		  }) 		

15、注册自定义指令

  • 除了核心功能默认内置的指令 (v-modelv-show),Vue 也允许注册自定义指令。
    可以为全局指令,也可以为局部指令,如:
 //局部指令
 directives: {
 	focus: {
 		// 指令的定义。例:
 		//钩子函数:当绑定元素插入到 DOM 中。
	    inserted: function (el) {
	      el.focus()
	    }
 	}
 }
 
 //全局指令
 Vue.directive('focus', {  
 	// 钩子函数:当绑定元素插入到 DOM 中。
 	inserted: function (el) { 			
 		// 聚焦元素 			
 		el.focus()
   	} 		
}) 		
//使用的语法为:v-focus property
<input v-focus>
  • 自定义指令的时候,有几个钩子函数可选:
    bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
    update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
    componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
    unbind:只调用一次,指令与元素解绑时调用。
    :VNode简单来说,就是Vue需要渲染的界面上的节点及其子节点,称为虚拟节点(virtual node),简称VNode。

示例:(效果:在div中输出钩子函数的一些参数值)

<div id="hook-arguments-example" v-demo:foo.a.b="message">div> 
	Vue.directive('demo', {
		bind: function (el, binding, vnode) {
			var s = JSON.stringify;
			el.innerHTML =
			'name: '       + s(binding.name) + '
'
+ 'value: ' + s(binding.value) + '
'
+ 'expression: ' + s(binding.expression) + '
'
+ 'argument: ' + s(binding.arg) + '
'
+ 'modifiers: ' + s(binding.modifiers) + '
'
+ 'vnode keys: ' + Object.keys(vnode).join(', '); } }) new Vue({ el: '#hook-arguments-example', data: { message: 'hello!' } })

示例解析:
指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,
      例如:v-my-directive="1 + 1" 中,绑定值为 2。
    • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式,
      例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选,
      例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。
  • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

:除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的dataset来进行。

待续

以上是整理出来的一部分内容,结合官方文档,可学习初步进行vue的使用了。
之后会再整理出路由等更加深入一些的内容进行分享。

你可能感兴趣的:(笔记,前端,Vue)