【尚硅谷】Vue2.x核心学习笔记--渐进式的JS框架

在这里插入图片描述


一、Vue的基本认识

Vue是一款渐进式的JavaScript框架库,作者是尤雨溪,作用是的动态的构建用户界面

官网地址:https://cn.vuejs.org/

1.1 Vue特点

  1. 遵循MVVM模式
  2. 编码简洁,体积小,运行效率高,适合移动端和PC端开发
  3. 本身是关注UI,可以轻松的引入Vue插件或者其他第三方库

1.2 与其他的前端Js框架的关联

Vue的作者尤雨溪在开源此框架的时候,就说Vue是借鉴了angular的模板和数据绑定技术和react的虚拟dom以及组件化

1.3 Vue的扩展插件

  1. vue-cli:vue的脚手架,下载基于Vue的项目 声明好了一些配置依赖
  2. vue-resource(axios官方推荐):ajax请求
  3. vue-router:路由
  4. vuex:状态管理
  5. vue-lazyload:图片懒加载
  6. vue-scoller:页面滑动相关
  7. mint-ui:基于vue的UI组件库(移动端)
  8. element-ui:基于vue 的UI组件库(PC端)

二、Vue的基本使用

2.1 效果

在这里插入图片描述
实现数据的双向绑定的案例

2.2 如何引入Vue.js

初学者建议使用CDN引入Vue.js的方式来使用,官网也是建议初学者这样来学习Vue。后期我们可以使用Vuecli来创建Vue的项目来实现

【引入Vue】

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

当然也可以下载Vue的js文件,通过script标签来引入Vue

2.3 声明式渲染 v-model

【官网案例】

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:

<script src="./js/vue.js"></script> <!--也可以使用CDN来引入,需要网络环境-->

<!-- MVVM 模型中的V(View视图)-->
<div id = "app">
    <input type="text" v-model="username"/>
    <p>{{ username }}</p>
</div>

<script>
    const vm = new Vue({ // 配置对象 实例化一个Vue的实例对象 VM 视图对象
        el: '#app', // id选择器 el:元素 值是一个选择器 实例的
        data: { // 数据Model M data的只是一个对象
            username: 'Hello Vue! '
        }
    })
</script>

【案例解析】:

  1. 引入Vue.js

  2. 创建Vue实例对象 一般使用Const 声明一个常量 MVVM中的VM 虚拟对象

    • el:指定根element(选择器)
    • data:初始化数据(页面可以访问)MVVM中的M 数据
  3. 双向绑定数据:v-model

  4. 显示数据:{{xxx}}

  5. 理解Vue的MVVM实现

2.4 理解MVVM模型

在这里插入图片描述

【MVVM】模型解读

  • model:M 模型—> Data 数据对象,可以自动给View显示使用(Vue的实例)

  • View:V 视图—> 模板页面

    • 指令:Vue提供的一些标签属性,例如v-model (数据绑定)…
    • {{}} 大括号表达式:用于显示数据
  • View Model VM —> Vue的实例对象

    • 通过数据绑定 将M的数据动态的传输给View

VM 是Vue的实例对象,不是Vue

那么Vue是如何实现数据的双向绑定的呢?
在这里插入图片描述

三、模板语法

3.1 效果

在这里插入图片描述

3.2 模板的理解

【官网解释:】
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。

【总结】

模板就是动态的Html页面,包含了一些JavaScript语法代码、双大括号表达式、指令(以v-打头的自定义标签属性)

3.3 双大括号表达式 {{}}

<h1>双大括号插值语法</h1>
<h3>你好{{msg}}</h3>
<p>全部大写:{{msg.toUpperCase()}}</p>
<p v-text="a_tip"></p> <!--会将绑定的数据作为纯文本解析 类似于innerText-->
<p v-html="a_tip"></p> <!--会识别Html标签 类似于innerHtml-->
  • {{}}:数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值
  • 使用双大括号绑定的数据
  • 既然绑定的是对象,那么就可以先弄个Js一样调用函数
  • 双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html
  • 双大括号语法有一个等效的指令:v-text

