创建一个 Vue 实例
- Vue 是一个构造函数,对其使用 new 操作符,就得到了一个 Vue 的实例。
const vm = new Vue(options)
// or
new Vue(options)
复制代码
- vm 对象
封装
了对视图的所有操作,包括数据读写
、事件绑定
、DOM 更新
。- vm 的构造函数是 Vue,按照 ES6 的说法,vm 所属的类是 Vue。
- options 是 new Vue 的参数,一般称之为
选项
或者构造选项
vue 的响应式原理
- 当我们把 options.data 传给 Vue 之后:
- data 会自动被 Vue 监听(getter 、setter)
- data 会被 Vue 的实例(vm)代理
- 每次对 data 的读写都会被 Vue 监控
- Vue 会在data 变化时更新 UI
options 构造选项
- Vue 中文搜索
选项
(英文搜options
),会列出 options 的五个大类,点击其中一个,即可得到所有相关文档。
DOM
el
(挂载点)- 用来指定数据的挂载位置,它的蚕食可以是 CSS 选择器,可以用
$mount
代替
const Vue = window.Vue new Vue({ el: '#app' }) // 用 $mount 代替 new Vue({ }).$mount('#app') 复制代码
- 用来指定数据的挂载位置,它的蚕食可以是 CSS 选择器,可以用
数据
data
(内部数据)data
支持对象和函数,请优先使用函数- 可以简单理解为防止组件复用造成的内部数据共享
const Vue = window.Vue new Vue({ data: { n: 0 } // or data(){ return { n: 0 } } }).$mount('#app') 复制代码
methods
(方法)methods
包含了所有事件处理函数或者是普通函数
const Vue = window.Vue new Vue({ data(){ return { n: 0, array: [11, 22, 33, 44] } }, template: ` <div id="demo"> {{n}} <button @click="add"> + 1 </button> {{filter()}} </div> `, methods: { add(){ this.n++ }, // 页面中主动调用函数,每次渲染都会自动执行 filter(){ return this.array.filter(i => i % 2 === 0) } } }).$mount('#app') 复制代码
props
(外部属性)- 不同于
data
的内部数据,允许从外部传入数据,传入的数据会自动绑定到this
上 - 声明:
// demo.vue <template> {{message}} <button @click="fn">+1</button> </template> <script> export default{ props: ['message','fn'] } </script> <style scoped></style> 复制代码
- 使用:从外部传入一组 key = value
// main.js const Vue = window.Vue import Demo from './demo.vue' new Vue({ components:{Demo}, template:` <div> <Demo message="外部数据"> <div> `, }).$mount('#app') 复制代码
- 传入变量或者函数:
// main.js const Vue = window.Vue import Demo from './demo.vue' new Vue({ data(){ return { n: 0 } } components:{Demo}, template:` <div> {{n}} <Demo :message="n" :fn="add" /> <div> `, methods: { add(){ this.n++ } } }).$mount('#app') 复制代码
- 不同于
computed
(计算属性)- computed 包含所有用于返回计算处理后的、可复用的属性的方法,有点绕,看下面例子
-
- 展示用户的昵称或者电话或者邮箱,要求优先展示昵称
new Vue({ data(){ return { user: { nickname: 'aaa', email: 'bbb@b.com', phone: 'ccc' } }, template: ` <div> {{ user.nickname || user.email || user.phone }} </div> ` }).$mount('#app') 复制代码
- 以上需求如果被复用多次,一旦需求改变(如优先展示邮箱),代码将难以维护
- 用 computed 处理
new Vue({ data(){ return { nickname: 'aaa', email: 'bbb@b.com', phone: 'ccc' } }, computed: { // 只读的 displayName() { const user = this.user return user.nickname || user.email || user.phone } // or 可读写的 displayName: { get: function() { const user = this.user return user.nickname || user.email || user.phone }, ser: function(value) { // this.user.nickname = value } } }, template: ` <div> {{displayName}} </div> ` )} 复制代码
- 无论需求怎么变,只要修改 computed 属性里的方法就可以了
watch
(监听 / 侦听)- 当数据变化时,执行一个函数
- 使用 watch 实现撤销
new Vue({ data(){ return { n: 0, history:[], isUndoMode: false } }, watch: { if(!inUndoMode) { n(newValue, oldvalue){ this.history.push({from: oldValue, to: newValue}) } } }, template: ` <div> {{n}} <br> <button @click="add">+1</button> <button @click="minus">-1</button> <br> <button @click="undo">撤销</button> <br> {{history}} </div> `, methods:{ add(){ this.n++ }, minus(){ this.n-- }, undo(){ const last = this.history.pop() if (last) { this.n = last.from } this.isUndoMode = true this.$nextTick(() => { // watch 是异步的 this.inUndoMode = false }, 0) } } }).$mount('#app') 复制代码
- watch 的
deep
属性 (深度监听)watch
在监听数据变化时,如果监听的是简单数据类型,如果值变化,则视为变化,如果监听复杂数据类型,如果对象的地址变化,则视为变化,如果对象里属性的值变化,而对象的地址没变,则视为无变化。- 修改
deep
属性的值为 true 可以改变这一点
... watch: { obj: { handle(){...}, deep: true } } ... 复制代码
watch
和computed
的区别- computed 计算属性
- 支持缓存,只有依赖数据发生改变,才会重新进行计算
- 不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化
- computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于 data 中声明过或者父组件传递的 props 中的数据通过计算得到的值
- 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用 computed
- 如果 computed 属性属性值是函数,那么默认会走 get 方法;函数的返回值就是属性的属性值;在 computed 中的,属性都有一个 get 和一个 set 方法,当数据变化时,调用 set 方法。
- watch 监听
- 不支持缓存,数据变,直接会触发相应的操作
- 支持异步
- 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值
- 当一个属性发生变化时,需要执行对应的操作;一对多
- 监听数据必须是 data 中声明过或者父组件传递过来的 props 中的数据,当数据变化时,触发其他操作,函数有两个参数
- immediate:组件加载立即触发回调函数执行
- deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep 无法监听到数组的变动和对象的新增,参考 vue 数组变异,只有以响应式的方式触发才会被监听到
资源
components
(组件)- Vue 组件有三种定义方式
- 单独创建一个 vue 文件 demo.vue
<template> <div id="demo"> {{n}} <button @click="add">+1</button> </div> </template> <script> export default{ data(){ return { n:0 } }, methods:{ add(){ this.n++ } } } </script> <style scoped> ... </style> 复制代码
- 引入组件,使用组件
const Vue = window.Vue // 注意路径 import demo from './demo.vue' new Vue({ // 使用 components: { demo }, template: ` <div> <demo /> <div> ` ... }).$mount('#app') 复制代码
- 或者使用 component 函数,直接定义组件。函数的第一个参数接收组件的名字,第二个参数和 options 完全一样
const Vue = window.Vue Vue.component('demo',{ template: ` <div> content <div> ` }) new Vue({ // 使用 template: ` <div> <demo /> <div> ` ... }).$mount('#app') 复制代码
- 第三种
const Vue = window.Vue new Vue({ // 定义 components: { newDemo: { template: ` <div> content <div> ` } } // 使用 template: ` <div> <newDemo /> <div> ` ... }).$mount('#app') 复制代码
生命周期钩子
- 钩子可以简单理解为程序执行的某个重要节点,可以使用这些方法来做一些事情。
beforeCreate
、created
(不会出现在页面中)
const Vue = window.Vue new Vue({ ... created(){ console.log('内容创建了') } }) 复制代码
beforeMount
、mounted
(会出现在页面中)
const Vue = window.Vue new Vue({ ... mounted(){ console.log('页面展示了') } }) 复制代码
beforeUpdate
、updated
(数据更新触发)
const Vue = window.Vue new Vue({ ... updated(){ console.log('数据更新了') } }) 复制代码
beforeDestroy
、destroyed
(数据从页面中消失)
const Vue = window.Vue new Vue({ ... destroyed(){ console.log('数据消亡了') } }) 复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END