笔记:Vue 2.0

笔记:Vue 2.0

  • 下载与安装
  • Vue项目
    • vue项目文件介绍
  • Vue插件
  • Vue实例
    • el 关联元素
    • data 数据
    • methods 函数
    • computed 计算属性
    • watch 侦听(监视)属性
    • filters 过滤器 (Vue3.0已移除)
    • directives 自定义指令
    • props 传参
    • mixins 混合
    • 特殊函数
      • 生命周期函数 mounted()
      • render()
  • Vue语法
    • 插值语法
    • 指令语法
      • 事件修饰符
      • 键盘事件
      • 样式绑定
      • 条件渲染
      • 列表渲染
      • 表单收集
      • 获取DOM节点
  • Vue中的方法 && 属性
  • Vue组件
    • 组件嵌套
  • 组件通信
    • 方式一:props (父组件 → 子组件)
    • 方式二:自定义事件 (子组件 → 父组件)
    • 方式三:全局事件总线 (任意组件通信)
    • 方式四:消息订阅与发布 (任意组件通信)
    • 方式五:插槽 (子组件 → 父组件)
    • 方式六:VueX (任意组件通信)
      • VueX模块化
      • VueX 与 Web Storage 的区别
  • 元素进入与离开的动画/过渡
    • 第三方动画库
  • 配置代理服务器
  • UI组件库
  • Vue的精髓
    • data为什么是函数
    • 模板解析器
    • 响应式原理 && 观察者模式
    • 生命周期
    • Diff算法

下载与安装

①Vue官网可下载vue.js(或vue.min.js等各种版本),在.html文件中引入并直接使用。
②开发中使用vue-cli脚手架来搭建项目,本文只记录用vue-cli脚手架的Vue技巧。
③下载vue-devtool扩展工具安装于浏览器扩展中,供Vue调试。

Vue项目

①安装Node
②设置淘宝镜像源。

npm config set registry https://registry.npm.taobao.org

③安装vue-cli脚手架,检查vue-cli版本。

npm install -g @vue/cli
vue -V

④进入想要创建项目的路径,选择创建的Vue版本。

vue create `项目名`

⑤执行项目

cd `项目名`
npm run serve

⑥输出Vue隐藏配置文件(修改配置无效)。

vue inspect > output.js

⑦手动创建vue.config.js文件,修改Vue的配置 (例如关闭语法检查,默认入口文件路径,配置代理服务器等)

module.exports = {
	// 项目打包部署时,不生成 .js.map 文件 
	productionSourceMap: false,
	// 关闭 eslint 语法检查
	lintOnSave: false,
	// 配置代理服务器
	devServer: {
		proxy: {
			'/api': {
				target: 'http://39.98.123.211',
			}
		}
	}
}

⑦项目打包,代码加密,生成最终部署上线的.html.js.css文件。其中.js.map文件是映射加密代码与原代码。可设置不生成.js.map文件。

npm run build

vue项目文件介绍

public文件夹存放网页、图表等静态资源。
src/main.js文件是项目程序的入口文件。

import Vue from 'vue';
import App from './App.vue';
// 阻止vue在启动时产生的提示
Vue.config.productionTip = false; 
// 创建Vue实例
new Vue({
  render: h => h(App),
}).$mount('#app')

src/App.vue文件是app组件,是所有其他组件的父组件,也是vm的子组件。
src/assets文件夹存放一些图片、视频等静态资源。
src/components文件夹存放静态组件、全局组件。.vue文件包含HTMLJSCSS三种语言,分别用划分区域。VSCode输入即可自动生成。


<template>

template>
<script>
// 此处写组件的配置对象
export default {
}
script>
<style lang="less" scoped>
/* 此处写组件样式 */
style>

必须有一个根节点。(Vue3.0中不用)
scoped属性限定样式作用域,防止组件中样式名的重复。app组件中通常不写scoped,存放公共样式。
lang属性指定样式语言,如果使用Less语言,需要安装Less-loader,注意版本与webpack对应。

npm i less-loader@7

Vue插件

Vue插件可以导入全局设置,导入已经封装好的第三方插件和组件。
②在src/plugins文件夹内编写自己的插件。插件对外暴露一个包含install()方法的对象,install()方法参数1是Vue实例,参数2是可选的配置对象。