3.4 指令一:强制数据绑定 v-bind

<div id="root">
	<h1>强制数据绑定</h1>
	<img :src="imgUrl" alt="">
	<a v-bind:href="url">点我去被百度</a>
	<div :id="show?'div':''"></div>
	<hr>
</div>

<script type="text/javascript">
    const vm = new Vue({
        el:"#root",
        data:{
            show:true,
        }
</script>

<style type="text/css">
    #div{
        width: 200px;
        height: 200px;
        background-color: #4caf50;
    }
</style>
  • 普通的插值语法不能做用在Html属性上,如果需要动态绑定属性需要使用 v-bind
  • v-bind可以简写为:
  • v-bind就可以实现数据的双向绑定

3.5 指令二:绑定事件监听 v-on

<div id="root">
	<h1>事件绑定监听</h1>
	<button v-on:click="test">test</button>
</div>

<script type="text/javascript">
    const vm = new Vue({
        el:"#root", // 指定容器
        data:{}, 	// 用于绑定数据
        methods:{ 	// 用于绑定事件
            test(){
                alert(111)
            }
        }
    })

</script>
  • v-on语法用于绑定vue的事件
  • 需要在script里面写一个methods:{}来进行事件的声明
  • v-on的缩写形式是@

3.6 指令三:条件渲染 v-show|v-else-if

<div id="root">
	<h1>逻辑判断</h1>
    <p v-show="show">我显示了</p>
    <p v-show="!show">我没显示了</p>

    <p v-if="Math.random()>0.5">you win,l am lose</p>
    <p v-else> I am lose ,you win</p>

    <div v-if="type === 'A'">
        A
    </div>
    <div v-else-if="type === 'B'">
        B
    </div>
    <div v-else-if="type === 'C'">
        C
    </div>
    <div v-else>
        Not A/B/C
    </div>
</div>

<script type="text/javascript">
    const vm = new Vue({
        el:"#root",
        data:{
            type:'B',
        },
</script>
  • v-show:根据表达式之真假值 触发显示与否
  • v-if:当和 v-if 一起使用时,v-for 的优先级比 v-if 更高。
  • v-else可以和v-if搭配使用,和Java的if-else一样的用法 前一兄弟元素必须有 v-if 或 v-else-if。
  • v-else-if 前置条件:必须有 v-if 或 v-else-if

3.7 列表渲染 v-for

列表渲染指令

  • 数组:v-for/index
  • 对象:v-for/key
<div id="app">
    <label>遍历数组</label>
    <br>
    <span v-for="item in list">{{item}}&nbsp;</span>
    <hr>
    <label>遍历数组对象</label>
    <br>
    <li v-for="(user,index) in list1" :key="index">
        用户编号:{{user.userid}}--;用户姓名:{{user.username}}--;索引:{{index}}
        <button @click="del(index)">删除</button>
        <button @click="upd(index,{userid:2,username:'李老头'})">更新</button>
        <button @click="add(index,{userid:5,username:'小王'})">添加</button>
    </li>
    
    <hr>
    <label>遍历对象</label>
    <br>
    <li v-for="(value,key,index) in list2">对象的键:{{key}}--;对象的值:{{value}}-- ;索引:{{index}}</li>
</div>

<script>
    var vm = new Vue({
        // vue本身是监视list1的改变 而非监视的是list1内部的内容
        // vue重新给了数组中一些列改变数组内部数据的方法
        // 逻辑:先调用原生的 在更新页面--->数组内部改变
        el: '#app',
        data: {
            list: [1, 2, 3, 4, 5, 6, 7, 8],
            list1: [
                {userid: 1, username: 'zs1'},
                {userid: 2, username: 'zs2'},
                {userid: 3, username: 'zs3'},
                {userid: 4, username: 'zs4'}
            ],
            list2: {
                id: 1232,
                name: '托尼.琼斯',
                gender: 'female'
            }
        },
        methods:{
            del(index){
                this.list1.splice(index,1)
            },
            upd(index,obj){
                console.log(this.list1[index].userid,this.list1[index].username)
                // this.list1[index] = obj // 并没有改变list1本身,数组内部发生了变化,但是并没调用变异方法,所有vue不会更新页面
                this.list1.splice(index,1,obj)
            },
            add(index,obj){
                this.list1.splice(index+1,0,obj)
            }
        }
    });
</script>

注意: Vue重写了数组中改变数组内部数据的一些方法,并取名为变异方法

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

【小结】:如上例,当我在修改一个数组的元素的时候,当我们使用this.list1[index] = obj的时候,其实时将数组中的内部的数据改了,但是这样并没有让list1知道,因为并没有调用变更方法。所以页面数据不会变

3.7.1 列表过滤和排序案例

<div id="app">
    <label for="condition">过滤条件</label>
    <input type="text" id="condition" placeholder="请输入过滤条件"
           v-model="queryByName">
    <ul>
        <li v-for="(p,index) in filterPersons" :index="index">
            {{p.username}}--{{p.age}}
        </li>
    </ul>
    <button @click="updateOrderType(1)">年龄升序排序</button>
    <button @click="updateOrderType(-1)">年龄降序排序</button>
    <button @click="updateOrderType(0)">原本排序</button>
</div>

<script>
    var vm = new Vue({

        el: '#app',
        data: {
            orderType: 0, // 0表示原本顺序 ;1代表升序 ;-1代表降序
            persons: [
                {userid: 1, username: 'Tom', age: 21},
                {userid: 2, username: 'Jack', age: 45},
                {userid: 3, username: 'Rose', age: 23},
                {userid: 4, username: 'Kappy', age: 21},
                {userid: 5, username: 'Sendy', age: 18},
                {userid: 6, username: 'Loray', age: 36},
                {userid: 7, username: 'Jessay', age: 39},
                {userid: 8, username: 'Navie', age: 28},
            ],
            queryByName: '',
        },
        methods:{
            updateOrderType(orderType){
                this.orderType = orderType;
            }
        },
        computed: {
            filterPersons() { // 过滤条件后新的数组对象
                // 取出相关的数据
                const {queryByName, persons, orderType} = this
                // 最终需要显示的数组
                let fpersons;
                // 对persons进行过滤
                fpersons = persons.filter(ps => ps.username.indexOf(queryByName) !== -1);
                // 排序
                if (orderType !== 0) {
                    // 排序函数 sort 传入对比对象
                    fpersons.sort(function (p1, p2) { // 如果返回负p1在前,代表升序
                        // 升序 1 降序 -1
                        if (orderType == 1) {
                            return p1.age-p2.age;
                        } else {
                            return p2.age - p1.age;
                        }
                    })
                }
                return fpersons;
            }
        }
    });
</script>

3.8 表单数据交互 v-model🔥🔥

v-model指令可以在表单 input、textarea以及select元素上创建双向数据绑定;

3.8.1 v-model的原理

官方有说到,v-model的原理其实是背后有两个操作:

  • v-bind绑定value属性的值;
  • v-on绑定input事件监听到函数中,函数会获取最新的值赋值到绑定的属性中;
<input v-model="Text" type="text"/>
<!--等效于-->
<input type="text" :vlaue="Text" @input="Text=$event.target.value">
  • v-model 绑定textarea的时候,其绑定的数据即为输入的文本内容
  • v-model 绑定checkbox的时候
    • 选中单个复选框:数据是布尔类型,选中则为true,否则为false
    • 选中多个复选框:对应的data是一个数组
  • v-model绑定select下拉列表
    • 选中一个下拉列表:数据时该列表的value值
    • 选中多个下来列表:数据是选中的列表的value组成的数组
  • v-model绑定radio的时候,数据即为选中的value值
<div id="root">
        <div><input type="radio" value="male" v-model="gender"><input type="radio" value="female" v-model="gender">
            <span>当前的性别是:{{gender}}</span>
        </div>
        <div>
            <select name="" id="" v-model="hobbies" multiple>
                <option value="苹果">苹果</option>
                <option value="栗子">栗子</option>
                <option value="西瓜">西瓜</option>
                <option value="香蕉">香蕉</option>
            </select>

            <span>当前选中的:{{hobbies}}</span>
        </div>
    </div>

四、计算属性和监听

4.1 效果

在这里插入图片描述

4.2 计算属性🔥🔥

说的通俗一点:就是相互依赖
一个数据, 依赖另外一些数据计算而来的结果

<div id="app">
    姓:<input type="text" placeholder="First Name" v-model="firstName"><br>
    名:<input type="text" placeholder="Last Name" v-model="lastName"><br>
    姓名1(单向):<input type="text" placeholder="Full Name1" v-model="fullName"><br>
    姓名2(单向):<input type="text" placeholder="Full Name2" v-model="fullName1"><br>
    姓名3(双向):<input type="text" placeholder="Full Name3"><br>
</div>

<script>
    Vue.config.productionTip = false;
    var vm = new Vue({
        el: "#app",
        data: {
            firstName: "A",
            lastName: 'B',
            fullName: 'A B'
        },
        computed: { // 计算属性 相当于是一个函数一样 可以监听
            // 什么时候执行:初始化显示/相关的data属性发生变化
            fullName1() {//计算属性的一个方法 返回一个值作为属性值
                return this.firstName + ' ' + this.lastName // 会将值存入缓存中 只要first Name或者lastName中任意一个改变,则重新计算
            }
        }
    })
</script>
  • 计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。
  • 给计算属性赋值:需要使用set:set接受赋予的值
  • 返回结果需要用到get
export default {
    computed: {
        fullName2: {
                set(val) { 
                    console.log(val)
                },
                get() { // 计算并返回当前属性的值
                    return this.firstName + ' ' + this.lastName
                }
            }
    }
}

4.3 监听属性

watch: { [key: string]: string | Function | Object | Array }

一个对象,键是需要观察的表达式,值是对应回调函数。 值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个 property。

<div id="app">
    姓:<input type="text" placeholder="First Name" v-model="firstName"><br>
    名:<input type="text" placeholder="Last Name" v-model="lastName"><br>
    姓名2监视(单向):<input type="text" placeholder="Full Name2" v-model="fullName2"><br>
</div>

<script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el: "#app",
        data: {
            firstName: "A",
            lastName: 'B',
            fullName: 'A B',
        },
        watch: { // 配置监视
            firstName: function (value) { // first的值发生变化 需要修改fullName1
                this.fullName2 = value + ' ' + this.lastName
            }
        }
    })
    // 监听方法 $开头的
    vm.$watch('lastName',function (newVal) {
        console.log(this) // vue的实例对象vm
        this.fullName2 = this.firstName+' '+newVal
    })
</script>
  • vm.$watch( expOrFn, callback, [options] )
    • 参数:
    • {string | Function} expOrFn :监视的对象
    • {Function | Object} callback :回调函数 监视对象发生变化时的操作
    • {Object} [options]
      • {boolean} deep :为true时表示发现监听监听对象发生化,默认是true
      • {boolean} immediate :为true时,立即触发回调

4.3.1 深度监听 deep

<!--view层 模板-->
<div id="app">
    <p>{{num.a}}</p>
    <button @click="num.a++">点我a+1</button>
    <p>{{num.b}}</p>
    <button @click="num.b++">点我b+1</button>
</div>
</body>

<!--导入js-->
<script src="./js/vue.js"></script>
<script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el: "#app",
        data: {
            num:{
                a:1,
                b:1,
            }
        },
        methods: {},
        watch: {
            //监视多级结构中所有属性的变化
            num:{
                deep:true,
                handler(){
                    console.log('a的值改变了',this.num.a)
                    console.log('b的值改变了',this.num.b)
                }
            }
        }
    })
