笔记(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文件包含HTML、JS、CSS三种语言,分别用、、划分区域。VSCode输入即可自动生成。
> // 此处写组件的配置对象 export default { } lang="less" scoped> /* 此处写组件样式 */

必须有一个根节点。(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储存计算属性,计算属性是操作data或VueX中已有数据得到的新数据。
②计算属性包含getter。当依赖数据变化或初次读取计算属性时都会执行get()方法。该方法具有缓存机制,多个相同变量不会多次执行get()get()方法的this是vm/vc本身。
③计算属性也可以包含setter,但不必要。当计算属性被修改时执行set()方法。set()方法的this是vm/vc本身。
③计算属性一定要有返回值,当计算属性对象只有getter,没有setter时可以进行简写。
new Vue({ // 完整写法 computed: { key: { get() {return this.value; } set(newValue) {this.value = https://www.it610.com/article/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临时变量储存再进行修改。
: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表达式,动态渲染页面。
|后面写过滤器函数名,给变量进行格式化加工操作。
> export default { el: '#app', data: {key: '动态显示数据'}, methods: { fun() {return '动态显示数据'; }, filter1() {} filter2() {} } };

指令语法 ①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的模板解析。可以优化性能。
超链接
这里写了也没用
div会被解析

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

键盘事件
.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是系统键)

样式绑定
①固定的基本样式写在class中,动态变化的样式写在:class由Vue管理。
:class为变量或数组时,样式个数和名字不确定,并会与class中的样式合并,所有样式一起组合显示。
:class为对象时,样式个数和名字确定,可以分别指定样式的显示与不显示。
:style可以指定内联样式。其中的样式用对象封装,并且属性值为CSS样式属性。注意一些带-的CSS样式属性需要改成驼峰命名。
> export default { el: '#root', data: { css: 'css1', cssArr: ['css2', 'css3', 'css4'], cssObj: { 'css5': true, 'css6': false }, styleObj: {fontSize: '40px'}, styleArr: [{backgroundColor: 'red'}, {color: 'black'}] } }

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

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

表单收集

获取DOM节点
①给模板中的标签添加ref属性,可以获取到该标签的DOM节点。
②若给组件标签添加ref属性,则获取的是整个组件实例对象。
vm.$refs中储存添加ref属性的DOM节点。
this.$refs.anyname;

Vue中的方法 && 属性 ①vm.$mount()用于指定vm/vc的关联元素,同初始化中的el
vm.$watch()用于指定vm/vc侦听变量。参数1是被侦听的变量,用字符串表示,参数2是侦听配置对象。当侦听配置对象不需要deepimmediate属性时,可以简写 (不能用箭头函数)。
vm.$set()用于后期给vm/vc添加新响应式数据。注意不能直接在data中添加心属性,应往后级对象中添加。也可以用于修改data中数组内容。vm.$delete()删除一个响应式数据。
vm.$destroy()用于销毁创建的vm/vc,页面保持最后销毁前的样式。
vm.$emit()用于触发自身被绑定的自定义事件函数。
vm.$off()用于解绑自身被绑定的自定义事件函数。
vm.$on()用于绑定自定义事件函数,vm.$once()表示绑定的自定义事件函数只触发一次。
vm.$nextTick()用于在下一次DOM更新结束后执行回调函数。
$attrs用于收集父组件给子组件传递的props没有接受的参数,结合v-bind可以进一步传递。
$listeners用于收集父组件给子组件传递的所有自定义事件,结合v-on可以进一步传递。
?$parent用于访问父组件的信息。
?$children用于访问子组件的信息。
vm.$mount('#anyname'); vm.$watch('anykey', {handler() {}, deep: true}); vm.$watch('anykey', fun(){}); vm.$set(targetObj, 'propertyName', value); vm.$delete(targetObj, 'propertyName'); vm.$destroy(); vm.$emit('anyname', value1, value2); vm.$off(['anyname', 'other']); vm.$on('anyname'); vm.$once('anyname'); vm.$nextTick(() => {}); -bind="$attrs"> -on="$listeners">

Vue组件 ①组件本质是一个名为VueComponent的构造函数,由Vue.extend()生成。
②在使用组件标签时,Vue帮我们执行了new VueComponent({});
③每次调用Vue.extend()返回的都是一个全新的VueComponent
④组件中的this指向VueComponent实例。
⑤Vue管理的组件都储存在vm.$children属性上。
VueComponent.prototype.__protot__ === Vue.prototype。所以组件实例对象可以访问到Vue原型上的方法。
const component = Vue.extend({ template: ``, data() {return {key: value}; }, });

组件嵌套 ①name给组件添加组件名,一般组件名与文件名一致,首字母大写的驼峰。
②组件的data必须写成函数形式。
③子组件需要在父组件中的components注册,此时组件是局部的。
④在模板中加入组件标签,标签名即组件名。组件标签可以是自闭和标签也可以是标签对。
> import component from './component'; new Vue({ components: {component} });

组件通信 方式一:props (父组件 → 子组件) ①父组件将变量或函数传递给子组件,子组件用props接受,同时$attrs也可以做到参数传递。
②此方式可以级联,实现祖先组件→后代组件。
方式二:自定义事件 (子组件 → 父组件) ①父组件的模板中,可以给子组件绑定一个自定义事件函数,事件函数写在methods中。
②父组件给子组件添加的自定义事件函数会被子组件的$listeners属性收集。
③使用ref获取子组件实例,再用mounted()在父组件挂载完毕时给子组件绑定自定义事件更加灵活。
④自定义事件可以设置事件修饰符。
⑤给子组件绑定原生DOM事件需要加上.native事件修饰符 (Vue3.0中移除了该事件修饰符,自定义事件需要用emits配置接受)。
.sync事件修饰符,当父组件给子组件传递的参数在子组件中变化时,父组件的数据也能同步变化。
// 父组件文件 .once="fun" @click.native="fun" :num.sync="arg" /> export default { methods: { fun(value) {} } } // 用ref绑定 ="son"/> export default { methods: { fun(value) {} } mounted() { this.$refs.son.$on('fun', this.anyname); this.$refs.son.$once('fun', this.anyname); } }

①子组件中用$emit()触发父组件给子组件绑定的自定义事件,参数1为事件函数名,参数2为其他参数。
②子组件中用$off()解绑父组件给子组件绑定的多个自定义事件。
③当父组件用.sync修饰符时,触发自定义事件,父组件中的参数也会同步变化。
// 子组件文件

方式三:全局事件总线 (任意组件通信) ①借助一个所有组件都能访问到的实例对象 (Vue.prototype),并赋予$on()$off()$emit()方法和自定义事件函数,可以实现任意组件间的通信。
②初始化Vue时,借助beforeCreate()生命周期函数,在Vue.prototype.$bus中连接vm自身实例即可安装全局事件总线。(很奇怪,因为原型无限套娃了!)
③使用这种方式还可以将统一的API请求接口注册到所有vm/vc上。
// main.js文件 import * as API from "@/api"; new Vue({ // 安装全局事件总线 beforeCreate() { Vue.prototype.$bus = this; Vue.prototype.$API = API; } });

④在接收参数的组件mounted中,用this.$bus.$on()方法添加一个自定义事件函数。
⑤在发送参数的组件methods中,用this.$bus.$emit()方法触发事件总线中的自定义事件函数。
⑥在接收参数的组件销毁前,记得用this.$bus.$off()手动解绑事件总线中的自定义函数。
// .vue文件 // 接收参数组件 export default { methods: { fun (value) {} } mounted: { this.$bus.$on('fun') } beforeDestroy() { this.$bus.$off('fun') } } // 发送参数组件 export default { methods: { this.$bus.$emit('fun', this.value) } }

方式四:消息订阅与发布 (任意组件通信) ①pubsub-js第三方库提供了消息订阅与发布的API,可适用于任意框架中。
npm i pubsub-js

②接受参数的组件订阅消息,subscribe()方法订阅消息名与回调函数。
③回调函数最好写在组件的methods中,函数的参数1是消息名(用不到),参数2是接受的参数。
unsubscribe()方法取消订阅消息,取消方法类似定时器。
import pubsub from 'pubsub-js'; this.pubid = pubsub.subscribe('anyname', (msgName, data) => {}); pubsub.unsubscribe(this.pubid);

⑤发送参数的组件发布消息,publish()方法发布消息名与参数,需要与订阅消息的统一。
pubsub.publish('anyname', this.data);

方式五:插槽 (子组件 → 父组件) ①父组件中子组件标签使用标签对的形式,标签对内传入的自定义模板会被插入子组件插槽处。
②子组件中插槽用确定插槽位置,使用name属性给插槽命名,可以在子组件中设置多个插槽。
③标签内可以写文本或其他元素,当插槽不被使用时,显示插槽内部的文本或元素。
④多个元素需要放入同一个插槽可以用打包。
⑤标签可以传入多个参数,父组件需要使用标签包裹,并用scope属性接受,接受的多个参数被打包成一个对象。
⑥指定插入子组件哪个插槽,用slot属性指定插槽名,Vue3.0中建议使用v-slot属性。
// 父组件 >
// 打包多个 // 子组件 ="1">不被使用时显示 ="2" :info="info">不被使用时显示

方式六:VueX (任意组件通信) ①多个组件共享读写同一个数据时,可以借助VueX插件管理共享数据。
②安装VueX,并使用插件。注意Vue2.0只能用VueX3.0,Vue3.0只能用VueX4.0。
③src/store/文件夹存放VueX所有配置与数据。
④只有安装了VueX插件,创建vm的时候才可以传入store配置对象,所有vm/vc都可以访问$store属性。
npm i vuex@3// main.js文件 import store from './store'; new Vue({ store, });

①store是VueX仓库的实例,包含actionsmutationsstategetters四个部分。
actions用于响应vm/vc中触发的数据操作。actions中编写数据操作前的预处理函数,例如做出一些判断,想服务器发送请求。预处理函数名小写,参数1是context,可以调用store的方法,参数2是value,接受vm/vc传入的参数。
actions中预处理函数逻辑太长太复杂,可以编写多个预处理函数,通过context参数互相调用使用dispatch()方法。
mutations用于操作仓库数据。mutations中编写数据操作函数,数据操作函数名大写,参数1是state,参数2是value,接受预处理函数传入的参数。
state存储共享数据。
getters用于加工state中的共享数据,类似计算属性,为vm/vc读取数据作简化。getters中编写数据加工函数,参数1为state,需要返回加工后的数据。
// store/index.js文件 import Vue from 'vue'; import VueX from 'vuex'; Vue.use(VueX); const actions = { // 预处理函数 anyname(context, value) { context.commit('ANYNAME', value); } }; const mutations = { // 数据操作函数 ANYNAME(state, value) { state.data += value; } }; const state = { // 数据 data: value }; const getters = { // 加工数据 data(state) { return state.data + 1; } }; // 创建store实例 export default new VueX.Store({ actions, mutations, state, getters, });

①vm/vc用this.$store.dispatch()方法将需要操作的参数传给actions中定义好的预处理函数。参数1是预处理函数名,参数2是其他参数。
②vm/vc用this.$store.commit()方法直接将需要操作的参数传给mutations中定义好的数据操作函数。参数1是数据操作函数名,参数2是其他参数。
③vm/vc可以通过this.$store.state读取VueX中的state数据。
④vm/vc可以通过this.$store.getters读取VueX中的getters数据。
// .vue文件 export default { methods: { fun() { this.$store.dispatch('anyname', this.value); this.$store.commit('ANYNAME', this.value); console.log(this.$store.state.data); console.log(this.$store.getters.data); }, }, }

VueX模块化
①VueX一般使用模块化编写。模块化actionsmutationsstategetters写在一个配置对象中,导入到VueX的modules中。
②模块配置对象中需要开启命名空间namespaced
// store/index.js文件 import store1 from "src/store/other.js" export default new VueX.Store({ modules: { other, } }); // 模块化仓库文件 export default { namespaced: true, state, actions, mutations, getters, };

①vm/vc可以在computed中,通过mapState()mapGetters()方法自动将VueX中的数据生成计算属性函数。当计算属性名与VueX中的数据同名时可以数组简写。
②vm/vc可以在methods中,通过mapMutations()mapActions()方法自动调用commit()方法和dispatch()方法。当函数名与VueX中函数名相同时可以数组简写。(注意!函数参数需要从模板中传入)
③以上四个方法读写VueX中的数据,参数1是模块化的仓库名。当使用原生函数时,数据路径需要添加仓库名。
// .vue文件 export default { computed: { ...mapState('other', {data:'data'}), ...mapState('other', ['data']), ...mapGetters('other', {data:'data'}), ...mapGetters('other', ['data']), }, methods: { ...mapActions('other', {fun: 'anyname'}), ...mapActions('other', ['anyname']), ...mapMutations('other', {fun: 'ANYNAME'}), ...mapMutations('other', ['ANYNAME']), this.$store.dispatch('other/anyname', this.value); this.$store.commit('other/ANYNAME', this.value); }, }

VueX 与 Web Storage 的区别
①VueX 数据存在内存中,在页面刷新后数据丢失。本地存储数据存在磁盘中,页面刷新数据还在。
元素进入与离开的动画/过渡 ①只有添加v-showv-if的元素可以添加离开与进入动画。用CSS制作进入动画,离开动画的样式。
②进入动画样式名后增加-enter-active,离开动画的样式名需要增加-leave-active,设置动画执行的参数。
/* 动画方式 */ @keyframes anim{ from{} to{} } .anyname-enter-active{ animation: anim 2s linear; } .anyname-leave-active{ animation: anim 2s linear reverse; }

①用CSS制作进入的过渡效果,.anyname-enter中写进入起点的样式 (Vue3.0中为.anyname-enter-from),.anyname-enter-to中写进入终点的样式。
②用CSS制作离开的过渡效果,.anyname-leave中写离开起点的样式 (Vue3.0中为.anyname-leave-from),.anyname-leave-to中写离开终点的样式。
③过渡参数写在.anyname-enter-active.anyname-leave-active中。
/* 过渡方式 */ .anyname-enter, .anyname-leave-to{ transform: translateX(0); } .anyname-leave, .anyname-enter-to{ transform: translateX(100%); } .anyname-enter-active, .anyname-leave-active{ transition: 2s linear; }

标签包裹需要动画/过渡的元素,当元素因事件触发隐藏或显示时,会自动播放进入或离开动画/过渡。
appear属性为true,页面刷新,元素首次就播放进入动画/过渡。
name属性中自定义动画/过渡的样式名.
包裹多个元素同时播放进入或离开动画/过渡,注意每个子元素需要一个唯一的key属性。

  • 第三方动画库 ①Animate.css第三方动画提供了设计好的动画。
    npm install animate.css --save // main.js文件 import 'animate.css'; // 使用动画

    配置代理服务器 ①vue-cli配置代理服务器,在vue.config.js中写入以下代码即可开启代理服务器。
    ②方式一:只能给固定端口服务器发送请求,不支持向其他服务器发送请求。代理服务器会优先返回public文件夹内的文件,若不存在,则向指定服务器发送请求。
    ③方式二:可以给任意多个服务器发送请求。可以指定请求前缀保,注意需要加上pathRewrite属性重写URL。
    ws默认值为true,用于支持websocket,可忽略该参数。
    changeOrigin默认值为true,用于控制请求头中的HOST值,与本地端口相同还是与请求服务器相同,可忽略该参数。
    // vue.config.js文件 module.exports = { // 开启代理服务器(方式一) devServer: { proxy: 'http://localhost:5000' }, // 开启代理服务器(方式二) devServer: { proxy: { '/api': { target: 'http://localhost:5000', pathRewrite: {'^/api': ''}, ws: true, changeOrigin: true }, '/other': { target: 'http://localhost:5001' } } } }

    UI组件库 ①移动端常用UI组件库:Vant,Cube UI,Mint UI。
    ②PC端常用UI组件库:Element UI,IView UI,Ant Design。
    ③Element UI不要全引入样式,借助babel-plugin-component按需引入。在babel.config.js和src/main.js中添加配置。
    // 安装element-ui npm i element-ui // 按需引入组件 npm install babel-plugin-component -D // 在babel.config.js中添加 presets: [ '@vue/cli-plugin-babel/preset', ["@babel/preset-env", { "modules": false }] ], plugins: [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ] // main.js文件 import {Button, MessageBox} from 'element-ui'; // 注册全局组件 Vue.component(Button.name, Button); // 挂载到原型 Vue.prototype.$msgbox = MessageBox; Vue.prototype.$alert = MessageBox.alert;

    Vue的精髓 data为什么是函数 Vue 里面data属性之所以不能写成对象的格式,是因为对象是对地址的引用,而不是独立存在的。如果一个.vue 文件有多个子组件共同接收一个变量的话,改变其中一个子组件内此变量的值,会影响其他组件的这个变量的值。如果写成函数的话,那么他们有一个作用域的概念在里面,相互隔阂,不受影响
    模板解析器 响应式原理 && 观察者模式 Getter 数据代理
    ①Vue用Object.defineProperty()中的getter与setter代理数据,进行双向绑定。
    ②Vue创建实例时的data被加工并保存在vm._data属性中,data对象中的每一个属性都被添加到vm/vc上并且增添get()set()方法。读取或修改data对象中的属性时会触发对应get()set()方法。
    Object.defineProperty(obj, key, { value: value,// 数据内容 configurable: true,// 是否可配置 enumerable: true,// 是否可枚举 writable: true,// 是否可改写 get() {return value; },// 属性值被读取时执行 set(args) {value = https://www.it610.com/article/args; }// 属性值被修改时执行 })

    Setter 数据监视
    data对象中的属性监视功能不能直接用Object.defineProperty()中的get()set()方法定义,会出现死循环。Vue通过构造函数来为data对象中的属性添加get()set()方法。
    data对象中多层结构的对象属性也全都递归被添加get()set()方法进行监视。
    ③多层结构如果是数组,并不是通过getter与setter进行监视,所以不能用索引去修改数组的内容。需要用过push()pop()shift()unshift()sort()splice()reverse()方法来证明原数组被修改。这7个数组方法经过Vue的包装,添加了重新解析页面的操作等,达到监视的目的。
    data对象中初始化后添加的新属性不会自动添加添加get()set()方法,需要调用vm.$set()Vue.set()方法添加。注意不能直接给data对象添加属性,应往后级对象中添加。也可用于修改数组某个元素。
    ⑤使用其他数组方法,产生新数组时,可以通过替换原数组方式修改数组,不影响数据监视。
    function Observer(obj) { const keys = Object.keys(obj); keys.forEach((k) => { Object.defineProperty(this, k, { get() { return obj[k]; }, set(value) { obj[k] = value; /* 并更新页面显示 */ } }) }); } const obs = new Observer(data); vm._data = https://www.it610.com/article/data = obs; // 后加入新属性 Vue.set(vm.obj,'newProperty', value); // 数组的数据监视 vm.$set(vm.arr, 1, value); this.arr = this.arr.filter(() => {});

    生命周期 ①创建Vue实例。
    ②初始化:生命周期,事件,但数据代理未开始。
    ③调用beforeCreate()生命函数。此时仍然无法访问到data中的数据和methods中的方法。
    ④初始化:数据监测、数据代理。
    ⑤调用created()生命函数。此时可以访问到data中的数据和methods中的方法。
    ⑥是否定义了el关联元素,若无关联元素则不再进行下面的流程,等待vm.$mount(el)被调用。
    ⑦是否确定了template模板,若无模板则使用el关联元素本身及其内容为模板,若有模板则使用定义的模板替换el元素本身。
    ⑧此时Vue开始解析模板,生成虚拟DOM存于内存,页面还不能显示解析好的内容。
    ⑨调用beforeMount()生命函数。此时页面呈现的是未经Vue编译的模板DOM结构,所有对模板DOM的操作最终不起作用。
    ⑩Vue将虚拟DOM挂载在页面上,并备份在vm.$el中。
    ?调用mounted()生命函数。此时页面呈现经过Vue编译后的模板DOM结构,并且可以进行开启定时器,发送网络请求,订阅消息,绑定自定事件等其他初始化操作。
    ?页面挂载完毕后,每次需要更新页面前,会调用beforeUpdate()生命函数,此时数据是新的,页面还是旧的。
    ?更新前后,新旧虚拟DOM进行比较,生成新的页面。更新完后,会调用updated()生命函数,此时页面与数据都是新的。
    ?等待vm.$destroy()被调用时,vm被销毁,页面保持最后的销毁前的样式。
    ?销毁前会调用beforeDestroy()生命函数,一般在此时关闭定时器,取消订阅,解绑所有自定义事件等操作。销毁后会调用destroyed()生命函数。
    Diff算法 【笔记(Vue 2.0)】key是虚拟DOM中的标识。当新的虚拟DOM生成后,通过key与之前的虚拟DOM进行diff算法对比。对比时先比较key是否相同,新的虚拟DOM中有些key不存在于之前的虚拟DOM时,更新。key相同时比较标签内的内容是否相同,内容相同则可以复用,内容不同则更新。

      推荐阅读