Vue
Vue 学习
| 1 | # 运行单独的Vue页面 | 
Vue简介
- Vue是什么? - 一套用于构建用户界面的 - 渐进式JavaScript框架- 渐进式:Vue可以自底向上逐层的 - 应用- 简单应用:只需一个轻量小巧的核心库 (100+ kb) - 复杂应用:可以引入各式各样的 Vue 插件 
- 谁开发的? - 尤雨溪
 
- Vue的特点 - 采用组件化模式,提高代码复用率,且让代码更好维护
- 声明式编码,让编码人员无需直接操作DOM,提高开发效率
- 使用虚拟DOM+ 优秀的DIff算法,尽量复用DOM节点
 
- 采用
- 学习Vue之前要掌握的JavaScript基础知识 - ES6语法规范
- ES6模块化
- 包管理 (npm等)
- 原型、原型链
- 数组常用方法
- axios
- promise
- ……
 
Vue官网使用指南
https://www.bilibili.com/video/BV1Zy4y1K7SH/?p=3
Vue 环境搭建
- 直接用 <script> 引入 - 开发版本: 包含完整的警告和调试模式。=>   vue.js
- 生产版本: 删除了警告,压缩。       =>   vue.min.js
 
- 开发版本: 包含完整的警告和调试模式。=>   
- npm + Vue-cli 
开始 Hello World 案例
| 1 | 
 | 
模板语法
Vue模板语法有2大类
- 插值语法- 功能:用于解析标签体内容。 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
- 指令语法- 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)。 举例:v-bind:href="xxx" 或 简写为 :href="xxx",xxx同样要写js表达式, 且可以直接读取到data中的所有属性。 备注:Vue中有很多的指令,且形式都是:v-????,此处我们只是拿v-bind举个例子。
数据绑定
Vue中有2种数据绑定的方式:
- 单向绑定(v-bind)- 数据只能从data流向页面。
- 双向绑定(v-model)- 数据不仅能从data流向页面,还可以从页面流向data。 - 备注: - 双向绑定一般都应用在表单类元素上(如:input、select等)
- v-model:value可以简写为- v-model,因为 v-model 默认收集的就是value值。
- v-model只能应用在表单类元素(输入类元素)上
 
| 1 | 单向数据绑定:<input type="text" :value="name"><br/> | 
el与data的两种写法
el的2种写法
- new Vue时候配置el属性。 - 1 
 2
 3
 4
 5
 6- const v = new Vue({ 
 el:'#root', // 第一种写法
 data:{
 name:'细粒丁'
 }
 })
- 先创建Vue实例,随后再通过 - vm.$mount('#root')指定el的值。- 1 
 2
 3
 4
 5
 6- const v = new Vue({ 
 data:{
 name:'细粒丁'
 }
 })
 v.$mount('#root') // 第二种写法
data的2种写法
- 对象式 - 1 
 2
 3
 4
 5
 6
 7- new Vue({ 
 el:'#root',
 //data的第一种写法:对象式
 data:{
 name:'细粒丁'
 }
 })
- 函数式 - 1 
 2
 3
 4
 5
 6
 7
 8
 9- new Vue({ 
 el:'#root',
 data(){
 console.log('@@@',this) //此处的this是Vue实例对象
 return{
 name:'细粒丁'
 }
 }
 })- 如何选择:目前哪种写法都可以 
 组件时,data必须使用函数式,否则会报错。
一个重要的原则
- 由Vue管理的函数,一定 不要写箭头函数,一旦写了箭头函数,this 就不再是Vue实例了。
理解MVVM
MVVM模型
    1. M:模型(Model) :data中的数据
    2. V:视图(View) :模板代码
    3. VM:视图模型(ViewModel):Vue实例
观察发现:
    1.data中所有的属性,最后都出现在了vm身上。
    2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
Object.defineProperty
| 1 | let number = 18 | 
数据代理
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
| 1 | let obj = {x:100} | 
Vue 中的数据代理
- Vue中的数据代理: - 通过vm对象来代理data对象中属性的操作(读/写)
- Vue中数据代理的好处: - 更加方便的操作data中的数据
- 基本原理: - 通过 Object.defineProperty()把data对象中所有属性添加到vm上
- 为每一个添加到vm上的属性,都指定一个getter/setter
- 在 getter/setter 内部去操作(读/写)data 中对应的属性
 