</script>

【小结】

Vue所提供的深度监听属性,可以帮助我们监听一些层级比较深的值,比如说一个对象、多级数组等。

  • vue默认是不支持深度监听的,只有我们设置了deep:true才会监视深层的对象数据
  • 我们在使用数据监听的时候,根据需要配置是否开启深度监听
  • 但是监听一般没有计算属性好用(个人认为),但是功能比较灵活。

4.4 计算属性高级

🔥🔥计算属性存在缓存,多次读取相同的条件表达式只执行一次getter计算

<div id="app">
    姓:<input type="text" placeholder="First Name" v-model="firstName"><br>
    名:<input type="text" placeholder="Last Name" v-model="lastName"><br>
    姓名3(双向):<input type="text" placeholder="Full Name3" v-model="fullName3"><br>
</div>

<script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el: "#app",
        data: {
            firstName: "A",
            lastName: 'B',
            fullName: 'A B',
        },
        computed: { // 计算属性 相当于是一个函数一样 可以监听
            fullName3: {
                get() {
                    return this.firstName + " " + this.lastName
                },
                set(value) {
                    const names = value.split(" ")
                    this.firstName = names[0]
                    this.lastName = names[1]
                }
            }
        }
    })
</script>

五、class和style的绑定

5.1 效果

在这里插入图片描述

