• Vue2基础学习


    Vue2快速入门

    Vue2视频教程地址(b站尚硅谷

    B站视频教程地址:https://www.bilibili.com/video/BV1Zy4y1K7SH?spm_id_from=333.1007.top_right_bar_window_default_collection.content.click&vd_source=b064d59376e0ccfa2b99b00cf3bb0ad0

    初识Vue

    入门示例

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>初识Vuetitle>
    		
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		
    
    		
    		<div id="demo">
    			<h1>Hello,我叫{{name}},来自{{address}}!h1>
    		div>
    
    		<script type="text/javascript" >
    			Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
    			//创建Vue实例
    			new Vue({
    				el:'#demo', //全称`element` 用来绑定所创建容器的`DOM` 对象(不仅仅可以通过`id` 选择器绑定)
    				data:{ //存储数据供绑定的容器获取对应的值
    					name:'mtf',
    					address:'河南'
    				}
    			})
    		script>
    	body>
    html>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    环境搭建

    • 导入Vue所需资源文件(在线或本地都可)
    • 创建容器
    • 创建Vue实例来绑定所常见的容器(这里使用的是id 选择器进行容器的绑定)
    • Vue实例参数:
      • el :全称element 用来绑定所创建容器的DOM 对象(不仅仅可以通过id 选择器绑定)
      • data :存储数据供绑定的容器获取对应的值

    模板语法

    模板语法主要分为:插值语法{{参数或者js表达式}}指令语法(用于解析标签,包括:标签属性、标签体内容、绑定事件…)

    示例

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>模板语法title>
    		
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		
    		<div id="root">
    			<h1>插值语法h1>
              	
    			<h3>你好,{{name}}!h3>
    			<hr/>
    			<h1>指令语法h1>
              	
    			<a v-bind:href="school.url.toUpperCase()">点我去{{school.name}}官网学习a>
    			<br>
    			<br>
              	
    			<a :href="school.url">点我还去{{school.name}}官网学习a>
    		div>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
    		new Vue({
    			el:'#root',
    			data:{
    				name:'mtf',
    				school:{
    					name:'aynu',
    					url:'http://www.aynu.edu.cn/',
    				}
    			}
    		})
    	script>
    html>
    
    • 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

    插值语法

    • 插值语法功能:用于解析标签体内容
    • {{xxx}} 中的xxx可以是data 中的数据,也可以是js表达式,且xxx可以自动读取到data中的所有属性;

    指令语法

    • 指令语法功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)
    • v-bind:href="xx" :引号中的xx 可以data 中的参数也可以是表达式,参考上面示例

    数据绑定

    Vue中的数据绑定主要分为单向数据绑定双向数据绑定

    单向数据绑定

    什么叫单向数据绑定:用户不能通过前端页面输入的值来改变前端代码里面的data 所对应的值(需要进一步总结

    
    单向数据绑定:<input type="text" v-bind:value="name"><br/>
    
    
    单向数据绑定:<input type="text" :value="name"><br/>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    双向数据绑定

    什么叫双向数据绑定:浏览器页面的数据能够从后台代码获取,同时也可以通过修改浏览器页面的数据并响应到后台

    • 注意:双向数据绑定v-model 指令语法只适用于表单标签(这样记:因为只有表单能够让我们在前端浏览器输入数据,才具备浏览器数据修改并响应到后台的前提条件)
    
    双向数据绑定:<input type="text" v-model:value="name"><br/>
    
    
    双向数据绑定:<input type="text" v-model="name"><br/>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    eldata 两种写法

    示例

    //el的两种写法
    const v = new Vue({
    //el:'#root', //第一种写法
      data:{
              name:'mtf'
          }
    })
    console.log(v)//Vue实例对象
    v.$mount('#root') //第二种写法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    //data的两种写法
    new Vue({
    el:'#root',
    //data的第一种写法:对象式
    data:{
    	name:'尚硅谷'
    } ,
    //data的第二种写法:函数式
    data(){
    	console.log('@@@',this) //此处的this是Vue实例对象
        return{
        		name:'mtf'
        	}
    	}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    MVVM模型

    请添加图片描述

    数据代理

    回顾defineProperty

    <script type="text/javascript" >
      let number = 18
      let person = {
        name:'张三',
        sex:'男',
      }
    
    //给person对象添加一个age属性
    Object.defineProperty(person,'age',{
      value:18
    })
    
    console.log(person)
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意:上述js代码虽然能够给已经创建的对象临时添加对应的属性,可是不能通过控制台修改age 属性的值

    在这里插入图片描述

    在这里插入图片描述

    这里查阅资料了解Object.defineProperty 方法有几个可配置的属性参数

    writable:true //控制属性是否可以被修改,默认值是false
    enumerable:true, //控制属性是否可以枚举,默认值是false
    configurable:true //控制属性是否可以被删除,默认值是false
    
    • 1
    • 2
    • 3

    场景:假设设置一个number 变量,将变量中的值动态的赋值给age 属性,并且能够通过控制台动态的修改age 属性的值

    <script type="text/javascript" >
      var number = 18
      let person = {
        name:'张三',
        sex:'男',
      }
    
    //给person对象添加一个age属性
    Object.defineProperty(person,'age',{
      // value:18,
      // enumerable:true, //控制属性是否可以枚举,默认值是false
      // writable:true, //控制属性是否可以被修改,默认值是false
      // configurable:true, //控制属性是否可以被删除,默认值是false
    
      //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
        get(){
          console.log('有人读取age属性了')
          return number![给age属性赋值](E:\java\Vue\笔记图片\给age属性赋值.png)
        },
    
        //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
        set(value){
          console.log('有人修改了age属性,且值是',value)
          number = value
        }
    
    })
    
    // console.log(Object.keys(person))
    
    console.log(person)
    </script>
    
    • 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

    在这里插入图片描述

    理解数据代理

    什么叫数据代理?数据代理就是对一个对象或对象属性值的修改等一些操作的行为“委托”给它的代理对象来做。就比如说上述实例中person 对象的age 属性,对age 属性一系列的操作交给了Object 对象,Object 对象调用defaultProperty 方法操作age属性

    Vue 中的数据代理

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>Vue中的数据代理title>
    		
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		<div id="root">
    			<h2>学校名称:{{name}}h2>
    			<h2>学校地址:{{address}}h2>
    		div>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    		
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				name:'aynu',
    				address:'安阳'
    			}
    		})
    		console.log(vm)
    	script>
    html>
    
    • 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

    总结:

    • Vue的实例对象(这里我们取名vm)就是我们提到的代理对象,通过vm 代理对象我么能够更加方便的操作data 中的数据
    • 基本原理:通过Object.defineProperty()把data对象中所有属性添加到vm上,为每一个添加到vm上的属性,都指定一个getter/setter,在getter/setter内部去操作(读/写)data中对应的属性。

    事件处理

    示例

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>事件的基本使用title>
    		
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		
    		
    		<div id="root">
    			<h2>欢迎来到{{name}}学习h2>
    			<button v-on:click="showInfo">点我提示信息button>
    			<button @click="showInfo1">点我提示信息1(不传参)button>
    			<button @click="showInfo2($event,66)">点我提示信息2(传参)button>
    		div>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				name:'尚硅谷',
    			},
    			methods:{
    				showInfo(event){
    					console.log(this)
    					alert("我是傻子!")
    				},
    				showInfo1(event){
    					console.log(this) //此处的this是vm
    					alert('mtf你好!')
    				},
    				showInfo2(event,number){
    					console.log(event,number)
    					console.log(this) //此处的this是vm
    					alert('mtf你好!!')
    				}
    			}
    		})
    	script>
    html>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    事件的基本使用

    • 使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名;
    • 事件的回调需要配置在methods对象中,最终会绑定在vm上
    • methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
    • @click=“demo” 和 @click=“demo($event)” 效果一致,但后者可以传参;
    • 箭头函数

    事件修饰符

    常用事件修饰符:

    • prevent
    • once
    • stop
    
    <a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息a>
    
    
    <div class="demo1" @click="showInfo1">
      <button @click.stop="showInfo">点我提示信息button>
    div>
    
    
    <button @click.once="showInfo">点我提示信息button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    键盘事件

    绑定指定键盘按键事件

    • 绑定已有别名的按键
    <div id="root">
      <input type="text" placeholder="回车" @keydown.enter="showInfo">
    div>
    
    <script type="text/javascript">
      Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
      new Vue({
        el:'#root',
        data:{
          name:'mtf'
        },
        methods: {
          showInfo(e){
            console.log(e.key,e.keyCode)
            console.log(e.target.value)
            alert("我按回车啦!")
          }
        },
      })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 绑定自定义别名的按键
    <div id="root">
      <input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo">
    div>
    body>
    
    <script type="text/javascript">
      Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
      Vue.config.keyCodes.huiche = 13 //定义了一个别名按键(需要知道指定按键对应的Code值)
    
      new Vue({
        el:'#root',
        data:{
          name:'mtf'
        },
        methods: {
          showInfo(e){
            //控制台输出指定按键对应的Code值
            console.log(e.key,e.keyCode)
            console.log(e.target.value)
            alert("我按回车啦!")
          }
        },
      })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    计算属性

    示例(拼接姓名)

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>姓名案例_计算属性实现title>
    		
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		
    		
    		<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>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				firstName:'张',
    				lastName:'三'
    			},
    			methods: {
    				demo(){
    					
    				}
    			},
    			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>
    html>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    什么叫计算属性

    • 定义:要用的属性不存在,要通过已有属性计算得来
    • 原理:底层借助了Objcet.defineproperty方法提供的getter和setter

    下面的代码也能够满足开发的需求(在methods中定义一个计算属性的方法)

    <div id="root">
      姓:<input type="text" v-model="firstName"> <br/><br/>
      名:<input type="text" v-model="lastName"> <br/><br/>
      //注意:这里插值语法中直接调用的是下面定义的`fullName()`函数,得到的是函数的返回值
      全名:<span>{{fullName()}}span>
    div>
    
    <script type="text/javascript">
      Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
      new Vue({
        el:'#root',
        data:{
          firstName:'张',
          lastName:'三'
        },
        methods: {
          fullName(){
            return this.firstName + '-' + this.lastName
          }
        },
      })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    总结:与上述计算属性相比二者的优缺点

    • 优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。

    计算属性简写形式

    computed:{
      //完整写法
      /* fullName:{
              get(){
                console.log('get被调用了')
                return this.firstName + '-' + this.lastName
              },
              set(value){
                console.log('set',value)
                const arr = value.split('-')
                this.firstName = arr[0]
                this.lastName = arr[1]
              }
            } */
    	//简写
      fullName(){
        console.log('get被调用了')
        return this.firstName + '-' + this.lastName
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    监事属性

    示例(监视天气属性)

    <div id="root">
      <h2>今天天气很{{info}}h2>
      <button @click="changeWeather">切换天气button>
    div>
    
    <script type="text/javascript">
      Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
      const vm = new Vue({
        el:'#root',
        data:{
          isHot:true,
        },
        computed:{
          info(){
            return this.isHot ? '炎热' : '凉爽'
          }
        },
        methods: {
          changeWeather(){
            this.isHot = !this.isHot
          }
        },
        watch:{
          isHot:{
            immediate:true, //初始化时让handler调用一下
            //handler什么时候调用?当isHot发生改变时。
            handler(newValue,oldValue){
              console.log('isHot被修改了',newValue,oldValue)
            }
          },
          //简写
          /* isHot(newValue,oldValue){
          		console.log('isHot被修改了',newValue,oldValue,this)
            } */
        }
      })
    
      // vm.$watch('isHot',{
      // 	immediate:true, //初始化时让handler调用一下
      // 	//handler什么时候调用?当isHot发生改变时。
      // 	handler(newValue,oldValue){
      // 		console.log('isHot被修改了',newValue,oldValue)
      // 	}
      // })
    script>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46

    深度监视

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>天气案例_深度监视title>
    		
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		<div id="root">
    			<h2>今天天气很{{info}}h2>
    			<button @click="changeWeather">切换天气button>
    			<hr/>
    			<h3>a的值是:{{numbers.a}}h3>
    			<button @click="numbers.a++">点我让a+1button>
    			<h3>b的值是:{{numbers.b}}h3>
    			<button @click="numbers.b++">点我让b+1button>
    			<button @click="numbers = {a:666,b:888}">彻底替换掉numbersbutton>
    			{{numbers.a}}
    		div>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    		
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				isHot:true,
    				numbers:{
    					a:1,
    					b:1,
    					c:{
    						d:{
    							e:100
    						}
    					}
    				}
    			},
    			computed:{
    				info(){
    					return this.isHot ? '炎热' : '凉爽'
    				}
    			},
    			methods: {
    				changeWeather(){
    					this.isHot = !this.isHot
    				}
    			},
    			watch:{
    				isHot:{
    					// immediate:true, //初始化时让handler调用一下
    					//handler什么时候调用?当isHot发生改变时。
    					handler(newValue,oldValue){
    						console.log('isHot被修改了',newValue,oldValue)
    					}
    				},
    				//监视多级结构中某个属性的变化
    				 'numbers.a':{
    					handler(){
    						console.log('a被改变了')
    					}
    				},
    				//监视多级结构中所有属性的变化
    				numbers:{
    					deep:true,
    					handler(){
    						console.log('numbers改变了')
    					}
    				}
    			}
    		})
    	script>
    html>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    总结:

    • 监视对象属性可以根据该属性所在层级结构绝对是否采用深度监视

    计算属性和监视属性之间的区别

    计算属性能做的监视属性一定能做!但是监视属性能做的计算属性不一定能做!

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>姓名案例_watch实现title>
    		
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		<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>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				firstName:'张',
    				lastName:'三',
    				fullName:'张-三'
    			},
    			watch:{
    				firstName(val){
    					setTimeout(()=>{
    						console.log(this)
    						this.fullName = val + '-' + this.lastName
    					},1000);
    				},
    				lastName(val){
    					this.fullName = this.firstName + '-' + val
    				}
    			}
    		})
    	script>
    html>
    
    • 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

    绑定样式

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>绑定样式title>
    		<style>
    			.basic{
    				width: 400px;
    				height: 100px;
    				border: 1px solid black;
    			}
    			
    			.happy{
    				border: 4px solid red;;
    				background-color: rgba(255, 255, 0, 0.644);
    				background: linear-gradient(30deg,yellow,pink,orange,yellow);
    			}
    			.sad{
    				border: 4px dashed rgb(2, 197, 2);
    				background-color: gray;
    			}
    			.normal{
    				background-color: skyblue;
    			}
    
    			.atguigu1{
    				background-color: yellowgreen;
    			}
    			.atguigu2{
    				font-size: 30px;
    				text-shadow:2px 2px 10px red;
    			}
    			.atguigu3{
    				border-radius: 20px;
    			}
    		style>
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		
    		
    		<div id="root">
    			
    			<div class="basic" :class="mood" @click="changeMood">{{name}}div> <br/><br/>
    
    			
    			<div class="basic" :class="classArr">{{name}}div> <br/><br/>
    
    			
    			<div class="basic" :class="classObj">{{name}}div> <br/><br/>
    
    			
    			<div class="basic" :style="styleObj">{{name}}div> <br/><br/>
    			
    			<div class="basic" :style="styleArr">{{name}}div>
    		div>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false
    		
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				name:'尚硅谷',
    				mood:'normal',
    				classArr:['atguigu1','atguigu2','atguigu3'],
    				classObj:{
    					atguigu1:false,
    					atguigu2:false,
    				},
    				styleObj:{
    					fontSize: '40px',
    					color:'red',
    				},
    				styleObj2:{
    					backgroundColor:'orange'
    				},
    				styleArr:[
    					{
    						fontSize: '40px',
    						color:'blue',
    					},
    					{
    						backgroundColor:'gray'
    					}
    				]
    			},
    			methods: {
    				changeMood(){
    					const arr = ['happy','sad','normal']
    					const index = Math.floor(Math.random()*3)
    					this.mood = arr[index]
    				}
    			},
    		})
    	script>
    html>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108

    条件渲染

    一般用来通过逻辑表达式中是否为真来控制容器标签的显示与隐藏

    • v-if="表达式"
    • v-show="表达式"

    二者之间的区别:

    • 前者多适用于切换频率较低的场景,且可以和v-else-ifv-else 连用,但是注意他们彼此之间结构不能被打断,并且隐藏的DOM是直接被移除的
    • 后者多适用于切换频率较高的场景,并且隐藏的DOM元素通过格式隐藏起来了

    列表渲染

    示例

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>基本列表title>
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		
    		
    		<div id="root">
    			
    			<h2>人员列表(遍历数组)h2>
    			<ul>
    				<li v-for="(p,index) of persons" :key="index">
    					{{p.name}}-{{p.age}}
    				li>
                  
                  	<hr>
    				<li v-for="(p,pid) of persons" :key="p.id">
    					{{p.name}}-{{p.age}}-{{pid}}
    				li>
    			ul>
    		div>
    
    		<script type="text/javascript">
    			Vue.config.productionTip = false
    			
    			new Vue({
    				el:'#root',
    				data:{
    					persons:[
    						{id:'001',name:'张三',age:18},
    						{id:'002',name:'李四',age:19},
    						{id:'003',name:'王五',age:20}
    					]
    			})
    		script>
    html>
    
    • 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
    • 42
    • 43
    • 44

    注意:v-for 指令语法的使用

    • v-for="(p,index) of persons"persons 代表要遍历的数组(对象,集合等),p 代表遍历数组中的一个元素,index 代表虚拟DOM对象标识(尽量不要使用)可以选择使用数据中的唯一标识,例如:id…(Vue中key的比较原理)
    • 测试:简单列表过滤和排序

    收集表单数据

    收集表单数据

    将收集的表单数据转换成JSON字符串

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>收集表单数据title>
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		
    		
    		<div id="root">
    			<form @submit.prevent="demo">
                  	
    				账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
    				密码:<input type="password" v-model="userInfo.password"> <br/><br/>
                  	
    				年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
    				性别:
    				男<input type="radio" name="sex" v-model="userInfo.sex" value="male"><input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
    				爱好:
    				学习<input type="checkbox" v-model="userInfo.hobby" value="study">
    				打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
    				吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
    				<br/><br/>
    				所属校区
    				<select v-model="userInfo.city">
    					<option value="">请选择校区option>
    					<option value="beijing">北京option>
    					<option value="shanghai">上海option>
    					<option value="shenzhen">深圳option>
    					<option value="wuhan">武汉option>
    				select>
    				<br/><br/>
    				其他信息:
    				<textarea v-model.lazy="userInfo.other">textarea> <br/><br/>
    				<input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.atguigu.com">《用户协议》a>
    				<button>提交button>
    			form>
    		div>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false
    
    		new Vue({
    			el:'#root',
    			data:{
    				userInfo:{
    					account:'',
    					password:'',
    					age:18,
    					sex:'female',
    					hobby:[],
    					city:'beijing',
    					other:'',
    					agree:''
    				}
    			},
    			methods: {
    				demo(){
    					console.log(JSON.stringify(this.userInfo))
    				}
    			}
    		})
    	script>
    html>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    过滤器

    定义:对显示的数据进行格式化处理

    过滤器定义方式两种:

    • 全局过滤器
    • 局部过滤器
    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>过滤器title>
    		<script type="text/javascript" src="../js/vue.js">script>
    		<script type="text/javascript" src="../js/dayjs.min.js">script>
    	head>
    	<body>
    		{ xxx | 过滤器名}}  或  v-bind:属性 = "xxx | 过滤器名"
    		-->
    		
    		<div id="root">
    			
    			<h3>现在是:{{time | FormatMyTime}}h3>
    			
    			<h3>现在是:{{time | FormatMyTime('YYYY_MM_DD') | mySlice}}h3>
    			<h3 :x="msg | mySlice">尚硅谷h3>
    		div>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false
    		//注册全局过滤器
    		Vue.filter('mySlice',function(value){
    			return value.slice(0,4)
    		})
    		
    		new Vue({
    			el:'#root',
    			data:{
    				time:Date.now(), //获取当前系统时间戳
    				msg:'你好,mtf'
    			},
    			//注册
    			filters:{
    				FormatMyTime(value,str='YYYY年MM月DD日 HH:mm:ss'){
                      	//通过控制台输出:过滤器并没有改变原本的数据, 是产生并返回新的对应的数据
    					console.log('@',value)
    					return dayjs(value).format(str)
    				}
    			}
    		})
    	script>
    html>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    总结:

    • 过滤器也可以接收额外参数、多个过滤器也可以串联
    • 并没有改变原本的数据, 是产生新的对应的数据

    指令

    内置指令

    Vue内部定义的指令,我们拿来即用

    • v-bind :单向绑定解析表达式
    • v-model :双向数据绑定
    • v-for :遍历数组、对象、字符串等
    • v-on :绑定事件监听(简写:@)
    • v-if v-else v-else-if v-show :条件渲染
    • v-text :向所在节点渲染文本内容(原有内容直接覆盖)
    • v-html :向所在节点渲染文本内容(包含html结构)
    • v-once :所在节点在初次动态渲染后就视为静态内容
    • v-pre :跳过所在节点的编译过程(初次编译时不需要Vue渲染数据)

    自定义指令

    生命周期

    在这里插入图片描述

    组件

    Vue使用组件三大步骤

    • 定义组件

      • 使用Vue.extend(options) 创建
      • 注意:
        • 创建的组件中不要写el ,因为所有组件都由Vue实例管理,Vue实例决定使用哪个容器
        • data必须写成函数 —避免组件被复用时,数据存在引用关系。
        • 使用template 配置组件结构
    • 注册组件

      • 局部注册组件,Vue创建实例中注册

        new Vue({
            components:{
            school,//组件名称
            student//组件名称
        	}
        })
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
      • 全局注册组件

        
        
        • 1
        • 2
        • 3
        • 4
    • 使用组件标签

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>几个注意点title>
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		<div id="root">
    			<h1>{{msg}}h1>
    			<school>school>
    		div>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false
    		//const school = Vue.extend(options) 可简写为:const school = options
    		//定义组件(方式一)
    		const s1 = Vue.extend({
              	//可以使用name配置项指定组件在开发者工具中呈现的名字
    			name:'School1',
    			template:`
    				

    学校名称:{{name}}

    学校地址:{{address}}

    `
    , data(){ return { name:'mtf', address:'河南' } } }) //定义组件(方式二) const s2 = ({ name:'School2', template:`

    学校名称:{{name}}

    学校地址:{{address}}

    `
    , data(){ return { name:'mtf', address:'河南' } } }) new Vue({ el:'#root', data:{ msg:'欢迎学习Vue!' }, components:{ school:s2 } })
    script> html>
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    深入理解VueComponent 组件

    根据上述示例s1、s2 组件本质上是由VueComponent 构造函数来创建的,每次常见组件调用Vue.extend 返回的都是一个全新的VueComponent实例对象 (保证即使使用多次相同的组件,数据变换也不相互影响)

    内置关系:VueComponent.prototype.__proto__ === Vue.prototype 让组件实例对象(vc)可以访问到 Vue原型上的属性、方法

    Vue组件化编程

    模块

    • 向外提供特定功能的js程序,一般就是一个js文件
    • 复用js,简化js的编写,提高js运行效率

    组件

    • 用来实现局部或特定功能的代码集合

    模块化

    • 当应用中的 js 都以模块来编写的, 那这个应用就是一个模块化的应用

    组件化

    • 当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用

    refprops

    ref

    <template>
      <div>
        <h1 ref="title" v-text="msg">h1>
        <School ref="sch">School>
        <button @click="showDOM()" ref="btn">点击输出DOM元素button>
      div>
    template>
    
    <script>
    import School from "./components/School";
    import Student from "./components/Student";
    export default {
      name: 'App',
      components: {Student, School},
      data(){
        return{
          msg:"我是傻子!"
        }
      },
      methods:{
        showDOM(){
          console.log(this.$refs)
        }
      }
    }
    script>
    
    • 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

    在这里插入图片描述

    props

    用于父组件给子组件传递数据

    App.vue

    <template>
      <div>
        <Student name="mtf" age="22" sex="">Student>
      div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    School.vue

    <template>
    	<div>
    		<h1>{{msg}}h1>
    		<h2>学生姓名:{{name}}h2>
    		<h2>学生性别:{{sex}}h2>
    		<h2>学生年龄:{{myAge+1}}h2>
    		<button @click="updateAge">尝试修改收到的年龄button>
    	div>
    template>
    
    <script>
    	export default {
    		name:'Student',
    		data() {
    			console.log(this)
    			return {
    				msg:'我是一个aynu的学生',
    				myAge:this.age
    			}
    		},
    		methods: {
    			updateAge(){
    				this.myAge++
    			}
    		},
    		//简单声明接收
    		props:['name','age','sex']
    
    		//接收的同时对数据进行类型限制
    		/* props:{
    			name:String,
    			age:Number,
    			sex:String
    		} */
    
    		//接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
    		// props:{
    		// 	name:{
    		// 		type:String, //name的类型是字符串
    		// 		required:true, //name是必要的
    		// 	},
    		// 	age:{
    		// 		type:Number,
    		// 		default:99 //默认值
    		// 	},
    		// 	sex:{
    		// 		type:String,
    		// 		required:true
    		// 	}
    		// }
    	}
    script>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    混入

    通过使用模块思想定义一个js文件,给Vue或Vue实例添加方法、定义全局指令

    mixin.js

    export const hunhe = {
    	methods: {
    		showName(){
    			alert(this.name)
    		}
    	},
    	mounted() {
    		console.log('你好啊!')
    	},
    }
    export const hunhe2 = {
    	data() {
    		return {
    			x:100,
    			y:200
    		}
    	},
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    School.vue

    <template>
    	<div>
    		<h2 @click="showName">学校名称:{{name}}h2>
    		<h2>学校地址:{{address}}h2>
    	div>
    template>
    
    <script>
    	//引入一个hunhe
    	import {hunhe,hunhe2} from '../mixin'
    
    	export default {
    		name:'School',
    		data() {
    			return {
    				name:'mtf',
    				address:'河南',
    				x:666
    			}
    		},
    		mixins:[hunhe,hunhe2]
    	}
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    插件

    Vue 插件是一个包含 install 方法的对象 ,通过 install 方法给 Vue 或 Vue 实例添加方法, 定义全局指令等

    plugins.js

    export default {
      install(Vue,x,y,z){
        console.log(x,y,z)
        //全局过滤器
        Vue.filter('mySlice',function(value){
          return value.slice(0,4)
        })
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    p70-p79

    组件自定义事件

    组件之间的通信方式,适用于:子组件===》父组件

    案例一

    父组件给子组件传递函数类型的props来实现子组件给父组件传递数据

    App.vue

    <template>
    	<div class="app">
    		
    		<School :getSchoolName="getSchoolName"/>
    	div>
    template>
    
    <script>
    	import School from './components/School'
    
    	export default {
    		name:'App',
    		components:{School},
    		data() {
    			return {
    				msg:'你好啊!'
    			}
    		},
    		methods: {
    			getSchoolName(name){
    				console.log('App收到了学校名:',name)
    			}
    	}
    script>
    
    <style scoped>
    	.app{
    		background-color: gray;
    		padding: 5px;
    	}
    style>
    
    • 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

    School.vue

    <template>
    	<div class="school">
    		<h2>学校名称:{{name}}h2>
    		<h2>学校地址:{{address}}h2>
    		<button @click="sendSchoolName">把学校名给Appbutton>
    	div>
    template>
    
    <script>
    	export default {
    		name:'School',
          	//接收父组件传递过来的函数
    		props:['getSchoolName'],
    		data() {
    			return {
    				name:'aynu',
    				address:'安阳',
    			}
    		},
    		methods: {
    			sendSchoolName(){
                  	//调用父组件传递过来的函数,将子组件数据传递给父组件
    				this.getSchoolName(this.name)
    			}
    		},
    	}
    script>
    
    <style scoped>
    	.school{
    		background-color: skyblue;
    		padding: 5px;
    	}
    style>
    
    • 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

    案例二

    组件自定义事件

    • 通过父组件给子组件绑定一个自定义事件来实现子组件给父组件传递数据
    • 解绑自定义事件
    • 销毁组件实例==解绑自定义事件(但是回调函数正常运行,只不过函数执行之后的数据不再响应到Vue模板中)

    App.vue

    <template>
    	<div class="app">
    		<h1>{{msg}},学生姓名是:{{studentName}}h1>
    		
    		<Student @mtf="getStudentName" @demo="m1"/>
    
    		
    		<Student ref="student" @click.native="show"/>
    	div>
    template>
    
    <script>
    	import Student from './components/Student'
    
    	export default {
    		name:'App',
    		components:{Student},
    		data() {
    			return {
    				msg:'你好啊!',
    				studentName:''
    			}
    		},
    		methods: {
              	//当子组件向父组件传递多个数据时,父组件接收多个数据可以使用es6语法接收
    			getStudentName(name,...params){
    				console.log('App收到了学生名:',name,params)
    				this.studentName = name
    			},
    			m1(){
    				console.log('demo事件被触发了!')
    			},
    			show(){
    				alert(123)
    			}
    		},
    		mounted() {
    			this.$refs.student.$on('atguigu',this.getStudentName) //绑定自定义事件
    			// this.$refs.student.$once('atguigu',this.getStudentName) //绑定自定义事件(一次性)
    		},
    	}
    script>
    
    <style scoped>
    	.app{
    		background-color: gray;
    		padding: 5px;
    	}
    style>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    Student.vue

    <template>
    	<div class="student">
    		<h2>学生姓名:{{name}}h2>
    		<h2>学生性别:{{sex}}h2>
          	<h2>当前求和为:{{number}}h2>
    		<button @click="add">点我number++button>
    		<button @click="sendStudentlName">把学生名给Appbutton>
          	<button @click="unbind">解绑atguigu事件button>
    		<button @click="death">销毁当前Student组件的实例(vc)button>
    	div>
    template>
    
    <script>
    	export default {
    		name:'Student',
    		data() {
    			return {
    				name:'张三',
    				sex:'男',
    				number:0
    			}
    		},
    		methods: {
              add(){
    				console.log('add回调被调用了')
    				this.number++
    			},
    			sendStudentlName(){
    				//触发Student组件实例身上的mtf事件
    				this.$emit('mtf',this.name,666,888,900)
    				// this.$emit('demo')
    				// this.$emit('click')
    			},
    			unbind(){
    				this.$off('atguigu') //解绑一个自定义事件
    				// this.$off(['atguigu','demo']) //解绑多个自定义事件
    				// this.$off() //解绑所有的自定义事件
    			},
    			death(){
    				this.$destroy() //销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效。
    			}
    		},
    	}
    script>
    
    <style lang="less" scoped>
    	.student{
    		background-color: pink;
    		padding: 5px;
    		margin-top: 30px;
    	}
    style>
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    p84-p101

    插槽

    默认插槽

    往子组件插入数据时,子组件只有一个插槽(只有一个 标签),要插入的数据默认插入该位置

    //父组件
    <template>
      <div id="app">
    	<Category>
          
      	Category>
      div>
    template>
    //子组件
    <template>
    	<div>
          
          <solt>solt>
      div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    具名插槽

    //父组件
    <template>
    	<Category>
      		<template slot="header">
    			
    		template>
    		<template slot="footer">
    			
    		template>
      	Category>
    template>
    
    //子组件
    <template>
    	<div>
        	
          	<solt name="header">solt>
          	<solt name="footer">solt>
      	div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    作用域插槽

    适用场景:和默认插槽场景不同,默认插槽要插入的数据在父组件,而作用域插槽适用的场景是父组件要插入的数据需要从带插槽的子组件中获取,这就需要解决子组件的数据怎么传递给父组件!

    //父组件
    <template>
    	<div class="container">
    
    		<Category title="游戏">
    			<template scope="mtf">
    				<ul>
    					<li v-for="(g,index) in mtf.games" :key="index">{{g}}li>
    				ul>
    			template>
    		Category>
    
    		<Category title="游戏">
    			<template slot-scope="{games}">
    				<h4 v-for="(g,index) in games" :key="index">{{g}}h4>
    			template>
    		Category>
    
    	div>
    template>
    
    //子组件
    <template>
    	<div class="category">
    		<h3>{{title}}分类h3>
    		<slot :games="games" msg="hello">我是默认的一些内容slot>
    	div>
    template>
    
    <script>
    	export default {
    		name:'Category',
    		props:['title'],
    		data() {
    			return {
    				games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
    			}
    		},
    	}
    script>
    
    • 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

    p105-p116

    路由

    理解路由

    在了解路由之前,我们先了解一下家里常用的路由器,路由器后面有很多供给我们上网的接口,每天电脑通过链接接口进行上网,因此一个路由器多个接口可以连接多台电脑;这里的一个接口对应一台电脑其实就是一个路由,而路由器负责管理这些路由。其实一个路由就是一组映射关系(key-value)

    基本路由实现

    步骤:

    • 定义路由组件
    • 注册路由
    • 使用路由

    定义路由组件

    Home.vue

    <template>
    	<h2>我是Home的内容h2>
    template>
    
    <script>
    	export default {
    		name:'Home'
    	}
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    About.vue

    <template>
    	<h2>我是About的内容h2>
    template>
    
    <script>
    	export default {
    		name:'About'
    	}
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注册路由

    index.js

    // 该文件专门用于创建整个应用的路由器
    import VueRouter from 'vue-router'
    //引入组件
    import About from '../components/About'
    import Home from '../components/Home'
    
    //创建并暴露一个路由器
    export default new VueRouter({
    	routes:[
    		{
    			path:'/about',
    			component:About
    		},
    		{
    			path:'/home',
    			component:Home
    		}
    	]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    使用路由

    App.vue

    <template>
      <div>
        <div class="row">
          <div class="col-xs-offset-2 col-xs-8">
            <div class="page-header"><h2>Vue Router Demoh2>div>
          div>
        div>
        <div class="row">
          <div class="col-xs-2 col-xs-offset-2">
            <div class="list-group">
    					
              
              
    
    					
    					<router-link class="list-group-item" active-class="active" to="/about">Aboutrouter-link>
              <router-link class="list-group-item" active-class="active" to="/home">Homerouter-link>
            div>
          div>
          <div class="col-xs-6">
            <div class="panel">
              <div class="panel-body">
    						
                <router-view>router-view>
              div>
            div>
          div>
        div>
      div>
    template>
    
    <script>
    	export default {
    		name:'App',
    	}
    script>
    
    • 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

    main.js

    //引入Vue
    import Vue from 'vue'
    //引入App
    import App from './App.vue'
    //引入VueRouter
    import VueRouter from 'vue-router'
    //引入路由器
    import router from './router'
    
    //关闭Vue的生产提示
    Vue.config.productionTip = false
    //应用插件
    Vue.use(VueRouter)
    
    //创建vm
    new Vue({
    	el:'#app',
    	render: h => h(App),
    	router:router
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    注意点

    • 路由组件一般存放在pages 文件夹,一般组件存放在components 文件夹
    • 经过验证,切换走的路由组件是被销毁了,启用时重新挂载
    • 每个组件都有自己的$route 属性,里面存放的是自己的路由信息
    • 整个应用只有一个router,可以通过组件得$router 属性获取

    嵌套路由(多级路由)

    router文件夹下的:index.js

    // 该文件专门用于创建整个应用的路由器
    import VueRouter from 'vue-router'
    //引入组件
    import About from '../pages/About'
    import Home from '../pages/Home'
    import News from '../pages/News'
    import Message from '../pages/Message'
    
    //创建并暴露一个路由器
    export default new VueRouter({
    	routes:[
    		{
    			path:'/about',
    			component:About
    		},
    		{
    			path:'/home',
    			component:Home,
    			children:[
    				{
    					path:'news',
    					component:News,
    				},
    				{
    					path:'message',
    					component:Message,
                      	//name属性,路由命名,通过路由命名可以简化路由跳转了解的编写
                      	children:[
    						{
                              	name:'xiangqing',
    							path:'detail',
    							component:Detail,
    						}
    					]
    				}
    			]
    		}
    	]
    })
    
    • 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

    路由传参

    路由组件route 对应的query 属性

    Message.vue

    <template>
    	<div>
    		<ul>
    			<li v-for="m in messageList" :key="m.id">
    				
    				{m.title}}   -->
                  
              <router-link class="list-group-item" active-class="active" :to="{name:'guanyu'}">Aboutrouter-link>
    
    				
    				<router-link :to="{
                        //二者选一个(路由命名的写法)
                        name:'xiangqing',
    					//path:'/home/message/detail',
    					query:{
    						id:m.id,
    						title:m.title
    					}
    				}">
    					{{m.title}}
    				router-link>
    			
    			li>
    		ul>
    		<hr>
    		<router-view>router-view>
    	div>
    template>
    
    <script>
    	export default {
    		name:'Message',
    		data() {
    			return {
    				messageList:[
    					{id:'001',title:'消息001'},
    					{id:'002',title:'消息002'},
    					{id:'003',title:'消息003'}
    				]
    			}
    		},
    	}
    script>
    
    • 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
    • 42
    • 43

    Detail.vue

    <template>
    	<ul>
    		<li>消息编号:{{$route.query.id}}li>
    		<li>消息标题:{{$route.query.title}}li>
    	ul>
    template>
    
    <script>
    	export default {
    		name:'Detail',
    		mounted() {
    			console.log(this.$route)
    		},
    	}
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    总结:

    • 使用routequery 属性传递参数地址栏形式:xxx/?id=001&title=消息001
    • 定义路由跳转链接有两种形式:
      • to的字符串写法
      • to的对象写法
    • 路由命名
    路由组件route 对应的params 属性

    router文件夹下的:index.js

    // 该文件专门用于创建整个应用的路由器
    import VueRouter from 'vue-router'
    //引入组件
    import About from '../pages/About'
    import Home from '../pages/Home'
    import News from '../pages/News'
    import Message from '../pages/Message'
    import Detail from '../pages/Detail'
    
    //创建并暴露一个路由器
    export default new VueRouter({
    	routes:[
    		{
    			name:'guanyu',
    			path:'/about',
    			component:About
    		},
    		{
    			path:'/home',
    			component:Home,
    			children:[
    				{
    					path:'news',
    					component:News,
    				},
    				{
    					path:'message',
    					component:Message,
    					children:[
    						{
    							name:'xiangqing',
                              	//使用占位符声明接收的params参数
    							path:'detail/:id/:title',
    							component:Detail,
    						}
    					]
    				}
    			]
    		}
    	]
    })
    
    • 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

    Message.vue

    <template>
    	<div>
    		<ul>
    			<li v-for="m in messageList" :key="m.id">
    				
    				{m.title}}   -->
    
    				
    				<router-link :to="{
    					name:'xiangqing',
    					params:{
    						id:m.id,
    						title:m.title
    					}
    				}">
    					{{m.title}}
    				router-link>
    			
    			li>
    		ul>
    		<hr>
    		<router-view>router-view>
    	div>
    template>
    
    <script>
    	export default {
    		name:'Message',
    		data() {
    			return {
    				messageList:[
    					{id:'001',title:'消息001'},
    					{id:'002',title:'消息002'},
    					{id:'003',title:'消息003'}
    				]
    			}
    		},
    	}
    script>
    
    • 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

    Detail.vue

    <template>
    	<ul>
    		<li>消息编号:{{$route.params.id}}li>
    		<li>消息标题:{{$route.params.title}}li>
    	ul>
    template>
    
    <script>
    	export default {
    		name:'Detail',
    		mounted() {
    			// console.log(this.$route)
    		},
    	}
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注意:

    • 如果采用params 属性传递参数,那么跳转路由要是采用to对象写法的话,就只能通过路由命名的name属性值来跳转,不能再通过path的属性值(声明占位符的原因)

    路由参数接收优化

    总结

    Vue模板

    • 只要数据变化,涉及到该数据的Vue模板就要根据变化的数据重新解析模板
    • 因此,页面初始化并不能体会到Vue的特性

    两个重要的小原则:
    1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
    2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,
    这样this的指向才是vm 或 组件实例对象。

  • 相关阅读:
    tcping下载安装步骤,如何ping端口,tcping详解
    (三)构建网络模型
    阿里推出新品牌“瓴羊”,致力成为“数字化领头羊”
    21天学会C++:Day13----动态内存管理
    MAC显示解锁记录(show last times the screen was unlocked in mac os)
    MySQL表的约束
    计算机毕设 大数据电商用户行为分析 -python 大数据
    实用调试技巧
    天宇优配|上架秒光 “3时代”的大额存单受宠
    点云从入门到精通技术详解100篇-低重叠率三维点云配准及点云数据一体化处理系统开发
  • 原文地址:https://blog.csdn.net/qq_48575500/article/details/126506591