- 通过 
事件处理
事件的基本使用:
- 使用
v-on:xxx或@xxx绑定事件,其中xxx是事件名;- 事件的回调需要配置在methods对象中,最终会在vm上;
- methods中配置的函数,
不要用箭头函数!否则this就不是vm了;- methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
@click="demo"和@click="demo($event)"效果一致,但后者可以传参;
| 1 | <button @click="showInfo1">点我提示信息1(不传参)</button> | 
事件修饰符
Vue中的事件修饰符:
prevent:阻止默认事件 (常用) - 如<a>标签的跳转
stop:阻止事件冒泡 (常用) - 子元素不触发父元素事件
once:事件只触发一次 (常用)
capture:使用事件的捕获模式 - 父元素不触发子元素事件
注:捕获是从父传到子,冒泡是从子传到父,先捕获 后冒泡
self:只有event.target是当前操作的元素时才触发事件;
passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
| 1 | <!-- 阻止默认事件(常用, 执行完 showInfo 后不跳转 --> | 
键盘事件
Vue中常用的按键别名:
回车 => enter 删除 => delete (捕获“删除”和“退格”键) 退出 => esc 空格 => space 换行 => tab (特殊,必须配合keydown去使用) 上 => up 下 => down 左 => left 右 => right
Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为
kebab-case(短横线命名)
系统修饰键(用法特殊):
ctrl、alt、shift、meta(win键)(1). 配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。 (2). 配合keydown使用:正常触发事件。
也可以使用keyCode去指定具体的按键(不推荐)
Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
| 1 | <input type="text" placeholder="按下ctrl+y触发showInfo" @keyup.ctrl.y="showInfo"> | 
计算属性
- 定义:要用的属性
不存在,要通过已有属性计算得来- 原理:底层借助了
Objcet.defineproperty方法提供的 getter 和 setter- get函数什么时候执行?
- 初次读取时会执行一次。
- 当依赖的数据
发生改变时会被再次调用。- 优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
- 备注:
- 计算属性最终会出现在vm上,直接读取使用即可。
- 如果计算属性要被修改,那必须写
set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
姓名案例 - 拼接姓名
- 第一种写法 - 前端插值语法实现- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17- <body> 
 <div id="root">
 姓:<input type="text" v-model="firstName"> <br/><br/>
 名:<input type="text" v-model="lastName"> <br/><br/>
 全名:<span>{{firstName}}-{{lastName}}</span>
 </div>
 </body>
 <script type="text/javascript">
 new Vue({
 el:'#root',
 data:{
 firstName:'张',
 lastName:'三'
 }
 })
 </script>
- 第二种写法 - methods函数返回值 实现- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20- <div id="root"> 
 姓:<input type="text" v-model="firstName"> <br/><br/>
 名:<input type="text" v-model="lastName"> <br/><br/>
 全名:<span>{{fullName()}}</span>
 </div>
 <script type="text/javascript">
 new Vue({
 el:'#root',
 data:{
 firstName:'张',
 lastName:'三'
 },
 methods: {
 fullName(){
 return this.firstName + '-' + this.lastName
 }
 },
 })
 </script>
- 第三种写法 - computed计算属性 实现- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33- <div id="root"> 
 姓:<input type="text" v-model="firstName"> <br/><br/>
 名:<input type="text" v-model="lastName"> <br/><br/>
 全名:<span>{{fullName}}</span> <br/><br/>
 </div>
 <script type="text/javascript">
 const vm = new Vue({
 el:'#root',
 data:{
 firstName:'张',
 lastName:'三'
 },
 computed:{
 fullName:{
 //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
 //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
 get(){
 console.log('get被调用了')
 // console.log(this) //此处的this是vm
 return this.firstName + '-' + this.lastName
 },
 //set什么时候调用? 当fullName被修改时。
 set(value){
 console.log('set',value)
 const arr = value.split('-')
 this.firstName = arr[0]
 this.lastName = arr[1]
 }
 }
 }
 })
 </script>
计算属性简写
| 1 | computed:{ | 
监视属性
监视属性watch:
- 当被监视的属性变化时, 回调函数自动调用, 进行相关操作
- 监视的
属性必须存在,才能进行监视- 监视的两种写法:
- new Vue时传入watch配置
- 通过vm.$watch监视
天气案例
点击按钮,切换状态,从而显示不同内容
- 普通方法 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24- <div id="root"> 
 <h2>今天天气很{{info}}</h2>
 <!-- <button @click="isHot = !isHot">切换天气</button> -->
 <button @click="changeWeather">切换天气</button>
 </div>
 <script type="text/javascript">
 const vm = new Vue({
 el:'#root',
 data:{
 isHot:true,
 },
 computed:{
 info(){
 return this.isHot ? '炎热' : '凉爽'
 }
 },
 methods: {
 changeWeather(){
 this.isHot = !this.isHot
 }
 },
 })
 </script>
- 监视方法,利用 - watch实现- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41- <div id="root"> 
 <h2>今天天气很{{info}}</h2>
 <button @click="changeWeather">切换天气</button>
 </div>
 <script type="text/javascript">
 const vm = new Vue({
 el:'#root',
 data:{
 isHot:true,
 },
 computed:{
 info(){
 return this.isHot ? '炎热' : '凉爽'
 }
 },
 methods: {
 changeWeather(){
 this.isHot = !this.isHot
 }
 },
 // watch 的第一种写法
 /* watch:{
 isHot:{
 immediate:true, //初始化时让handler调用一下
 //handler什么时候调用?当isHot发生改变时。
 handler(newValue,oldValue){
 console.log('isHot被修改了',newValue,oldValue)
 }
 }
 } */
 })
 // watch 的第二种写法
 vm.$watch('isHot',{
 immediate:true, //初始化时让handler调用一下
 handler(newValue,oldValue){
 console.log('isHot被修改了',newValue,oldValue)
 }
 })
 </script>
深度监视
深度监视:
- Vue中的watch默认不监测对象内部值的改变(一层)。
- 配置
deep:true可以监测对象内部值改变(多层)。- 备注:
- Vue自身可以监测对象内部值的改变(setter监测到了),但Vue提供的watch默认不可以!
- 使用watch时根据数据的具体结构,决定是否采用深度监视。
| 1 | <body> | 
监视的简写形式
简写模式下,默认:
immediate为false
deep为false
| 1 | // 向 Vue 传入 watch 配置对象写法 | 
watch对比computed
computed和watch之间的区别:
computed能完成的功能,watch都可以完成。
watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
解释:因为computed依靠return返回值,而 return 不能延时/异步
两个重要的小原则:
- 所
被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。- 所有
不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),
最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。
| 1 | <!-- 姓名案例_watch实现 --> | 
绑定样式
- class 样式- 写法 - :class="xxx",xxx 可以是字符串、对象、数组。- 字符串写法适用于:类名不确定,要动态获取。
- 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
- 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
 
- style 样式- :style="{fontSize: xxx}"其中xxx是动态值。- :style="[a,b]"其中a、b是样式对象。
| 1 | <style> | 
条件渲染
v-if写法:
v-if="表达式"
v-else-if="表达式"
v-else="表达式"适用于:切换频率较低的场景。 特点:不展示的DOM元素直接被移除。 注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。
v-show
写法:
v-show="表达式"适用于:切换频率较高的场景。 特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
备注:
使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到
| 1 | <div id="root"> | 
列表渲染
key作用与原理
列表过滤
列表排序
更新时的一个问题
Vue监测数据的原理_对象
Vue.set()方法
Vue监测数据的原理_数组
总结Vue监视数据
收集表单数据
过滤器
v-text指令
v-html指令
v-cloak指令
v-once指令
v-pre指令
自定义指令_函数式
自定义指令_对象式
自定义指令总结
生命周期
组件
Vuex
- 安装VueX- Vue2中,要使用Vuex的3版本- $ npm i vuex@3
 
- Vue3中,要使用Vuex的4版本- $ npm i vuex
 
 
- Vue2中,要使用Vuex的3版本
| 1 | $ npm i vuex | 