5.2 理解

  1. 在应用界面中,某个元素的样式是变化的
  2. class/style绑定就是专门来实现动态样式效果的技术

5.3 class绑定

【绑定语法】::class=xxx

  • xxx是一个字符串
  • xxx是一个对象
  • xxx是一个数组
<div id="root">
    <h2>1.Class绑定::class='xxx'</h2>
    <!--绑定的是个字符串-->
    <h4>xxx是字符串</h4>
    <p :class="bgRed">背景色红色</p>
    <button @click="update">切换为粉色背景,字号30px</button>
    <!--绑定的只是一个对象-->
    <hr>
    <h4>xxx是对象</h4>
    <!--对象名:是一个类名:值是布尔类型 为true显示,否则不显示-->
    <p :class="{red:isRed,pink:isPink}">背景色红色</p>
    <button @click="update2">切换为粉色背景,字号30px</button>
    <hr>
    <h4>xxx是数组</h4>
    <p :class="['red','pink']">背景色红色</p>
</div>

<script type="text/javascript">
    const vm = new Vue({
        el: "#root",
        data: {
            bgRed: 'red',
            isRed: true,
            isPink: false,
        },
        methods: {
            update() {
                this.bgRed = 'pink font30'
            },
            update2() {
                this.isRed = false
                this.isPink = true
            },
        }
    })