// plugin.js插件文件
export default {
	install(Vue, options) {
		// 设置全局过滤器
		Vue.filter('funName', function(args) {});
		// 设置全局自定义指令函数
		Vue.directive(`anyname`, {
			bing(element, binding) {},
			inserted(element, binding) {},
			update(element, binding) {}
		});
		Vue.directive(`anyname`, fun(element, binding) {});
		// 设置全局组件
		const component = Vue.extend({});
		Vue.component('组件名', component);
		// 设置全局mixin
		import {fun} from './mixin.js';
		Vue.mixin(fun);
	}
}

Vue.use()方法安装插件,自动执行install()方法。

// main.js文件
import plugin from './plugin.js';
// 安装Vue插件
Vue.use(plugin, options);

Vue实例

Vue的配置对象包含:el 关联元素和其中的data 数据methods 函数computed 计算属性watch 侦听属性filters 过滤器directives 自定义指令props 传参mixin 混合。配置对象中的内容都可在vm/vc上获取到。
Vue的配置对象还包含一些特殊函数Vue会在特定情况下会自动调用这些函数。例如生命周期函数,render()函数等。

el 关联元素

el储存关联元素,可以用CSS选择器,或用JS获取节点。
②一个页面应用只有一个vm,只有vm实例需要制定关联app元素,其他所有组件都是vm的子组件。

new Vue({
	el: '#app'
});

data 数据

data储存数据,是一个对象,也可以是一个返回对象的函数 (组件和Vue3.0中必须是函数形式)。
data中的数据是响应式的,模板中使用数据无需加this,其他配置项中使用数据需要加this

new Vue({
    // 对象写法  
	data: {key: value}           
	// 函数写法
	data() {
		return {key: value};
	}      
});

methods 函数

methods储存各种函数,包括事件回调函数和异步函数,其中的this指向vm/vc
②原生DOM事件回调函数会传入浏览器event事件对象。

new Vue({	
	methods: {
		fun(args, event){}
	}
});

computed 计算属性

computed储存计算属性,计算属性是操作dataVueX中已有数据得到的新数据。
②计算属性包含getter。当依赖数据变化初次读取计算属性时都会执行get()方法。该方法具有缓存机制,多个相同变量不会多次执行get()get()方法的thisvm/vc本身。
③计算属性也可以包含setter,但不必要。当计算属性被修改时执行set()方法。set()方法的thisvm/vc本身。
③计算属性一定要有返回值,当计算属性对象只有getter,没有setter时可以进行简写。

new Vue({	
	// 完整写法
	computed: {                         
		key: {
			get() {return this.value;}
			set(newValue) {this.value = newValue;}
		}
	} 
	// 简写
	computed: {
		key() {return this.value;}
	}          
});

watch 侦听(监视)属性

watch储存侦听属性,监视datacomputed中的数据是否发生变化。
②侦听属性包含handler()方法。当侦听的属性发生变化时,会调用该方法,传入修改前后的值。
immediate属性控制模板初始化是否调用handler()方法。
deep属性控制是否深度侦听多级结构中所有变量。
⑤侦听多级结构中的某个变量,侦听属性需要写成字符串形式'obj.key'
⑥不需要deepimmediate属性时可以进行简写。
⑦计算属性能实现的功能,侦听属性也能实现。计算属性不能实现延迟计算或者异步操作的需求,而侦听属性可以。不需要这些需求的时候,计算属性更简洁方便。

new Vue({	
	// 完整写法
	watch: {
		'obj.key': {
			handler(newValue, oldValue) {},
			immediate: true,
			deep: true,
		}
	}
	// 简写
	watch:{
		key(newValue, oldValue) {}
	}
});

filters 过滤器 (Vue3.0已移除)

filters储存过滤函数,用于给数据进行加工,例如将时间以一定的格式显示在网页上。
②过滤器函数的参数1是插值语法|前的变量,参数2为其他参数,最终返回处理后的结果。
③过滤器可以串联使用。
④写在vm/vc中的过滤器函数是局部的,只有当前的vm/vc能使用。全局过滤器需要在vm初始化前使用Vue.filter()
⑤过滤器也可以应用在v-bind上 (几乎不用)。

new Vue({	
	filters: {
		formater(value, args) {
			return '加工后的结果';
		}
	}
});

directives 自定义指令

