1.10 开始
尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1Zy4y1K7SH?p=4&spm_id_from=pageDriver
Vue 前言
虚拟DOM
Vue文档介绍
开发环境
chrome://extensions/ 安装插件 Vue.js devtools
开始整活~
new Vue()
先有容器
实例跟容器,一一对应
如果绑定的容器有重复(比如两个div class 一样,则Vue 实例就解析第一个div)
如果一个容器有多个Vue 绑定(比如两个new Vue el:’#sample’,则容器由第一个new Vue接管,第二个实例无用)
容器里的代码被称为Vue模板
真实开发中只有一个Vue实例,并且会配合着组件一起使用
{{ xxx }} 中要写 js表达式 ,且xxx 可以自动读取到data中的所有属性
一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新。
js表达式 和 js代码(语句)
- 表达式:a, a+b, demo( ) …. 表达式有返回值
- js代码(语句):if ( ){ }, for( ){ }
控制台开发者工具
模板语法
插值语法
功能:用于解析标签体内容
{{ name }} : {{ address}}
{{ xxx }} 是 js表达式,可直接读取data中的所有属性指令语法
功能:用于解析标签(标签属性,标签体内容,绑定事件 … )
baidu
v-bind 后面的 “url” 为 js表达式,可直接读取data中的所有属性。
v-bind: 简写为 :
baidu
数据绑定(vue中有2种数据绑定方式)
v-bind 单向绑定
v-model 双向绑定
双向绑定:数据不仅能从data流向页面,还可以从页面流向data
v-model 只能用在表单类元素(输入元素)上,比如 input , select 等有value值的 , 有交互才有双向
简写
v-bind:value=”name”, 简写 :value=”name”
v-model 默认收集的就是 value 值,v-model:value=”name”, 简写 :v-model =”name”
el和data的两种写法
el
- el:”#root”
const v = new Vue( {} ) ; v.$mount(“#root”)
data
对象式。 data:{ name: “ jara” }
- 函数式。函数的返回值是数据。 data: function( ){ return{ name: “jara”} }
组件的时候,用函数式的,防止作用域污染。
data 函数没有箭头函数,箭头函数的this不是vue实例,而是window.
架构模型 MVVM,双向数据绑定
View => DOM (页面结构)=> 模板
data中的所有属性,最后都出现在了vm身上,(数据代理)
vm身上所有属性及vue原型上的所有属性,在vue模板中都可以直接使用
数据代理(双向绑定原理
1、回顾Object.defineproperty方法
v-model 是靠这个函数实现的
实现数据层到显示层的实时绑定,且不需要重新赋值
2、何为数据代理
3、Vue中的数据代理(底层原理)
一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新。
事件处理
事件的基本使用:
1、使用 v-on:xxx 或者 @ xxx 绑定事件,其中xxx 是事件名
2、事件的回调需要配置在methods对象中,最终会在vm上
3、methods中配置的函数,不要用箭头函数,否则this就不是vm了
4、methods中配置的函数,都是被Vue管理的函数,this指向vm 或者组件实例对象
5、@ click = “demo” 和 @ click=”demo($event)” 效果一致,但后者可以传参
事件修饰符
@ click . prevent
一般事件采用冒泡,然后用了.capture 就使用事件的捕获阶段
键盘事件
计算属性 computed
姓名案例
插值语法和methods实现
计算属性实现
定义
原理
低层借助了 Object.defineproperty 方法提供的getter 和 setter
getter 什么时候执行
1、初次读取时会执行一次。
2、当依赖的数据发生改变时,会被再次调用
优势
与 methods 相比,内部有缓存机制(复用),效率更高,调试方便
备注
计算属性最终会出现在vm上,直接读取使用即可
如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变
监视属性 watch
天气案例
当被监视的属性发生变化时,回调函数自动调用,进行相关操作
监视的属性必须存在,才能进行监视
两种写法:
new Vue 时传入 watch 配置
通过vm. $watch 监视
深度监视
Vue中的watch默认不监测对象内部值的改变(一层)
配置 deep:true 可以监测对象内部值的改变(多层)
姓名案例
computed 和 watch 的区别
- computed 能完成的功能,watch 都可以完成
- watch 能完成的功能,computed 不一定能完成,例如,watch 可以进行异步操作
两个重要的小原则:(反正this要指向vm)
- 所有被Vue 管理的函数,最好写成普通函数,这样 this 的指向才是vm 或者组件实例对象。
- 所有不被Vue 管理的函数(定时器的回调函数、ajax 的回调函数、Promise的回调函数),最好写成箭头函数,这样this 的指向才是vm 或组件实例对象
绑定样式
class 绑定
style绑定
总结
条件渲染
v-show
v-if
总结
列表渲染
基本列表
key 的原理(虚拟DOM对比算法 diff )
如果不写 key, vue 自动将索引值 index 设为 key。
key 总结 !
列表过滤
watch 实现
computed 实现 (better)
列表排序
更新时的一个问题
Vue检测数据改变的原理
模拟一个数据检测 ??WTF
底层源码
这个不太懂。。。
Vue 监视的是数组这个对象,没有监视数组里面的元素
vue.set 的使用
大总结!Vue 监视数据的原理
vue会监视data中所有层次的数据
如何监测对象中的数据?
通过 setter 实现监视,且要在 new Vue 时就传入要监测的数据。
1、对象中追加的属性,Vue 默认不作响应式处理
2、如需给后添加的属性做响应式,请用如下API :
Vue.set(target, propertyName / index , value) 或
vm.$set(target, propertyName / index , value)
如何监测数组中的数据?
通过包裹数组更新元素的方法实现。本质就是做了两件事:
1、调用原生对应的方法对数组进行更新。
2、重新解析模板,进而更新页面。
在Vue修改数组中的某个元素一定要用如下方法:
1、使用这些API : push( ) 、pop( ) 、shift( ) 、unshift( )、splice( )、sort( )、reverse( )
2、Vue.set( ) 或 vm.$set( )
特别注意:Vue.set( ) 和 vm.$set( ) 不能给 vm 或 vm 的根数据对象 添加属性
收集表单数据
若, 则v-model 收集的是value值,用户输入的就是value值
若, 则v-model 收集的是value值,要标签配置value值
若
1、没有配置 input的 value 属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2、配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的就是value 组成的数组
备注:v-model 的三个修饰符:
lazy : 失去焦点再收集数据
number : 输入字符串转为有效的数字
trim : 输入首位空格过滤
过滤器
本质是个函数,可以对前面写的数据进行某种形式加工处理
管道符 |
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
语法:
1、注册过滤器:Vue.filter(name, callback) 或 new Vue{ filters:{ } }
2、使用过滤器:{{ xxx | 过滤器名 }} 或 v-bind:属性=”xxx | 过滤器名”
备注:
1、过滤器也可以接收额外参数、多个过滤器也可以串联
2、并没有改变原本的数据,是产生新的对应的数据
内置指令
v-text
v-html
- 作用:向指定节点中渲染包含html 结构的内容
- 与插值语法的区别:
- v-html会替换掉节点中所有内容,{{ xx }} 则不会
- v-html 可以识别 html 结构
严重注意:v-html 有安全性问题!!
没有值的,本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
使用css配合v-cloak 可以解决网速慢时页面展示出 {{ xxx }} 的问题
v-once
v-once 所在节点在初次动态渲染后,就视为静态内容了。
以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
v-pre
跳过其所在节点的编译过程。就是不用vue解析它了。
- 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
自定义指令
总结
生命周期
引入生命周期
mounted()
Vue 完成模板的解析并把最初的真实DOM元素放入页面后(挂载完毕)调用mounted
特殊时间点 调用方法挂载流程
更新流程
销毁流程
总结
四对
初始化的事在 mounted()
收尾的事在 beforeDestroy()Vue组件化编程
对组件化的理解
封装 复用非单文件组件
一个文件中包含n个组件单文件组件
一个文件中只包含一个组件基本使用,创建组件
几个注意点
组件的嵌套
VueComponent
Vue 实例 与 组件 Vc 实例
一个重要的内置关系:vc可以访问到vue原型上的属性和方法
单文件组件
使用Vue脚手架 CLI (command line interface)
第一次安装 cli
分析脚手架结构
├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── component: 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue: 汇总所有组件
│ │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件
render 函数
关于不同版本的Vue
- vue.js与vue.runtime.xxx.js的区别:
- vue.js是完整版的Vue,包含:核心功能 + 模板解析器。
- vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。
因为vue.runtime.xxx.js没有模板解析器,所以不能使用template这个配置项,需要使用render函数接收到的createElement函数去指定具体内容。
修改默认配置 vue.config.js
使用vue inspect > output.js可以查看到Vue脚手架的默认配置。
使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh
ref 属性
被用来给元素或子组件注册引用信息(id的替代者)
- 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
使用方式:
功能:让组件接收外部传过来的数据
- 传递数据:
<Demo name="xxx"/>
- 接收数据:
- 第一种方式(只接收):
props:['name']
- 第二种方式(限制类型):
props:{name:String}
- 第三种方式(限制类型、限制必要性、指定默认值):
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
}
}
备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
- 第一种方式(只接收):
mixin 混入
- 功能:可以把多个组件共用的配置提取成一个混入对象
使用方式:
第一步定义混合:
第二步使用混入:
全局混入:Vue.mixin(xxx)
局部混入:mixins:['xxx']
{ data(){....}, methods:{....} .... }
scoped 样式
作用:让样式在局部生效,防止冲突。
-
插件
功能:用于增强Vue
- 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
定义插件:
对象.install = function (Vue, options) { // 1. 添加全局过滤器 Vue.filter(....) // 2. 添加全局指令 Vue.directive(....) // 3. 配置全局混入(合) Vue.mixin(....) // 4. 添加实例方法 Vue.prototype.$myMethod = function () {...} Vue.prototype.$myProperty = xxxx }
-
to-do-list 案例
首先实现 静态页面
初始化列表
添加 功能
组件间通讯(低级:通过父组件) 后面会学其他高级方法
子组件里面的数据想要传给父组件,需要前提:父组件先定义一个函数方法,并且将这个函数方法传给子组件,然后子组件的数据代入为函数形参,这样父组件就可以有子组件的数据了。
参数变了,vue 会重新解析模板。props 用法
有个细节就是 其实子组件的props里面的属性 实际上是对父组件绑定的属性的代理
勾选功能
方法一:组件之间props传方法
数据在哪,方法在哪
data 在 App.vue,则在这里写勾选方法
所以老师说了数据在哪里,你的增删改查就在哪里,不要在接收数据传递过去的子组件里面改,子组件也就是给给参数,通知哪个东西要改了。
数据在哪个组件就在哪个组件去修改它,这样方便维护。
App.vue -> MyList.vue -> MyItem.vue , 勾选方法从App.vue 传到孙子组件 MyItem.vue ,连续传两次。
方法二:v-model
不建议
- 这个和const定义的数据一样,用const定义对象,对象里面的数据增删都会报错,但是修改对象数据的值是没问题的。
- a变量引用一个基本数据类型,值变了,a就变了。a引用一个引用数据类型(对象),若a没有引用新对象,即使对象的属性值变了,a也没有变化。除非a引用了新对象。
- 如果其他子组件也用到这个数据,两个同时修改会发生不可预料的后果。
- 前面的methods方法是从props中拿到id传到app然后在app中修改data数据的不是直接修改的props
删除功能
底部统计功能
数组函数 reduce() :
reduce() 方法对数组中的每个元素执行一个由开发者自己提供的函数,将其结果汇总为单个返回值。
可以理解为,reduce会遍历数组元素,将每个元素都作为参数,代入自定义函数执行并返回一个返回值。并在下一次执行时将返回值作为参数传入。
array.reduce(()=>{}, 0) : 第一个参数是要执行的函数,第二个参数是初始值。
数组的长度 == 被调用的次数总结TodoList案例
- 组件化编码流程:
(1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。
(2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
1).一个组件在用:放在组件自身即可。
2). 一些组件在用:放在他们共同的父组件上(状态提升)。
(3).实现交互:从绑定事件开始。 - props适用于:
(1).父组件 ==> 子组件 通信
(2).子组件 ==> 父组件 通信(要求父先给子一个函数) - 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
- props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。