</script>

<style type="text/css">
    #root {
        color: darkgreen;
    }

    .red {
        background-color: red;
    }

    .pink {
        background-color: pink;
        font-size: 30px;
    }
</style>

5.4 style绑定

【绑定语法】::style="{color:‘red’,backgroundColor:activeBgc,....}"

其中的activeBgc是一个data属性

<div id="root">
    <h2>1.style绑定</h2>
    <p :style="{fontSize:'30px',width:width,height:height,backgroundColor:bgc}">111</p>
    <button @click="update3">点我改变</button>
</div>

<script type="text/javascript">
    const vm = new Vue({
        el: "#root",
        data: {
            width:'100px',
            height:30,
            bgc:'skyblue'
        },
        methods: {
            update3(){
                this.width = '200px'
                this.height= 45
                this.bgc = 'yellow'
            }
        }
    })
</script>

六、事件处理

6.1 绑定监听 v-on

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

前面讲过,这里主要介绍下$event这个属性。

  • $event是指当前触发的是什么事件(鼠标事件,键盘事件等)
  • $event.target则指的是事件触发的目标,即哪一个元素触发了事件,这将直接获取该dom元素

下面是例子:

eve(event){
   console.log(event)
}

在这里插入图片描述

6.2 事件修饰符

原生JS中,我们在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。但是 这样在vue里仍不时最佳实践

vue提供的:但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

  • .stop:阻止事件冒泡
  • .prevent:阻止默认的事件发生
  • .capture:添加事件监听器时使用事件捕获模式
  • .self:只有当前元素才触发
  • .once:事件只会被触发一次 [2.1.4新增特性]
  • .passive:告诉浏览器你不i想阻止的事件的默认行为,所以不要和.prevent连用 [2.1.4新增特性]