directives储存自定义指令函数,自定义指令在使用时需要加上v-
②自定义指令可以写成对象或函数形式,需要亲自操作DOM
③函数形式写法的参数1是指令所在DOM节点,参数2是使用指令的vm/vc实例。指令函数在成功绑定元素(元素还不一定在页面上)模板被重新解析时会被调用。
④对象形式写法是完整写法,包含bind()inserted()update()三个函数,在特定情况下被调用。
⑤指令名不建议用驼峰命名。当指令名带有-时,对应的函数名或对象变量名写法应该用字符串形式。
⑥指令函数的this是全局对象window
⑦写在vm/vc中的自定义指令是局部的,只有当前的vm/vc能使用。全局自定义指令需要在vm初始化前使用Vue.directive()

new Vue({	
	directives: {
		// 函数写法
		anyname(element, binding) {
			element.innerText = binding.value;    // 最关心的属性
		}
		// 对象写法
		anyname: {
			bing(element, binding)) {},      // 当成功绑定元素时
			inserted(element, binding)) {},  // 当元素被放于页面时
			update(element, binding)) {},    // 当元素被重新解析时
			componentUpdated(element, binding) {},
			unbind(element, binding) {}
		}
	}
});

props 传参

props接受父组件给子组件传入的参数,在父组件模板中的子组件标签添加的属性为变量名,属性值作为传入的具体参数。
props对象写法可以规定限制接受参数的类型 (不匹配时Vue报错)、默认值、必要性。
③父组件传入子组件的参数不可以进行修改。
props中的参数优先于data被接受,如果要修改传入的参数,可以通过data临时变量储存再进行修改。

<Son :arg1="value1" :arg2="value2" />

new Vue({	
	// 数组简写
	props: ['arg1', 'arg2'];
	// 对象简写,限定类型
	props: {
		arg1: Number,
		arg2: String
	}
	// 完整写法,限定类型,规定必要
	props: {
		arg1: {
			type: Number,
			default: 66
		}
		arg2: {
			type: String,
			required: true
		}
	}
});

mixins 混合

vm/vc中有相同功能的函数和配置可以写入src/mixin文件夹并对外暴露,进行复用代码。

// mixin.js文件
export const fun1 = {
	methods: {},
	data: {},
	mounted() {}
}

mixin用数组储存引入mixin.js文件中的函数或参数,可以直接使用。
③当mixin中变量与data出现数据冲突时,以data中的为主。
③回调函数例如mounted(),当出现冲突时,采取都执行的方式,先执行mixins中的函数。
④写在vm/vc中的mixin是局部的,只有当前的vm/vc能使用。全局mixin需要在vm初始化前使用Vue.mixin()

// .vue文件
import {fun1, fun2} from './mixin.js';
new Vue({	
	mixins: [fun1, fun2]
});

特殊函数

生命周期函数 mounted()

Vue完成模板解析并把初始的真实DOM元素放入页面后才调用mounted()挂载完成回调函数。
mounted()回调函数的this指向vm/vc

new Vue({	
	mounted() {}
});

render()

render()函数的参数1是createElement()函数,调用createElement()能够创建HTML结构。render()函数返回被创建的HTML结构作为模板。
②一般写成箭头函数的形式。

new Vue({	
	render(createElement) {
		return createElement('h1', 'h1中的文本内容');
	}
	// 一般写成
	render: h => h(App)
});

Vue语法

插值语法

{{}}中可以放vm/vc中的任何定义的内容(不用加this)或JS表达式,动态渲染页面。
|后面写过滤器函数名,给变量进行格式化加工操作。

<template>
	<div id="app">
		<h1>{{key}}h1>        // 插入属性名
		<span>{{fun()}}span>  // 插入函数并调用执行
		<h1>{{value | filter1(args) | filter2(args)}}h1>
	div>
template>

<script>
export default {
    el: '#app',
	data: {key: '动态显示数据'},
	methods: {
		fun() {return '动态显示数据';},
		filter1() {}
		filter2() {}
	}
};
script>

指令语法

v-bind单向绑定元素属性的值,其属性值可以变成vm/vc中的任何内容(不用加this)或JS表达式。简写为:
v-model双向绑定元素属性的值,其属性值可以变成vm/vc中的任何内容(不用加this)或JS表达式。也可以实现父子组件的数据同步。
v-on给指定元素绑定事件函数,可以传入参数和浏览器event事件。简写为@
v-text可以将标签节点中的内容替换为属性值的文本,就算文本中有标签也不会被浏览器解析。
v-html可以将标签节点中的内容替换为属性值的文本,但是标签符号会被HTML解析。
v-cloak配合CSS[v-cloak]{display: none;}语句,可以在Vue未接管元素时,隐藏元素。
v-once只在初始模板解析时解析插值语法,之后为静态页面不再变化。可以优化性能。
v-pre标记的元素可以跳过Vue的模板解析。可以优化性能。