<div id="root">
    <h2>2. 事件修饰符</h2>
    <div style="width: 200px;height: 200px;background-color: red;" @click="test2">
        <div style="width: 100px;height: 100px;background-color: blue;" @click.stop="test3">

        </div>
    </div>

    <a href="http://www.baidu.com" @click.prevent="testa($event)">百度</a>
</div>
<script>
    Vue.config.productionTip = false;
    // 创建Vue实例
    const vm = new Vue({
        el: '#root',
        data: {},
        methods: {
            test2() {
                alert("out")
            },
            test3(event) {
                alert("in")
                // event.stopPropagation() // 原生的方式
            },
            testa(event){
                // 阻止默认提交事件
                // event.preventDefault()
                alert(111)
            },
        }
    });
</script>

6.3 按键修饰符

在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">

你可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。

<input v-on:keyup.page-down="onPageDown">

在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用。

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
我认为Vue的人性化的一点,帮我们声明了一些常用的按键别名

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right
<div id="root">
    <h2>3. 按键修饰符</h2>
    <button @click="eve($event)" name="哈哈">单击</button>
    <input type="text" @keyup.13="enter" placeholder="按下enter(13)弹出提示">
    <input type="text" @keyup.space="enter" placeholder="按下space弹出提示">
    <input type="text" @keyup.65="enter" placeholder="按下a弹出提示">
    <input type="text" @keyup.enter="enter" placeholder="按下enter弹出提示">
</div>
<script>
    Vue.config.productionTip = false;
    // 创建Vue实例
    const vm = new Vue({
        el: '#root',
        data: {},
        methods: {
            enter(event){
                // enter键的ascii码为13
                // if (event.keyCode === 13) {
                //     alert(event.target.value)
                // } // 原生写法
                alert(event.target.value)
            }
        }
    });
</script>

七、Vue实例生命周期

7.1 效果

在这里插入图片描述

7.2 生命周期流程图

官网为我们提供了一个Vue实例的生命周期流程图
在这里插入图片描述

7.3 生命周期分析

【流程分析】:

  1. 当我们new Vue()的时候,首先在初始化之前有一个beforeCreate,就是在初始化生命周期之前的一些比如说参数的设置等操作。
  2. 在早一些的版本中,在beforeCreate之后还有一个observe监视的环节,目的就是用于监视数据的变化(set)
  3. 初始化后,也就是created之后,进入一个判断,判断有没有el 有的话在判断有没有template这个东西。没有el的话需要我们手动配置vm.$mount(el)
  4. 在判断是否有template中,如果没有则 在内存中先编译 我们绑定的内部的el容器里的所有模板元素;有的话则 直接在内存中编译已有模板元素 并渲染进一个函数中
  5. 将内存中编译好的数据,在mounted挂载到页面上。在挂在之前有一个beforeMount,在挂载之后有一个mounted。 至此,第一个阶段,初始化就完毕
  6. 当数据被挂载到页面了之后,当数据发生了变化之后,我们需要对页面进行更新操做,这时候,我们就需要用到update方法,同理,在更新之前有一个beforeUpdate,在更新之后有一个updated方法
  7. 最后一个阶段:死亡,这里和React不一样的是,此时的页面数据仍然会在,但是,此时的VM已经不起作用了

7.4 常用的生命周期方法

【小结】

vue对象的声明周期:

  1. 初始化显示
    • beforeCreate()
    • created()
    • beforeMount()
    • mounted()
  2. 更新显示:this.xxx = value 修改数据的操做
    • beforeUpdate()
    • updated()
  3. 销毁Vue是对象,vm.$destroy()
    • beforeDestroy()
    • destroyed()

【案例演示】

<div id="root">
    <button @click="destroyVm">按钮--destory vm</button>
    <p v-show="isShow">尚硅谷Vue2.x教程</p>
</div>