<a v-bind:href="url">超链接a>
<input type="text" v-model="value">
<button @click="fun(args, $event)">按钮button>
<div v-text="txt">这里写了也没用div>
<div v-html="
"
>
div会被解析div> <div v-cloak v-once v-pre>div>

事件修饰符

.prevent阻止元素默认事件。
.stop阻止事件冒泡。
.once事件只触发一次。
.capture事件触发在捕获阶段。
.self只有event.target是当前操作元素时才触发事件。(注意:冒泡阶段中event.target永远是触发事件的那个元素)。
.passive事件的默认行为立即执行,不用等待事件回调函数执行完。注意:元素触发事件后,首先执行事件回调函数,再执行默认行为。例如wheel鼠标滚轮事件,当滚轮事件触发后,先执行事件函数后,才滚动滚动条。.passive能改变这种行为,常用于移动端。
⑦修饰符可以连续写,按顺序修饰。

<a href="url" @click.prevent="fun($event)">超链接a>
<button @click.stop.once.capture="fun($event)">按钮button>
<div @click.self.passive="fun($event)">按钮div>

键盘事件

.enter确认回车键是否被按下。
.delete确认退格键或删除键是否被按下。
.esc确认退出键是否被按下。
.space确认空格键是否被按下。
.tab确认Tab键是否被按下,只能绑在keydown上。
.up.down.left.right确认上下左右键是否被按下。
⑦其他按键被检测按下,可以同样使用其按键名event.key,或根据按键值event.keyCodeVue.config.keyCodes.自定义可以自定义按键名,一般不用。(Vue3.0中已经被移除)
.ctrl.meta.alt.shift按键配合keydown则检测是否被按下,配合keyup检测是否有组合键按下。(注意:.meta是系统键)

<input type="text" @keyup.enter="fun($event)">
<input type="text" @keydown.caps-lock="fun($event)">
<input type="text" @keydown.ctrl.s="fun($event)">

样式绑定

①固定的基本样式写在class中,动态变化的样式写在:classVue管理。
:class为变量或数组时,样式个数和名字不确定,并会与class中的样式合并,所有样式一起组合显示。
:class为对象时,样式个数和名字确定,可以分别指定样式的显示与不显示。
:style可以指定内联样式。其中的样式用对象封装,并且属性值为CSS样式属性。注意一些带-CSS样式属性需要改成驼峰命名。

<template>
	<div id="root">
		// 绑定样式1,样式名为变量
		<div class="basic" :class="css">div>
		// 绑定样式2,样式名为数组
		<div class="basic" :class="cssArr">div>
		// 绑定样式3,样式名为对象
		<div class="basic" :class="cssObj">div>
		// 内联样式1,样式名为对象
		<div :style="styleObj">div>
		// 内联样式2,样式名为数组
		<div :style="styleArr">div>
	div>
template>

<script>
export default {
	el: '#root',
	data: {
		css: 'css1',
		cssArr: ['css2', 'css3', 'css4'],
		cssObj: {
			'css5': true,
			'css6': false
		},
		styleObj: {fontSize: '40px'},
		styleArr: [{backgroundColor: 'red'}, {color: 'black'}]
	}
}
script>

条件渲染

v-show值为true时显示相应元素。值计算后为false时,相当于元素应用了display:none。但是元素的节点结构依然存在,频繁切换时建议用v-show
v-ifv-else-ifv-else值为true时显示相应元素。当其属性值计算后为false时,元素连网页节点都一起消失。v-else不用加条件。
配合v-if使用打包多个相同判断条件,不破坏原有网络节点结构。

<div v-show="false">div>
<div v-if="null === undefined">div>
<div v-else-if="fun()">div>
<div v-else>div>

<template v-if="true">
	<div>div>
	<div>div>
template>

列表渲染

v-for用于循环创建指定个数的列表项,可以用ofin遍历。
②使用v-for时一定要有:key属性,给每个列表项唯一的编号。
③遍历数组或字符串时,依次返回其元素value和索引index
④遍历对象时,依次返回对象键值value和键名key
⑤遍历指定次数时,依次返回从1开始的递增序列和索引。

<ul>
	<li v-for="(value, index) of/in arr/str" :key="id">li>
	<li v-for="(value, key) of/in obj" :key="id">li>
	<li v-for="(num, index) of/in 10" :key="id">li>
ul>

表单收集