<script type="text/javascript">
    Vue.config.productionTip = false;
    const vm = new Vue({
        el: "#root",
        data: {
            isShow:true
        },
        methods: {
            destroyVm(){
                this.$destroy()
            }
        },
        // 初始化阶段
        beforeCreate(){
            console.log("beforeCreate执行了")
        },
        created(){
            console.log("Created执行了")
        },
        beforeMount(){
            console.log("beforeMount执行了")
        },
        mounted(){
            console.log("mounted执行了")
            this.timer = setInterval(()=> { // 初始化显示之后立即调用一次 使用匿名函数 否则this变成window
                console.log("-------")
                // 匿名函数的特点是本身没有this 所以这里的this就是vm
                this.isShow=!this.isShow
            },1000)
        },
        // 更新阶段
        beforeUpdate(){
            console.log("beforeUpdate执行了")
        },
        update(){
            console.log("update执行了")
        },
        // 销毁阶段
        beforeDestroy(){ // 销毁之前调用一次
            console.log("beforeDestroy执行了")
            clearInterval(this.timer)
        },
        destroyed(){
            console.log("销毁方法执行了")
        }
    })
</script>

在这里插入图片描述
常用的Vue声明周期函数:

  • mounted():发送Ajax请求,启动定时器等异步操作,在后面我们使用Axios完成异步请求的发送的时候,就用到mounted方法。
  • beforeDestroy():收尾工作,如:消除定时器等

八、过度与动画

8.1 Vue动画的理解

记住一点:世界的本质就是套娃,任何高大上的技术都离不开最原始的技术。

  1. vue的动画操做实际上就是对Css的Trasition或者animation的封装
  2. 动画的产生就是在起始的时候加一个样式,在切换另一个事件过渡期间,再换上另外一个终止样式,Vue也不例外。
  3. 过渡的相关类名:
    • xxx-enter-active: 指定显示的transition
    • xxx-leave-active: 指定隐藏的transition
    • xxx-enter/xxx-leave-to: 指定隐藏时的样式

8.2 官网案例分析

【单元素组件过渡】

<div id="root">
    <button v-on:click="show = !show">
        Toggle
    </button>
    <transition name="myTransition">
        <p v-if="show">hello</p>
    </transition>
</div>
<style type="text/css">
	/*这里是什么意思???*/
    .myTransition-enter-active, .myTransition-leave-active {
        transition: opacity .5s;
    }
    .myTransition-enter, .myTransition-leave-to /* .myTransition-leave-active below version 2.1.8 */ {
        opacity: 0;
    }
</style>
<script src="js/vue.js"></script>
<script type="text/javascript">

    Vue.config.productionTip = false;
    const vm = new Vue({
        el:"#root",
        data(){
            return {
            	show:true
        },
    })
</script>

在这里插入图片描述

🙅🙅🙅在看源码的初期,我们可能会有这样一个疑问,css样式里的代码我好像熟悉,但是又不熟悉,哈哈哈哈,这难道就是最熟悉的陌生“人”么❓❓❓

8.2.1 分析

在这里插入图片描述

对于这些在过渡中切换的类名来说,如果你使用一个没有名字的
<transition>,则 v- 是这些类名的默认前缀。
🔥🔥🔥:如果你使用了 <transition name="my-transition">,那么 v-enter 会替换为 my-transition-enter。,比如我在案例中将transition的name属性修改为了myTransition则后续的所有xxx将被替换为myTransition

v-enter-active 和 v-leave-active 可以控制进入/离开过渡的不同的缓和曲线,在下面章节会有个示例说明。

搞清楚之一点之后,我们回过头来再看之前那段那一理解的代码🧧

在这里插入图片描述
将他拆分成两部分,❤️红色区域和 💚绿色区域

  • ❤️ 两个类名 分别是进入和离开的过程中的过渡动画 含义是一个持续时间为0.5s的透明动画
  • 💚 两个类名,分别是进入之前离开之后 透明度为0 也就是隐藏时的样式

这么一看,嗨嗨,原来如厕儿🕵️

8.3 基本动画的步骤

  1. 在目标的元素外包裹<transition name=“xxx”>
  2. 定义class样式
    • 指定过渡样式 transition
    • 指定隐藏时的样式 opacticy / 其他

8.4 Vue的animation

CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在animationend 事件触发时删除。

<div id="root">
    <button @click="Change=!Change">text Change</button>
    <transition name="textChange">
        <p v-if="Change" id="div">富裕国家古迹看</p>
    </transition>
</div>
<style type="text/css">
    /*显示/隐藏的过渡效果*/
    .textChange-enter-active {
        animation: fade-big .5s;
    }

    .textChange-leave-active {
        animation: fade-big .5s reverse;
    }

    @keyframes fade-big {
        0% {
            transform: scale(0);
        }
        50% {
            transform: scale(1.5);
        }
        100% {
            transform: scale(1);
        }
    }

    /*隐藏式的样式*/
    .textChange-enter, .textChange-leave-to {
        opacity: 0;
    }

    button {
        margin: 10px 0;
    }

    #div {
        width: 600px;
        height: 100px;
        background-color: orangered;

    }

</style>
<script src="js/vue.js"></script>
<script type="text/javascript">
    Vue.config.productionTip = false;
    const vm = new Vue({
        el: "#root",
        data() {
            return {
                Change: true,
            }
        },
    })
</script>

九、过滤器

Vue的过滤器:是对我们要显示的数据进行格式化的一个技术点

9.1自定义过滤器

Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:

9.1.1 语法格式

  1. 定义过滤器
<script>
Vue.filter(filterName,function(value[,arg1,arg2,...]){
	// 进行一定的数据处理
	return newValue; 
)
</script>
  1. 使用过滤器
<!-- 在双花括号中 -->
{{ message | filterName}}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | filterName(args)"></div>

先来看如何定义过滤器,从官网给出的实例我们可以知道filter是Vue的方法,但是你会发现有点怪 为什么是Vue.filter,那么就要把Vue的过滤器分一下类了:

  • 全局过滤器:全局过滤器是通过Vue.filter()来定义的,定义好后,它在所有组件中都可以使用。
  • 组件过滤器:定义在组件内部 filters 属性上.它只能在此组件内部使用,有时也叫做局部过滤器。

【全局过滤器】

Vue.filter('filterName', function (value,...args) {
	// 相关的处理
    // 返回一个格式化好的数据
    return newValue; // 返回的新值
});
  • filterName是过滤器名称。
  • 函数第一个参数value是需要过滤的数据。
  • 函数第二个参数args是给过滤器传递的值,是一个可变形参。

【局部过滤器】

var app = new Vue({
    el: '#app',
    data: {
      oldValue: '原始数据'
    },
    methods: {},
    // 定义组件过滤器
    filters: {
      // 过滤器需要处理的方法
      priceFmt(val,...args) {
        	return newValue;
        }
      }
    })

注意: 在局部过滤器中使用的filters 需要加上s。而全局过滤器是filter

9.1.2 案例格式化时间

<div id="root">
    <h1>显示日期格式化</h1>
    <p>原始的时间格式:{{date}}</p>
    <p>格式化的时间格式:{{date | dateFilter}}</p>
    <p>格式化的时间格式:{{date | dateFilter('YYYY年MM月DD日')}}</p>
    <p>格式化的时间格式:{{date | dateFilter('HH时mm分ss秒')}}</p>
</div>
<script src="js/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.3/moment.js"></script>
<script type="text/javascript">
    // 这里的value参数是我们即将要格式化的时间数据
    Vue.filter('dateFilter', function (value,format) {
        // 格式化时间 moment库 一个js的时间库

        // 返回一个格式化好的数据
        return moment(value).format(format || 'YYYY-MM-DD HH:mm:ss');
    });
    Vue.config.productionTip = false;
    const vm = new Vue({
        el:"#root",
        data:{
            date:new Date()
        }
    })
</script>

在这里插入图片描述
这里应用了一个时间的javaScript库—moment库
moment官网地址:http://momentjs.cn/

9.2 过滤器应用场景

  • 单位转换
  • 数字打点
  • 文本格式化
  • 时间格式化
  • 货币格式化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@WAT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值