超级详细的vue2学习笔记

概要

vue的官方文档

一.vue的核心

1.初始vue

创建一个vue的实例
const x = new vue({});
下面的代码快速了解vue,快速知道vue的工作方式

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    
    <script  src="../js/vue.js">script>
head>
<body>    
    
    <div id="app">
        <h1>hello,{{message}}h1>  
        双括号里可以写javascript的表达式 如a,a+b,demo(a),x===y?'a':'b'等
        不是代码:如if(){}   for(){}
      div>
    <script>
        Vue.config.productionTip = false //以阻止 vue 在启动时生成生产提示

        // 创建一个实例 
        new Vue({
            el:'#app',     //el 用于指定当前Vue位于哪个容器中,值通常为为css选择器==字符串==
            data:{          //data中用于存放数据,数据供el所指定的容器去使用,值占时先写成一个对象。
                message:'你好',
            }
        })
    script>
     
body>
html>

在这里插入图片描述

2.模板语法

超级详细的vue2学习笔记_第1张图片
v-bind之后就当成表达式了
可以简写成:
总结
超级详细的vue2学习笔记_第2张图片

3.数据绑定

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>

    
    <script  src="../js/vue.js">script>
head>
<body>

    

    <div id="root">

      
      单向数据的绑定: <input type="text" v-bind:value="name"><br>
      双向数据的绑定: <input type="text" v-model:value="name"><br>

      
      单向数据的绑定: <input type="text" :value="name"><br>
      双向数据的绑定: <input type="text" v-model="name"><br>
 
      

      
      <h1 v-mode:x="name">你好啊h1>
    div>

    <script>
        Vue.config.productionTip = false //以阻止 vue 在启动时生成生产提示

        new Vue({
            el:"#root",
            data:{
                name:"为将去哪"
            }
        })

    script>
body>
html>

超级详细的vue2学习笔记_第3张图片
总结:
超级详细的vue2学习笔记_第4张图片

4.el和data的两种写法

超级详细的vue2学习笔记_第5张图片

超级详细的vue2学习笔记_第6张图片
在这里插入图片描述

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>

    
    <script  src="../js/vue.js">script>
head>
<body>

    

    <div id="root">
      <h1>你好,{{name}}h1>
    div>

    <script>
        Vue.config.productionTip = false //以阻止 vue 在启动时生成生产提示

        // el的两种写法
        /* const v = new Vue({
            // el:"#root",   第一种写法
            data:{
                name:"鲸落"
            }
        })
        console.log(v);

        setTimeout(()=>{
            v.$mount('#root')  //第二种写法对于有定时器的时候更加的好
        },1000) */


        //data的两种写法
        const x = new Vue({
            // 第一种在上面
            // data的函数式写法(第二种写法)
            el:"#root",
            data:()=>{
                console.log("此处的this",this);
                return{
                    name:'鲸落'
                }
            }
        })
  
    script>
body>
html>

总结
超级详细的vue2学习笔记_第7张图片

5.MVVM模型

超级详细的vue2学习笔记_第8张图片
超级详细的vue2学习笔记_第9张图片
下面的只是为了验证,并没有什么具体的意义
超级详细的vue2学习笔记_第10张图片
比如随便写一个
超级详细的vue2学习笔记_第11张图片

超级详细的vue2学习笔记_第12张图片
超级详细的vue2学习笔记_第13张图片
总结
超级详细的vue2学习笔记_第14张图片

6.数据代理

6.1 回顾Object.defineProperty方法

这个方法vue的底层用的比较多,所以有必要深入的了解它

这个方法是定义属性的意思,这个方法传入三个参数
在没有用到这个方法的时候

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <script>
        let person = {
            name:"金落",
            sex:'男',
            age:12
        }
        console.log(person);        
    script>
body>
html>

超级详细的vue2学习笔记_第15张图片
使用这个方法添加属性

 let person = {
	name:"金落",
	    sex:'男',
	    // age:12
	}
	
	Object.defineProperty(person,'age',{
	    value:12
	})
	console.log(person);  

超级详细的vue2学习笔记_第16张图片
这个时候的通过这个方法添加的属性age是不参加遍历的(也就是不参加枚举)

 let person = {
            name:"金落",
            sex:'男',
            // age:12
        }
Object.defineProperty(person,'age',{
   value:12
})
/* Object.keys()这个方法可以把传入其中的
对象的属性名提取出来组成一个数组 */
console.log(Object.keys(person));

在这里插入图片描述
进一步分析

  let person = {
            name:"金落",
            sex:'男',
        }

        Object.defineProperty(person,'age',{
            value:12,
            enumerable:true   //控制属性是否可以枚举
        })
        /* Object.keys()这个方法可以把参入其中的
        对象的属性名提取出来组成一个数组 */
        console.log(Object.keys(person));

超级详细的vue2学习笔记_第17张图片

let number = 22;
        let person = {
            name:"金落",
            sex:'男',
        }


        Object.defineProperty(person,'age',{

            /* 当有人读取person的age属性时,
            get函数(getter)就会被调用,且返回值就是age的值 */
            get:function(){
                return number
            }
        })
        /* Object.keys()这个方法可以把参入其中的
        对象的属性名提取出来组成一个数组 */
        console.log(person);

超级详细的vue2学习笔记_第18张图片
完整代码

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>回顾Object.defineproperty方法title>
	head>
	<body>
		<script type="text/javascript" >
			let number = 18
			let person = {
				name:'张三',
				sex:'男',
			}

			Object.defineProperty(person,'age',{
				// value:18,
				// enumerable:true, //控制属性是否可以枚举,默认值是false
				// writable:true, //控制属性是否可以被修改,默认值是false
				// configurable:true //控制属性是否可以被删除,默认值是false

				//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
				// get:function()可以简写成get()
				get(){
					console.log('有人读取age属性了')
					return number
				},

				//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
				set(value){
					console.log('有人修改了age属性,且值是',value)
					number = value
				}

			})

			// console.log(Object.keys(person))

			console.log(person)
		script>
	body>
html>
不喜欢就是不喜欢不在乎就是不在乎不明白就是不明白不在乎就是·

6.2 理解数据代理

简单的数据代理的例子

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>何为数据代理title>
	head>
	<body>
		
		<script type="text/javascript" >
			let obj = {x:100}
			let obj2 = {y:200}

			Object.defineProperty(obj2,'x',{
				get(){
					return obj.x
				},
				set(value){
					obj.x = value
				}
			})
		script>
	body>
html>

这个就相当于数据的双向绑定了
超级详细的vue2学习笔记_第19张图片

6.3 vue中的数据代理

代码如下

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue中的数据代理title>

    
    <script  src="../js/vue.js">script>
head>
<body>

    

    <div id="root">
      <h1>学校名称:{{name}}h1>
      <h2>学校地址:{{address}}h2>
    div>

    <script>
        Vue.config.productionTip = false //以阻止 vue 在启动时生成生产提示

        const vm =  new Vue({
            el:"#root",
            data:{
                name:"鲸落",
                address:"武汉"
            }
        })
    script>
body>
html>

超级详细的vue2学习笔记_第20张图片

7.事件处理

7.1 事件的基本使用

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 @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:{
				showInfo1(event){
					// console.log(event.target.innerText)
					// console.log(this) //此处的this是vm
					alert('同学你好!')
				},
				showInfo2(event,number){
					console.log(event,number)
					// console.log(event.target.innerText)
					// console.log(this) //此处的this是vm
					alert('同学你好!!')
				}
			}
		})
	script>
html>

7.2 事件的修饰符

  • prevent阻止事件的默认行为
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>
			
			
			<a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息a>
			
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷'
			},
			methods:{
				showInfo(e){
					alert('同学你好!')
					// console.log(e.target)
				},
			}
		})
	script>
html>

超级详细的vue2学习笔记_第21张图片

  • stop阻止事件冒泡
DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>事件修饰符title>
		
		<style type="text/css">
		 .demo1{
			height: 50px;
			background-color: skyblue;
		  }
		style>
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		<div id="root">
			
			<div class="demo1" @click="showInfo">
				<button @click.stop="showInfo">点我提示信息button>
				
			div>	
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷'
			},
			methods:{
				showInfo(e){
					alert('同学你好!')
					// console.log(e.target)
				},
			}
		})
	script>
html>

超级详细的vue2学习笔记_第22张图片

提示事件是先捕获再冒泡,而事件的触发是在事件冒泡阶段发生的

完整代码

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>事件修饰符title>
		
		<script type="text/javascript" src="../js/vue.js">script>
		<style>
			*{
				margin-top: 20px;
			}
			.demo1{
				height: 50px;
				background-color: skyblue;
			}
			.box1{
				padding: 5px;
				background-color: skyblue;
			}
			.box2{
				padding: 5px;
				background-color: orange;
			}
			.list{
				width: 200px;
				height: 200px;
				background-color: peru;
				overflow: auto;
			}
			li{
				height: 100px;
			}
		style>
	head>
	<body>
		
		
		<div id="root">
			<h2>欢迎来到{{name}}学习h2>
			
			
			<a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息a>

			
			<div class="demo1" @click="showInfo">
				<button @click.stop="showInfo">点我提示信息button>
				
				
				<a href="http://www.atguigu.com" @click.stop.prevent="showInfo">点我提示信息a>
			div>

			
			
			<button @click.once="showInfo">点我提示信息button>

			
			<div class="box1" @click.capture="showMsg(1)">
				div1
				<div class="box2" @click="showMsg(2)">
					div2
				div>
			div>

			
			<div class="demo1" @click.self="showInfo">
				<button @click="showInfo">点我提示信息button>
			div>

			
			<ul @wheel.passive="demo" class="list">
				<li>1li>
				<li>2li>
				<li>3li>
				<li>4li>
			ul>

		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷'
			},
			methods:{
				showInfo(e){
					alert('同学你好!')
					// console.log(e.target)
				},
				showMsg(msg){
					console.log(msg)
				},
				demo(){
					for (let i = 0; i < 100000; i++) {
						console.log('#')
					}
					console.log('累坏了')
				}
			}
		})
	script>
html>

超级详细的vue2学习笔记_第23张图片

7.3 键盘事件

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>
			<input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo">
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		Vue.config.keyCodes.huiche = 13 //定义了一个别名按键

		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷'
			},
			methods: {
				showInfo(e){
					// console.log(e.key,e.keyCode)
					console.log(e.target.value)
				}
			},
		})
	script>
	
html>

8.计算属性

下面是本节要实现的效果,通过不同的方式实现进行比较,最后发现设计计算属性的目的。
超级详细的vue2学习笔记_第24张图片

8.1 姓名案例_插值语法实现

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>{{firstName}}-{{lastName}}span>
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		new Vue({
			el:'#root',
			data:{
				firstName:'张',
				lastName:'三'
			}
		})
	script>
html>

8.2 姓名案例_methods实现

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>姓名案例_methods实现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>
			
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		new Vue({
			el:'#root',
			data:{
				firstName:'张',
				lastName:'三'
			},
			methods: {
				fullName(){
					console.log('@---fullName')
					return this.firstName + '-' + this.lastName
				}
			},
		})
	script>
html>

8.3 姓名案例_计算属性实现

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/>
			测试:<input type="text" v-model="x"> <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:'三',
				x:'你好'
			},
			methods: {
				demo(){
					
				}
			},
			computed:{
				fullName:{
					//get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
					//get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
					get(){
						console.log('get被调用了')
						// console.log(this) //此处的this是vm 是vue帮我们调成这样的
						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>

8.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">
			姓:<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:'三',
			},
			//当确定了只读取,不修改的话就可以写成下面的简写方式
			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
				}
			}
		})
		
	script>
html>

9.监听属性

超级详细的vue2学习笔记_第25张图片

9.1 天气案例

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>
	
		div>
	body>

	<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
				}

			},
		})
	script>
html>

9.2 天气案例_监听属性

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>
		div>
	body>

	<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)
					}
				}
			} */
		})

		vm.$watch('isHot',{
			immediate:true, //初始化时让handler调用一下
			//handler什么时候调用?当isHot发生改变时。
			handler(newValue,oldValue){
				console.log('isHot被修改了',newValue,oldValue)
			}
		})
	script>
html>

9.3 天气案例_深度监视

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.c.d.e}}
		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>

9.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">
			<h2>今天天气很{{info}}h2>
			<button @click="changeWeather">切换天气button>
		div>
	body>

	<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调用一下
					// deep:true,//深度监视
					handler(newValue,oldValue){
						console.log('isHot被修改了',newValue,oldValue)
					}
				}, */
				//简写
				/* isHot(newValue,oldValue){
					console.log('isHot被修改了',newValue,oldValue,this)
				} */
			}
		})
		
		
		
		 
		//正常写法
		/* vm.$watch('isHot',{
			immediate:true, //初始化时让handler调用一下
			deep:true,//深度监视
			handler(newValue,oldValue){
				console.log('isHot被修改了',newValue,oldValue)
			}
		}) */

		//简写
		/* vm.$watch('isHot',(newValue,oldValue)=>{
			console.log('isHot被修改了',newValue,oldValue,this)
		}) */

	script>
html>

9.5 姓名案例_watch实现

	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>

10.绑定样式

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>

运行结果
超级详细的vue2学习笔记_第26张图片

11.条件渲染

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>当前的n值是:{{n}}h2>
			<button @click="n++">点我n+1button>
			
			
			

			
			
			

			
			

			
			<template v-if="n === 1">
				<h2>你好h2>
				<h2>尚硅谷h2>
				<h2>北京h2>
			template>

		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false

		const vm = new Vue({
			el:'#root',
			data:{
				name:'尚硅谷',
				n:0
			}
		})
	script>
html>

超级详细的vue2学习笔记_第27张图片
超级详细的vue2学习笔记_第28张图片

12.列表渲染(重要)

我们本节要实现的主要有下面的这些
超级详细的vue2学习笔记_第29张图片

12.1 基本列表渲染(较简单)

v-for指令

  • 用于展示列表数据
  • 语法:v-for=“(item, index) in xxx” :key=“yyy”
  • 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
    举例的实例代码如下
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>
			ul>

			
			<h2>汽车信息(遍历对象)h2>
			<ul>
				<li v-for="(value,k) of car" :key="k">
					{{k}}-{{value}}
				li>
			ul>

			
			<h2>测试遍历字符串(用得少)h2>
			<ul>
				<li v-for="(char,index) of str" :key="index">
					{{char}}-{{index}}
				li>
			ul>
			
			
			<h2>测试遍历指定次数(用得少)h2>
			<ul>
				<li v-for="(number,index) of 5" :key="index">
					{{index}}-{{number}}
				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}
					],
					car:{
						name:'奥迪A8',
						price:'70万',
						color:'黑色'
					},
					str:'hello'
				}
			})
		script>
html>

运行结果
超级详细的vue2学习笔记_第30张图片

12.2 key的原理(重要)

代码如下


DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用于检测title>

    
    <script  src="../js/vue.js">script>
head>
<body>

    

    <div id="root">
      <ul>
          
          <h2>人员列表h2>
          <button @click.once="add">添加一个老刘button>
          <li v-for="(p,index) of persons" :key="index">
              {{p.name}}-{{p.age}}
              <input type="text">
          li>
          
      ul>
    div>

    <script>
        Vue.config.productionTip = false

        new Vue({
            el:"#root",
            data:{
              persons:[
                {id:'001',name:'张三',age:12},
                {id:'002',name:'李四',age:12},
                {id:'003',name:'王五',age:12}                  
              ]
            },
            methods: {
                add(){
                    const p = {id:'004',name:'老刘',age:40};
                    this.persons.unshift(p);  //往前面添加
                }
            },
        })

    script>
body>
html>

对上面的代码进行标记
超级详细的vue2学习笔记_第31张图片
运行结果
超级详细的vue2学习笔记_第32张图片
当在每一个输入框中输入内容的时候
超级详细的vue2学习笔记_第33张图片
这个时候点击按钮,会看到
超级详细的vue2学习笔记_第34张图片
超级详细的vue2学习笔记_第35张图片
接下来,改一下
超级详细的vue2学习笔记_第36张图片
下面显示正常,没有错位了
超级详细的vue2学习笔记_第37张图片
详细原理如下
使用index作为key
超级详细的vue2学习笔记_第38张图片
超级详细的vue2学习笔记_第39张图片

超级详细的vue2学习笔记_第40张图片

超级详细的vue2学习笔记_第41张图片

=使用id作为key
超级详细的vue2学习笔记_第42张图片
总结
超级详细的vue2学习笔记_第43张图片

12.3 列表的过滤

  1. 使用watch实现
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>列表过滤title>
    

    
    <script  src="../js/vue.js">script>
head>
<body>

    <div id="root">
      <ul>
          <h2>人员列表h2>
          <input type="text" placeholder="请输入名字" v-model="keyWord">
          <li v-for="(p,index) in filpersons" :key="index">
              {{p.name}}-{{p.age}}-{{p.sex}}
          li>
      ul>
    div>

    <script>
        Vue.config.productionTip = false //以阻止 vue 在启动时生成生产提示

        //方式一: 用watch实现
        new Vue({
            el:"#root",
            data:{
              keyWord:"", //刚开始的时候为空
              persons:[
                {id:'001',name:'马冬梅',age:12,sex:'女'},
                {id:'002',name:'周冬雨',age:22,sex:'女'},
                {id:'003',name:'周杰伦',age:34,sex:'男'},
                {id:'004',name:'温兆伦',age:21,sex:'男'}
              ],
              filpersons:[]
            },
            watch:{
                keyWord:{
                    immediate:true, //可以走来就执行一次
                    handler(val){
                        this.filpersons = this.persons.filter((p)=>{
                        return p.name.indexOf(val) !== -1;
                    })
                    }
                }
            }
        })
    script>
body>
html>

代码分析
超级详细的vue2学习笔记_第44张图片
超级详细的vue2学习笔记_第45张图片
知识回顾
filter过滤器
超级详细的vue2学习笔记_第46张图片
indexof数组的一个方法
没有的就返回-1,
注意:空格也是返回-1
超级详细的vue2学习笔记_第47张图片

  1. 使用计算属性实现

这个方法比上面有watch要好一点,简单一点

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>列表过滤title>
    

    
    <script  src="../js/vue.js">script>
head>
<body>

    <div id="root">
      <ul>
          <h2>人员列表h2>
          <input type="text" placeholder="请输入名字" v-model="keyWord">
          <li v-for="(p,index) in filpersons" :key="index">
              {{p.name}}-{{p.age}}-{{p.sex}}
          li>
      ul>
    div>

    <script>
        Vue.config.productionTip = false //以阻止 vue 在启动时生成生产提示

        //方式一: 用watch实现
        new Vue({
            el:"#root",
            data:{
              keyWord:"", //刚开始的时候为空
              persons:[
                {id:'001',name:'马冬梅',age:12,sex:'女'},
                {id:'002',name:'周冬雨',age:22,sex:'女'},
                {id:'003',name:'周杰伦',age:34,sex:'男'},
                {id:'004',name:'温兆伦',age:21,sex:'男'}
              ],
            },
           computed:{   //刚开始的时候就会执行一次 数据改变的时候也会执行
            filpersons(){
                    return this.persons.filter((p)=>{
                        return p.name.indexOf(this.keyWord) !==-1;
                    })
                }
           }
        })
    script>
body>
html>

12.4 列表的排序

首先先回顾一下数组中的sort方法,sort会改变原来的数组
详细教程sort方法文档
举例子

 Vue.config.productionTip = false //以阻止 vue 在启动时生成生产提示

        // 如果数组是数字的话,就需要在方法里面的函数里面传入两个参数
        let  arr = [1,4,3,2];
        // 根据a-b还是b-a确定是降序还是升序 默认是降序
        
        arr.sort(function(a,b){
            return a-b;  //第一参数减去第二参数  升序
        }) 
        console.log(arr);

        arr.sort((a,b)=>{
            return b-a;  //第二个参数减去第一个参数 降序
        })
        console.log(arr);

在这里插入图片描述

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>列表排序title>

    
    <script  src="../js/vue.js">script>
head>
<body>

    

    <div id="root">
      <ul>
          <h2>人员列表h2>
          <input type="text" placeholder="请输入名字" v-model="keyWord">
          <button @click="sortType = 2">年龄升序button>
          <button @click="sortType = 1">年龄降序button>
          <button @click="sortType = 0">原顺序button>


          <li v-for="(p,index) in filpersons" :key="p.id">
              {{p.name}}-{{p.age}}-{{p.sex}}
              <input type="text">
          li>
      ul>
    div>

    <script>
        Vue.config.productionTip = false //以阻止 vue 在启动时生成生产提示

       new Vue({
            el:"#root",
            data:{
              keyWord:"", //刚开始的时候为空
              sortType:0,  //原顺序是0, 1是降序 2是升序
              persons:[
                {id:'001',name:'马冬梅',age:12,sex:'女'},
                {id:'002',name:'周冬雨',age:22,sex:'女'},
                {id:'003',name:'周杰伦',age:34,sex:'男'},
                {id:'004',name:'温兆伦',age:21,sex:'男'}
              ],
            },
            computed:{
                filpersons(){
                    const arr = this.persons.filter((p)=>{
                        return p.name.indexOf(this.keyWord) !==-1;
                    })
                    //判断是否需要排序
                    if(this.sortType){
                        arr.sort((p1,p2)=>{    //这里面的p1,p2是对象
                            return this.sortType ===1? p2.age-p1.age : p1.age-p2.age
                        })
                    }
                    return arr
                }
            }
       })

    script>
body>
html>

运行结果
超级详细的vue2学习笔记_第48张图片

12.5 更新时的一个问题

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>列表排序title>                             
    
    <script  src="../js/vue.js">script>
head>
<body>
  
    <div id="root">
      <ul>
          <h2>人员列表h2>
         <button @click="updataMei">更新马冬梅的信息button>
          <li v-for="(p,index) in persons" :key="p.id">
              {{p.name}}-{{p.age}}-{{p.sex}}
          li>
      ul>
    div>

    <script>
        Vue.config.productionTip = false //以阻止 vue 在启动时生成生产提示

       const vm = new Vue({
            el:"#root",
            data:{
              persons:[
                {id:'001',name:'马冬梅',age:12,sex:'女'},
                {id:'002',name:'周冬雨',age:22,sex:'女'},
                {id:'003',name:'周杰伦',age:34,sex:'男'},
                {id:'004',name:'温兆伦',age:21,sex:'男'}
              ]
            },
            methods: {
                updataMei(){
                    /* this.persons[0].name = '马老师',
                    this.persons[0].age = 50,
                    this.persons[0].sex = '男'  */  //上面的可以成功,但是太麻烦了

                    this.persons[0] ={id:'001',name:'马老师',age:59,sex:'男'}
                }
            },

       })
    
    script>
body>
html>



超级详细的vue2学习笔记_第49张图片
超级详细的vue2学习笔记_第50张图片
当先点开控制台,再点开vue的时候
超级详细的vue2学习笔记_第51张图片
超级详细的vue2学习笔记_第52张图片

12.6 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:'尚硅谷',
				address:'北京',
				student:{
					name:'tom',
					age:{
						rAge:40,
						sAge:29,
					},
					friends:[
						{name:'jerry',age:35}
					]
				}
			}
		})
	script>
html>

12.7 模拟一个数据检测

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Documenttitle>
	head>
	<body>
		<script type="text/javascript" >

			let data = {
				name:'尚硅谷',
				address:'北京',
			}

			//创建一个监视的实例对象,用于监视data中属性的变化
			const obs = new Observer(data)		
			console.log(obs)	

			//准备一个vm实例对象
			let vm = {}
			vm._data = data = obs

			function Observer(obj){
				//汇总对象中所有的属性形成一个数组
				const keys = Object.keys(obj)
				//遍历
				keys.forEach((k)=>{
					Object.defineProperty(this,k,{
						get(){
							return obj[k]
						},
						set(val){
							console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)
							obj[k] = val
						}
					})
				})
			}
		script>
	body>
html>

12.8 Vue.set的使用(后面再回来看)

12.9 Vue检测数据改变的原理_数组

12.10 总结数据检测

13.收集表单数据(比较轻松)

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>

运行结果
超级详细的vue2学习笔记_第53张图片

14.过滤器(不是必须的,先跳过)

15 内置指令

常用的内置属性
超级详细的vue2学习笔记_第54张图片

15.1 v-text指令(不常用)

这个不常用

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>v-text指令title>
		
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		
		
		<div id="root">
			<div>你好,{{name}}div>
			<div v-text="name">div>
			<div v-text="str">div>
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		
		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷',
				str:'

你好啊!

'
} })
script> html>

超级详细的vue2学习笔记_第55张图片

15.2 v-html指令(里面有关cookie的没看)

视频大概26分钟,看了4分钟,到时候需要的时候再看

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>v-html指令title>
		
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		
		
		<div id="root">
			<div>你好,{{name}}div>
			<div v-html="str">div>
			<div v-html="str2">div>
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷',
				str:'

你好啊!

'
, str2:'兄弟我找到你想要的资源了,快来!', } })
script> html>

运行结果
超级详细的vue2学习笔记_第56张图片

15.3 v-cloak指令(目前用不到)

先跳过

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>v-cloak指令title>
		<style>
			[v-cloak]{
				display:none;
			}
		style>
		
	head>
	<body>
		
		
		<div id="root">
			<h2 v-cloak>{{name}}h2>
		div>
		<script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js">script>
	body>
	
	<script type="text/javascript">
		console.log(1)
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		
		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷'
			}
		})
	script>
html>

15.4 v-once指令(这个简单)

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>v-once指令title>
		
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		
		
		<div id="root">
			
			<h2 v-once>初始化的n值是:{{n}}h2>  
			<h2>当前的n值是:{{n}}h2>
			<button @click="n++">点我n+1button>
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		
		new Vue({
			el:'#root',
			data:{
				n:1
			}
		})
	script>
html>

15.5 v-pre指令(简单)

这个就是程序员写的是就是什么,不关vue的事

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>v-pre指令title>
		
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		
		
		<div id="root">
			<h2 v-pre>Vue其实很简单h2>
			<h2 >当前的n值是:{{n}}h2>
			<button @click="n++">点我n+1button>
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		new Vue({
			el:'#root',
			data:{
				n:1
			}
		})
	script>
html>

16. 自定义属性

16.1 自定义指令

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>
			<h2>当前的n值是:<span v-text="n">span> h2>
			
			<h2>放大10倍后的n值是:<span v-big="n">span> h2>
			<button @click="n++">点我n+1button>
			<hr/>
			<input type="text" v-fbind:value="n">
		div>
	body>
	
	<script type="text/javascript">
		Vue.config.productionTip = false

		//定义全局指令
		/* Vue.directive('fbind',{
			//指令与元素成功绑定时(一上来) 
			bind(element,binding){
				element.value = binding.value
			},
			//指令所在元素被插入页面时
			inserted(element,binding){
				element.focus()
			},
			//指令所在的模板被重新解析时
			update(element,binding){
				element.value = binding.value
			}
		}) */

		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷',
				n:1
			},
			directives:{
				//big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
				/* 'big-number'(element,binding){
					// console.log('big')
					element.innerText = binding.value * 10
				}, */
				big(element,binding){  
					console.log('big',this) //注意此处的this是window
					// console.log('big')
					element.innerText = binding.value * 10
				},
				fbind:{
					//指令与元素成功绑定时(一上来)
					bind(element,binding){
						console.log(element,binding); 
						element.value = binding.value
					},
					//指令所在元素被插入页面时
					inserted(element,binding){
						element.focus()
					},
					//指令所在的模板被重新解析时
					update(element,binding){
						element.value = binding.value
					}
				}
			}
		})
		
	script>
html>

16.2 回顾DOM的操作

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Documenttitle>
		<style>
			.demo{
				background-color: orange;
			}
		style>
	head>
	<body>
		<button id="btn">点我创建一个输入框button>
		
		<script type="text/javascript" >
			const btn = document.getElementById('btn')
			btn.onclick = ()=>{
				const input = document.createElement('input')

				input.className = 'demo'
				input.value = 99
				input.onclick = ()=>{alert(1)}
				
				document.body.appendChild(input)

				input.focus()
				// input.parentElement.style.backgroundColor = 'skyblue'
				console.log(input.parentElement)
				
			}
		script>
	body>
html>

17 生命周期(目前先跳过去)

到时候有时间再看

17.1引出生命周期

需求,一开始就让页面的文字得到透明度逐渐发生变化,而不是通过点击或者触发。
使用方法的实现的话
用这个,不要将定时器写再方法中,可能会导致无限的调用,造成不必要的麻烦

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 v-if="a">你好啊h2>
			<h2 :style="{opacity}">欢迎学习Vueh2>
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		
		 new Vue({
			el:'#root',
			data:{
				a:false,
				opacity:1
			},
			methods: {
				
			},
			//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
			mounted(){
				console.log('mounted',this)
				setInterval(() => {
					this.opacity -= 0.01
					if(this.opacity <= 0) this.opacity = 1
				},16)
			},
		})

		//通过外部的定时器实现(不推荐)
		/* setInterval(() => {
			vm.opacity -= 0.01
			if(vm.opacity <= 0) vm.opacity = 1
		},16) */
	script>
html>

在这里插入图片描述

17.2 分析生命周期

生命周期的图如下所示
超级详细的vue2学习笔记_第57张图片

17.3 总结生命周期

二 .Vue组件化编程

18.非单文件组件(不常用,跳过)

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>基本使用title>
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		
		
		<div id="root">
			<hello>hello>
			<hr>
			<h1>{{msg}}h1>
			<hr>
			
			<school>school>
			<hr>
			
			<student>student>
		div>

		<div id="root2">
			<hello>hello>
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false

		//第一步:创建school组件
		const school = Vue.extend({
			template:`
				

学校名称:{{schoolName}}

学校地址:{{address}}

`
, // el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。 data(){ return { schoolName:'尚硅谷', address:'北京昌平' } }, methods: { showName(){ alert(this.schoolName) } }, }) //第一步:创建student组件 const student = Vue.extend({ template:`

学生姓名:{{studentName}}

学生年龄:{{age}}

`
, data(){ return { studentName:'张三', age:18 } } }) //第一步:创建hello组件 const hello = Vue.extend({ template:`

你好啊!{{name}}

`
, data(){ return { name:'Tom' } } }) //第二步:全局注册组件 Vue.component('hello',hello) //创建vm new Vue({ el:'#root', data:{ msg:'你好啊!' }, //第二步:注册组件(局部注册) components:{ school, student } }) new Vue({ el:'#root2', })
script> html>

18.1 基本使用

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 s = Vue.extend({
			name:'atguigu',
			template:`
				

学校名称:{{name}}

学校地址:{{address}}

`
, data(){ return { name:'尚硅谷', address:'北京' } } }) new Vue({ el:'#root', data:{ msg:'欢迎学习Vue!' }, components:{ school:s } })
script> html>

18.2 几个注意点

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>组件的嵌套title>
		
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		
		<div id="root">
			
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		//定义student组件
		const student = Vue.extend({
			name:'student',
			template:`
				

学生姓名:{{name}}

学生年龄:{{age}}

`
, data(){ return { name:'尚硅谷', age:18 } } }) //定义school组件 const school = Vue.extend({ name:'school', template:`

学校名称:{{name}}

学校地址:{{address}}

`
, data(){ return { name:'尚硅谷', address:'北京' } }, //注册组件(局部) components:{ student } }) //定义hello组件 const hello = Vue.extend({ template:`

{{msg}}

`
, data(){ return { msg:'欢迎来到尚硅谷学习!' } } }) //定义app组件 const app = Vue.extend({ template:`
`
, components:{ school, hello } }) //创建vm new Vue({ template:'', el:'#root', //注册组件(局部) components:{app} })
script> html>

18.3 组件的嵌套

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>组件的嵌套title>
		
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		
		<div id="root">
			
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		//定义student组件
		const student = Vue.extend({
			name:'student',
			template:`
				

学生姓名:{{name}}

学生年龄:{{age}}

`
, data(){ return { name:'尚硅谷', age:18 } } }) //定义school组件 const school = Vue.extend({ name:'school', template:`

学校名称:{{name}}

学校地址:{{address}}

`
, data(){ return { name:'尚硅谷', address:'北京' } }, //注册组件(局部) components:{ student } }) //定义hello组件 const hello = Vue.extend({ template:`

{{msg}}

`
, data(){ return { msg:'欢迎来到尚硅谷学习!' } } }) //定义app组件 const app = Vue.extend({ template:`
`
, components:{ school, hello } }) //创建vm new Vue({ template:'', el:'#root', //注册组件(局部) components:{app} })
script> html>

18.4 VueComponent

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>VueComponenttitle>
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		
		
		<div id="root">
			<school>school>
			<hello>hello>
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false
		
		//定义school组件
		const school = Vue.extend({
			name:'school',
			template:`
				

学校名称:{{name}}

学校地址:{{address}}

`
, data(){ return { name:'尚硅谷', address:'北京' } }, methods: { showName(){ console.log('showName',this) } }, }) const test = Vue.extend({ template:`atguigu` }) //定义hello组件 const hello = Vue.extend({ template:`

{{msg}}

`
, data(){ return { msg:'你好啊!' } }, components:{test} }) // console.log('@',school) // console.log('#',hello) //创建vm const vm = new Vue({ el:'#root', components:{school,hello} })
script> html>

18.5 一个重要的内置关系

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>一个重要的内置关系title>
		
		<script type="text/javascript" src="../js/vue.js">script>
	head>
	<body>
		
		
		<div id="root">
			<school>school>
		div>
	body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		Vue.prototype.x = 99

		//定义school组件
		const school = Vue.extend({
			name:'school',
			template:`
				

学校名称:{{name}}

学校地址:{{address}}

`
, data(){ return { name:'尚硅谷', address:'北京' } }, methods: { showX(){ console.log(this.x) } }, }) //创建一个vm const vm = new Vue({ el:'#root', data:{ msg:'你好' }, components:{school} }) //定义一个构造函数 /* function Demo(){ this.a = 1 this.b = 2 } //创建一个Demo的实例对象 const d = new Demo() console.log(Demo.prototype) //显示原型属性 console.log(d.__proto__) //隐式原型属性 console.log(Demo.prototype === d.__proto__) //程序员通过显示原型属性操作原型对象,追加一个x属性,值为99 Demo.prototype.x = 99 console.log('@',d) */
script> html>

19.单文件组件

在这里插入图片描述

一个标准的单文件组件
School.vue文件

<template>
  <div class="demo">
    <h2>学校名称:{{ schoolName }}h2>
    <h2>学校地址:{{ address }}h2>
    <button @click="showName">点我提示学校名button>
  div>
template>

<script>
 export default ({   //为了可以让其它的文件可以引用 一般都喜欢用默认暴露
  name:'School',  //最好和文件名保持一致

  data() {
    return {
      schoolName: "尚硅谷",
      address: "北京昌平",
    };
  },
  methods: {
    showName() {
      alert(this.schoolName);
    },
  },
});
script>


<style>
    .demo{
        background-color: aqua;
    }
style>

index.htm文件

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>联系一下单组件的写法title>
head>
<body>
    
    <div id="root">
    div>
    <script src="../js/vue.js">script>
    <script src="./main.js">script>
body>
html>

main.js文件

import App from './School.vue'

new Vue({
    el:"#root",
    template:`<App>App>`,
    components:{
        App
    }
})

School.vue文件

<template>
  <div class="demo">
    <h2>学校名称:{{ schoolName }}h2>
    <h2>学校地址:{{ address }}h2>
    <button @click="showName">点我提示学校名button>
  div>
template>

<script>
 export default ({   //为了可以让其它的文件可以引用 一般都喜欢用默认暴露
  name:'School',  //最好和文件名保持一致

  data() {
    return {
      schoolName: "尚硅谷",
      address: "北京昌平",
    };
  },
  methods: {
    showName() {
      alert(this.schoolName);
    },
  },
});
script>


<style>
    .demo{
        background-color: aqua;
    }
style>

Student.vue文件

<template>
  <div class="demo">
    <h2>学生姓名:{{ name }}h2>
    <h2>学生年龄:{{ age }}h2>
  div>
template>

<script>
 export default ({
  name:'School',
  data() {
    return {
      name: "鲸落",
      age: 45,
    };
  },
});
script>

三 vue脚手架

创建项目
超级详细的vue2学习笔记_第58张图片

超级详细的vue2学习笔记_第59张图片

20.脚手架文件的分析

脚手架文件结构

├── 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:包版本控制文件

package.json文件
··超级详细的vue2学习笔记_第60张图片

超级详细的vue2学习笔记_第61张图片
超级详细的vue2学习笔记_第62张图片
超级详细的vue2学习笔记_第63张图片
main.js文件

/* 
	该文件是整个项目的入口文件
*/
//引入Vue
import Vue from 'vue'
//引入App组件,它是所有组件的父组件
import App from './App.vue'
//关闭vue的生产提示
Vue.config.productionTip = false

/* 
	关于不同版本的Vue:
	
		1.vue.js与vue.runtime.xxx.js的区别:
				(1).vue.js是完整版的Vue,包含:核心功能+模板解析器。
				(2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。

		2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用
			render函数接收到的createElement函数去指定具体内容。
*/

//创建Vue实例对象---vm
new Vue({
	el:'#app',
	//render函数完成了这个功能:将App组件放入容器中
  render: h => h(App),
	// render:q=> q('h1','你好啊')

	// template:`

你好啊

`,
// components:{App}, })

21 ref属性(ok)

超级详细的vue2学习笔记_第64张图片
超级详细的vue2学习笔记_第65张图片
超级详细的vue2学习笔记_第66张图片
超级详细的vue2学习笔记_第67张图片
运行结果
超级详细的vue2学习笔记_第68张图片
总结:
ref属性

  1. 被用来给元素或子组件注册引用信息(id的替代者)
  2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
  3. 使用方式:
    1. 打标识:

      .....

    2. 获取:this.$refs.xxx

22 props属性(ok)

本节用到的文件如下
简单的父组件给子组件传值的方式
超级详细的vue2学习笔记_第69张图片
本节用到是上面的两个文件
StudentStudent.vue文件

<template>
  <div class="demo">
      <h1>{{msg}}h1>
      <h2>学校的名称:{{name}}h2>
      <h2>学校地址:{{sex}}h2>
      <h2>学生年龄:{{age+22}}h2>
  div>
template>

<script>
export default {
    name:'StudentStudent',
    data() {
        return {
          msg:"我是一个优秀的学生"
        }
    },
     props:["name","sex","age"]
}
script>

<style>
   .demo{
       background-color: aquamarine;
   }
style>

App.vue文件

<template>
<div>
   <StudentStudent name="小白" sex="" age="22"/>
   <StudentStudent name="李百" sex="" :age="55"/>
   
div>
template>



<script>
// 引入school组件
import StudentStudent from './components/StudentStudent'

export default {
    name:'App',
    components:{StudentStudent},
}

script>

<style>

style>


运行结果
超级详细的vue2学习笔记_第70张图片
超级详细的vue2学习笔记_第71张图片
限制类型的方式
超级详细的vue2学习笔记_第72张图片
在这里插入图片描述
更高端的方式
超级详细的vue2学习笔记_第73张图片
总结
props配置项

  1. 功能:让组件接收外部传过来的数据

  2. 传递数据:

  3. 接收数据:

    1. 第一种方式(只接收):props:['name']

    2. 第二种方式(限制类型):props:{name:String}

    3. 第三种方式(限制类型、限制必要性、指定默认值):

      props:{
      	name:{
      	type:String, //类型
      	required:true, //必要性
      	default:'老王' //默认值
      	}
      }
      

    备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
    超级详细的vue2学习笔记_第74张图片
    超级详细的vue2学习笔记_第75张图片
    超级详细的vue2学习笔记_第76张图片
    超级详细的vue2学习笔记_第77张图片

23 mixin混入(合)

为什么要引入混合
如下图代码
超级详细的vue2学习笔记_第78张图片
有重复的部分,看起来很不舒服
所以有必要将它们合在一起不是更好
所以就有了这个概念
超级详细的vue2学习笔记_第79张图片
超级详细的vue2学习笔记_第80张图片
总结:

  1. 功能:可以把多个组件共用的配置提取成一个混入对象

  2. 使用方式:

    第一步定义混合:

    {
        data(){....},
        methods:{....}
        ....
    }
    

    第二步使用混入:

    ​ 全局混入:Vue.mixin(xxx)
    ​ 局部混入:mixins:['xxx']

24 插件(简单的东西)(很重要)

超级详细的vue2学习笔记_第81张图片
超级详细的vue2学习笔记_第82张图片
插件在这里定义
超级详细的vue2学习笔记_第83张图片
引入插件
超级详细的vue2学习笔记_第84张图片
超级详细的vue2学习笔记_第85张图片

25 scoped样式

超级详细的vue2学习笔记_第86张图片
超级详细的vue2学习笔记_第87张图片

26 TodoList案例

本节主要实现的效果如下
超级详细的vue2学习笔记_第88张图片
超级详细的vue2学习笔记_第89张图片

超级详细的vue2学习笔记_第90张图片
总共分成四个vue的组件

静态布局

关键代码

MyFooter.vue
超级详细的vue2学习笔记_第91张图片
MyHeader.vue
超级详细的vue2学习笔记_第92张图片

MyItem.vue
超级详细的vue2学习笔记_第93张图片
MyList.vue
超级详细的vue2学习笔记_第94张图片

完整代码

超级详细的vue2学习笔记_第95张图片

<template>
	<div class="todo-footer">
		<label>
			<input type="checkbox"/>
		label>
		<span>
			<span>span> / 全部
		span>
		<button class="btn btn-danger">清除已完成任务button>
	div>
template>

<script>
	export default {
		name:'MyFooter',
	}
script>

<style scoped>
	/*footer*/
	.todo-footer {
		height: 40px;
		line-height: 40px;
		padding-left: 6px;
		margin-top: 5px;
	}

	.todo-footer label {
		display: inline-block;
		margin-right: 20px;
		cursor: pointer;
	}

	.todo-footer label input {
		position: relative;
		top: -1px;
		vertical-align: middle;
		margin-right: 5px;
	}

	.todo-footer button {
		float: right;
		margin-top: 5px;
	}
style>
<template>
   <div class="todo-header">
   	<input type="text" placeholder="请输入你的任务名称,按回车键确认"/>
   div>
template>

<script>
   export default {
   	name:'MyHeader',
   }
script>

<style scoped>
   /*header*/
   .todo-header input {
   	width: 560px;
   	height: 28px;
   	font-size: 14px;
   	border: 1px solid #ccc;
   	border-radius: 4px;
   	padding: 4px 7px;
   }

   .todo-header input:focus {
   	outline: none;
   	border-color: rgba(82, 168, 236, 0.8);
   	box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
   }
style>

<template>
	<li>
		<label>
			<input type="checkbox"/>
			<span>{{todo.title}}span>
		label>
		<button>删除button>
	li>
template>

<script>
	export default {
		name:'MyItem',
		// 声明接收的todo对象
		props:['todo'],
	}
script>


<style scoped>
	/*item*/
	li {
		list-style: none;
		height: 36px;
		line-height: 36px;
		padding: 0 5px;
		border-bottom: 1px solid #ddd;
	}

	li label {
		float: left;
		cursor: pointer;
	}

	li label li input {
		vertical-align: middle;
		margin-right: 6px;
		position: relative;
		top: -1px;
	}

	li button {
		float: right;
		display: none;
		margin-top: 3px;
	}

	li:before {
		content: initial;
	}

	li:last-child {
		border-bottom: none;
	}

	li:hover{
		background-color: #ddd;
	}
	
	li:hover button{
		display: block;
	}
style>
<template>
	<ul class="todo-main">
		<MyItem v-for="todoObj in todos" :key="todoObj.id" :todo="todoObj"/>
	ul>
template>

<script>
	import MyItem from './MyItem'

	export default {
		name:'MyList',
		components:{MyItem},
		data() {
			return {
				todos:[
					{id:'0001',title:'吃饭',deno:true},
					{id:'0002',title:'喝酒',deno:false},
					{id:'0003',title:'开车',deno:true},
				]
			}
		},
	}
script>

<style scoped>
	/*main*/
	.todo-main {
		margin-left: 0px;
		border: 1px solid #ddd;
		border-radius: 2px;
		padding: 0px;
	}

	.todo-empty {
		height: 40px;
		line-height: 40px;
		border: 1px solid #ddd;
		border-radius: 2px;
		padding-left: 5px;
		margin-top: 10px;
	}
style>
<template>
	<div id="root">
		<div class="todo-container">
			<div class="todo-wrap">
				<MyHeader/>
				<MyList/>
				<MyFooter/>
			div>
		div>
	div>
template>

<script>
	import MyHeader from './components/MyHeader'
	import MyList from './components/MyList'
	import MyFooter from './components/MyFooter.vue'

	export default {
		name:'App',  //自己的名字
		components:{MyHeader,MyList,MyFooter},
	}
script>

<style>
	/*base*/
	body {
		background: #fff;
	}
	.btn {
		display: inline-block;
		padding: 4px 12px;
		margin-bottom: 0;
		font-size: 14px;
		line-height: 20px;
		text-align: center;
		vertical-align: middle;
		cursor: pointer;
		box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
		border-radius: 4px;
	}
	.btn-danger {
		color: #fff;
		background-color: #da4f49;
		border: 1px solid #bd362f;
	}
	.btn-danger:hover {
		color: #fff;
		background-color: #bd362f;
	}
	.btn:focus {
		outline: none;
	}
	.todo-container {
		width: 600px;
		margin: 0 auto;
	}
	.todo-container .todo-wrap {
		padding: 10px;
		border: 1px solid #ddd;
		border-radius: 5px;
	}
style>

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

//创建vm
new Vue({
	el:'#app',
	render: h => h(App)
})

超级详细的vue2学习笔记_第96张图片

项目的过程细节

实现勾选

超级详细的vue2学习笔记_第97张图片
超级详细的vue2学习笔记_第98张图片
动态确定勾选谁
超级详细的vue2学习笔记_第99张图片

添加一个todo

需求:在在输入框中输入内容的时候,按回车就会把内容添加到列表里面。
在这里插入图片描述
第一阶段在输入框中输入内容
超级详细的vue2学习笔记_第100张图片
运行结果
超级详细的vue2学习笔记_第101张图片
拓展

在本节需要使用到id,因此引入了一个库,它可以随机的生成不重复的id
导入它的方式:

超级详细的vue2学习笔记_第102张图片
下载它的方式如下
超级详细的vue2学习笔记_第103张图片

总结:在这里面实现了输入并存放数据的功能,本节主要使用知识点有

  • @keyup.enter="add"通过点击键盘中的每一个键触发,这里使用的是回车键
  • e.target.value获取输入框输入的值
  • 随机生成idnanoid的下载和使用

将添加的东西传给另一个组件

超级详细的vue2学习笔记_第104张图片
本次动了下面的三个文件
Myheader.vue
Mylist.vue
App.vue
App.vue将数据通过props传给Mylist.vue组件,然后App.vue组件通过传递一个函数给Myheader.vue通过参数的方式得到它输入的数据
Mylist.vue
超级详细的vue2学习笔记_第105张图片
App.vue
超级详细的vue2学习笔记_第106张图片
超级详细的vue2学习笔记_第107张图片
Myheader.vue
超级详细的vue2学习笔记_第108张图片
超级详细的vue2学习笔记_第109张图片
上面传递成功了

可以真的添加到列表里面了

MyHeader.vue组件变化的地方
·超级详细的vue2学习笔记_第110张图片
App.vue变化的地方
超级详细的vue2学习笔记_第111张图片
超级详细的vue2学习笔记_第112张图片

勾选列表(引起数据的变化)

超级详细的vue2学习笔记_第113张图片
App.vue
变化的地方
超级详细的vue2学习笔记_第114张图片
MyList.vue变数的地方
超级详细的vue2学习笔记_第115张图片
MyItem.vue组件变化的地方
超级详细的vue2学习笔记_第116张图片
运行结果
没有点击之前的状态
超级详细的vue2学习笔记_第117张图片
点击之后的状态
超级详细的vue2学习笔记_第118张图片

删除按钮的实现

MyItem.vue组件的变化
超级详细的vue2学习笔记_第119张图片
MyList.vue组件的变化
超级详细的vue2学习笔记_第120张图片
App.vue组件的变化
超级详细的vue2学习笔记_第121张图片
超级详细的vue2学习笔记_第122张图片
超级详细的vue2学习笔记_第123张图片
超级详细的vue2学习笔记_第124张图片

底部的统计功能的实现

本节会用到reduce这个方法reduce的回顾
reduce这个方法作用在数组上,数组有几条数据就会执行几次

超级详细的vue2学习笔记_第125张图片
在这里插入图片描述
pre第一次的值为后面给的第二个参数0,第二个参数为第一次的返回值
有于没有写retrun语句,所以后面的两个值都是未定义
当给一个返回值的时候
超级详细的vue2学习笔记_第126张图片
在这里插入图片描述
current为每一个数组的每一个项

超级详细的vue2学习笔记_第127张图片
超级详细的vue2学习笔记_第128张图片
进入到正题
App.vue改变的地方
超级详细的vue2学习笔记_第129张图片
MyFooter.vue改变的地方
超级详细的vue2学习笔记_第130张图片
运行结果
超级详细的vue2学习笔记_第131张图片
超级详细的vue2学习笔记_第132张图片
超级详细的vue2学习笔记_第133张图片

底部交互功能的实现

实现了上面全部勾选上的时候下面的全选按钮就会被勾选上
超级详细的vue2学习笔记_第134张图片
超级详细的vue2学习笔记_第135张图片
勾选下面的按钮,上面的按钮会全部被勾选
超级详细的vue2学习笔记_第136张图片
超级详细的vue2学习笔记_第137张图片
超级详细的vue2学习笔记_第138张图片
底部的全部清除功能
超级详细的vue2学习笔记_第139张图片
超级详细的vue2学习笔记_第140张图片
超级详细的vue2学习笔记_第141张图片

总结TodoList案例

  1. 组件化编码流程:

    ​ (1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。

    ​ (2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:

    ​ 1).一个组件在用:放在组件自身即可。

    ​ 2). 一些组件在用:放在他们共同的父组件上(状态提升)。

    ​ (3).实现交互:从绑定事件开始。

  2. props适用于:

    ​ (1).父组件 ==> 子组件 通信

    ​ (2).子组件 ==> 父组件 通信(要求父先给子一个函数)

  3. 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!

  4. props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。

27.浏览器本地存储(比较轻松)

超级详细的vue2学习笔记_第142张图片
超级详细的vue2学习笔记_第143张图片
超级详细的vue2学习笔记_第144张图片
超级详细的vue2学习笔记_第145张图片

存数据

DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>localStoragetitle>
	head>
	<body>
		<h2>localStorageh2>
		<button onclick="saveData()">点我保存一个数据button>
	body>
	<script type="text/javascript">
	
	    let p = {name:'张三',age:13}
		
		function saveData(){
			localStorage.setItem('msg','hello!!!')
			localStorage.setItem('msg2',666)
			localStorage.setItem('person',JSON.stringify(p))//将一个对象装换成一个字符串并且可以正常的显示
		}
		
	script>
html>


超级详细的vue2学习笔记_第146张图片
读数据
超级详细的vue2学习笔记_第147张图片

超级详细的vue2学习笔记_第148张图片
移除和清空数据
超级详细的vue2学习笔记_第149张图片
将浏览器关闭掉也不会丢失
清空缓存就没有了

session

DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>sessionStoragetitle>
	head>
	<body>
		<h2>sessionStorageh2>
		<button onclick="saveData()">点我保存一个数据button>
		<button onclick="readData()">点我读取一个数据button>
		<button onclick="deleteData()">点我删除一个数据button>
		<button onclick="deleteAllData()">点我清空一个数据button>

		<script type="text/javascript" >
			let p = {name:'张三',age:18}

			function saveData(){
				sessionStorage.setItem('msg','hello!!!')
				sessionStorage.setItem('msg2',666)
				sessionStorage.setItem('person',JSON.stringify(p))
			}
			function readData(){
				console.log(sessionStorage.getItem('msg'))
				console.log(sessionStorage.getItem('msg2'))

				const result = sessionStorage.getItem('person')
				console.log(JSON.parse(result))

				// console.log(sessionStorage.getItem('msg3'))
			}
			function deleteData(){
				sessionStorage.removeItem('msg2')
			}
			function deleteAllData(){
				sessionStorage.clear()
			}

			
		script>
	body>
html>

总结

webStorage

  1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样)

  2. 浏览器端通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制。

  3. 相关API:

    1. xxxxxStorage.setItem('key', 'value');
      该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。

    2. xxxxxStorage.getItem('person');

      ​ 该方法接受一个键名作为参数,返回键名对应的值。

    3. xxxxxStorage.removeItem('key');

      ​ 该方法接受一个键名作为参数,并把该键名从存储中删除。

    4. xxxxxStorage.clear()

      ​ 该方法会清空存储中的所有数据。

  4. 备注:

    1. SessionStorage存储的内容会随着浏览器窗口关闭而消失。
    2. LocalStorage存储的内容,需要手动清除才会消失。
    3. xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到,那么getItem的返回值是null。
    4. JSON.parse(null)的结果依然是null。

28.todoList_本地存储

超级详细的vue2学习笔记_第150张图片
超级详细的vue2学习笔记_第151张图片
刷新浏览器不会丢失数据

29 组件的自定义事件

这个是为了区别内置事件而产生的
本节用到三个文件
School.vue文件

<template>
	<div class="school">
		<h2>学校名称:{{name}}h2>
		<h2>学校地址:{{address}}h2>

	div>
template>

<script>
	export default {
		name:'School',
		data() {
			return {
				name:'尚硅谷',
				address:'北京',
			}
		},
	}
script>

<style scoped>
	.school{
		background-color: skyblue;
		padding: 5px;
	}
style>

Student.vue文件

<template>
	<div class="student">
		<h2>学生姓名:{{name}}h2>
		<h2>学生性别:{{sex}}h2>
	div>
template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男'
			}
		},
	}
script>

<style lang="less" scoped>
	.student{
		background-color: pink;
		padding: 5px;
		margin-top: 30px;
	}
style>

app.vue

<template>
	<div class="app">
		<h1>{{msg}}h1>
		<School/>
		<Student/>
	div>
template>

<script>
	import Student from './components/Student'
	import School from './components/School'

	export default {
		name:'App',
		components:{School,Student},
		data(){
			return{
				msg:"你好啊"
			}
		}
	}
script>

<style scoped>
	.app{
		background-color: gray;
		padding: 5px;
	}
style>

超级详细的vue2学习笔记_第152张图片
在这里插入图片描述
父给子传递函数的方式获取子的数据(这是之前用到过的)为了和下面的形成对比
超级详细的vue2学习笔记_第153张图片
超级详细的vue2学习笔记_第154张图片
在这里插入图片描述
下面通过app.vue和Student.vue文件将下面的组件的自定义事件
超级详细的vue2学习笔记_第155张图片
App.vue文件
超级详细的vue2学习笔记_第156张图片
Student.vue文件
超级详细的vue2学习笔记_第157张图片
在这里插入图片描述
第二种方式,比第一种更加的灵活
超级详细的vue2学习笔记_第158张图片
如果想要传多个值的话
student.vue
超级详细的vue2学习笔记_第159张图片
app.vue

超级详细的vue2学习笔记_第160张图片
超级详细的vue2学习笔记_第161张图片

解绑自定义事件

解绑一个自定义事件
超级详细的vue2学习笔记_第162张图片
销毁多个
超级详细的vue2学习笔记_第163张图片

超级详细的vue2学习笔记_第164张图片

组件自定义事件的总结

超级详细的vue2学习笔记_第165张图片

超级详细的vue2学习笔记_第166张图片
超级详细的vue2学习笔记_第167张图片
组件绑定原生的事件
超级详细的vue2学习笔记_第168张图片
超级详细的vue2学习笔记_第169张图片
会放在最外侧的那一个大的div,所以这就是只要一个根元素的原因之一

总结

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

  3. 绑定自定义事件:

    1. 第一种方式,在父组件中:

    2. 第二种方式,在父组件中:

      <Demo ref="demo"/>
      ......
      mounted(){
         this.$refs.xxx.$on('atguigu',this.test)
      }
      
    3. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

TodoList都改成成自定义事件的方式(子给父传递)

App.vue组件子组件header.vue通过自定义事件的方式拿到子组件的数据
超级详细的vue2学习笔记_第170张图片

超级详细的vue2学习笔记_第171张图片

超级详细的vue2学习笔记_第172张图片
Footer.vue的改变

超级详细的vue2学习笔记_第173张图片

超级详细的vue2学习笔记_第174张图片

全局事件总线(重要)

可以实现任意组件之间的通信
超级详细的vue2学习笔记_第175张图片
兄弟组件之间的通信(传数据)

超级详细的vue2学习笔记_第176张图片
超级详细的vue2学习笔记_第177张图片
超级详细的vue2学习笔记_第178张图片
总结:
全局事件总线(GlobalEventBus)

  1. 一种组件间通信的方式,适用于任意组件间通信。

  2. 安装全局事件总线:

    new Vue({
    	......
    	beforeCreate() {
    		Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
    	},
        ......
    }) 
    
  3. 使用事件总线:

    1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.$bus.$on('xxxx',this.demo)
      }
      
    2. 提供数据:this.$bus.$emit('xxxx',数据)

TodoList案例_事件总线

本节改的是App.vueMyItemvue通信的情况
下面两张都是App.vue
超级详细的vue2学习笔记_第179张图片
超级详细的vue2学习笔记_第180张图片
MyList.vue文件
超级详细的vue2学习笔记_第181张图片
在这里插入图片描述

消息订阅与发布_pubsub(另外一种通信的方式)(这个在vue里面不常用)

本节需要用到的库
pubsub.js他是subscript和publish的简写(在任何一个框架里面都可以实现消息的发布和订阅
)
先安装这个库
超级详细的vue2学习笔记_第182张图片
在这里插入图片描述
本节可以通过消息订阅的方式实现两个组件的通信
student.vue

超级详细的vue2学习笔记_第183张图片
超级详细的vue2学习笔记_第184张图片
超级详细的vue2学习笔记_第185张图片
用完了就要解绑
总结

== 消息订阅与发布(pubsub)==

  1. 一种组件间通信的方式,适用于任意组件间通信。

  2. 使用步骤:

    1. 安装pubsub:npm i pubsub-js

    2. 引入: import pubsub from 'pubsub-js'

    3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
      }
      
    4. 提供数据:pubsub.publish('xxx',数据)

    5. 最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)去取消订阅。

动画

<template>
    <div>
        <button @click="isShow =!isShow">显示/隐藏button>
        <transition>
            <h1 v-show="isShow">你好啊!h1>
        transition>
    div>
template>

<script>
export default {
    data(){
        return {
            isShow:true
        }
    },    
}
script>

<style>
h1{
    background-color: orange;
}
.v-enter-active{
    animation: atguigu 1s;
}
.v-leave-active{
    animation: atguigu 1s reverse;
}
@keyframes atguigu{
    from{
        transform: translateX(-100%);
    },
    to{
        transform: translateX(0px);
    }
}
style>

可以让他自己做动画
在这里插入图片描述

超级详细的vue2学习笔记_第186张图片

过渡效果
<template>
    <div>
        <button @click="isShow = !isShow">显示/隐藏button>
        <transition name="hello" appear>
            <h1 v-show="isShow">你好啊!h1>
        transition>
        
    div>
template>


<script>
export default {
    name:'Test2',
    data() {
        return {
            isShow: true,
        };
    },
};
script>


<style>
h1 {
    background-color: orange;
    transition: 0.5s linear;
}
/* 进入的起点 */
.hello-enter{
    transform: translateX(-100%);
}
/* 进入的终点 */
.hello-enter-to {
    transform: translateX(0);
}
/* 离开的起点 */
.hello-leave{
    transform: translateX(0);
}
/* 离开的终点 */
.hello-leave-to{
    transform: translateX(-100%);
}
 
style>


剩下的需要的时候再说(以后用到的时候再回来)

四 vue中的ajax

30 .配置代理_方式一

超级详细的vue2学习笔记_第187张图片

超级详细的vue2学习笔记_第188张图片
超级详细的vue2学习笔记_第189张图片
开启一个服务器
超级详细的vue2学习笔记_第190张图片
超级详细的vue2学习笔记_第191张图片
超级详细的vue2学习笔记_第192张图片

超级详细的vue2学习笔记_第193张图片

超级详细的vue2学习笔记_第194张图片
超级详细的vue2学习笔记_第195张图片
超级详细的vue2学习笔记_第196张图片
服务器收到了请求
超级详细的vue2学习笔记_第197张图片

不过这种方式的一次只能向一个端口请求数据

超级详细的vue2学习笔记_第198张图片
超级详细的vue2学习笔记_第199张图片

超级详细的vue2学习笔记_第200张图片
这种方式有一种小小的不完美

32 置代理_方式二

超级详细的vue2学习笔记_第201张图片
超级详细的vue2学习笔记_第202张图片

超级详细的vue2学习笔记_第203张图片
总结

vue脚手架配置代理

方法一

​ 在vue.config.js中添加如下配置:

devServer:{
  proxy:"http://localhost:5000"
}

说明:

  1. 优点:配置简单,请求资源时直接发给前端(8080)即可。
  2. 缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
  3. 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)

方法二

​ 编写vue.config.js配置具体代理规则:

module.exports = {
	devServer: {
      proxy: {
      '/api1': {// 匹配所有以 '/api1'开头的请求路径
        target: 'http://localhost:5000',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {'^/api1': ''}
      },
      '/api2': {// 匹配所有以 '/api2'开头的请求路径
        target: 'http://localhost:5001',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {'^/api2': ''}
      }
    }
  }
}
/*
   changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
   changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
   changeOrigin默认值为true
*/

说明:

  1. 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
  2. 缺点:配置略微繁琐,请求资源时必须加前缀。

33 github案例_静态组件

github用户搜索案例

静态效果

要实现的效果如下
超级详细的vue2学习笔记_第204张图片
目录结构
超级详细的vue2学习笔记_第205张图片
bootstrap.css文件的地址为:地址
它的引入地方
超级详细的vue2学习笔记_第206张图片
上面的第三方的样式库是控制Search.vue这个组件的
List.vue

<template>
    <div class="row">
        <div class="card">
            <a href="https://github.com/xxxxxx" target="_blank">
                <img
                    src="https://cn.vuejs.org/images/logo.svg"
                    style="width: 100px"
                />
            a>
            <p class="card-text">xxxxxxp>
        div>
        <div class="card">
            <a href="https://github.com/xxxxxx" target="_blank">
                <img
                    src="https://cn.vuejs.org/images/logo.svg"
                    style="width: 100px"
                />
            a>
            <p class="card-text">xxxxxxp>
        div>
        <div class="card">
            <a href="https://github.com/xxxxxx" target="_blank">
                <img
                    src="https://cn.vuejs.org/images/logo.svg"
                    style="width: 100px"
                />
            a>
            <p class="card-text">xxxxxxp>
        div>
        <div class="card">
            <a href="https://github.com/xxxxxx" target="_blank">
                <img
                    src="https://cn.vuejs.org/images/logo.svg"
                    style="width: 100px"
                />
            a>
            <p class="card-text">xxxxxxp>
        div>
        <div class="card">
            <a href="https://github.com/xxxxxx" target="_blank">
                <img
                    src="https://cn.vuejs.org/images/logo.svg"
                    style="width: 100px"
                />
            a>
            <p class="card-text">xxxxxxp>
        div>
    div>
template>

<script>
export default {
    name: "List",
};
script>

<style scoped>
.album {
    min-height: 50rem; /* Can be removed; just added for demo purposes */
    padding-top: 3rem;
    padding-bottom: 3rem;
    background-color: #f7f7f7;
}

.card {
    float: left;
    width: 33.333%;
    padding: 0.75rem;
    margin-bottom: 2rem;
    border: 1px solid #efefef;
    text-align: center;
}

.card > img {
    margin-bottom: 0.75rem;
    border-radius: 100px;
}

.card-text {
    font-size: 85%;
}
style>

Search.vue

<template>
    <section class="jumbotron">
        <h3 class="jumbotron-heading">Search Github Usersh3>
        <div>
            <input
                type="text"
                placeholder="enter the name you search"
            /> <button>Searchbutton>
        div>
    section>
template>

<script>
export default {
    name: "Search",
};
script>


App.vue

<template>
    <div class="container">
        <Search />
        <List />
    div>
template>

<script>
import Search from "./components/Search.vue";
import List from "./components/List.vue";

export default {
    name: "App",
    components: { Search, List },
};
script>

<style>
style>

静态效果(这个时候还没有绑定数据)
超级详细的vue2学习笔记_第207张图片

超级详细的vue2学习笔记_第208张图片

添加数据之后

https://api.github.com/search/users?q=xxx这个是github官方免费提供的接口
本节在上节的基础上只变了下面的两个文件

在这里插入图片描述
List.vue文件

<template>
    <div class="row">
        <div class="card" v-for="user in users" :key="user.login">
            <a :href="user.html_url" target="_blank">
                <img :src="user.avatar_url" style="width:100px"/>
            a> 
            <p class="card-text">{{user.login}}p>
        div>   
    div>
template>

<script>
export default {
    name: "List",
    data() {
        return {
            users:[]
        }
    },
    mounted(){
        this.$bus.$on('data1',(users)=>{
            this.users = users;
        })
    },
    beforeDestroy(){
        this.$bus.$off('data1');
    }
};
script>

<style scoped>
.album {
    min-height: 50rem; /* Can be removed; just added for demo purposes */
    padding-top: 3rem;
    padding-bottom: 3rem;
    background-color: #f7f7f7;
}

.card {
    float: left;
    width: 33.333%;
    padding: 0.75rem;
    margin-bottom: 2rem;
    border: 1px solid #efefef;
    text-align: center;
}

.card > img {
    margin-bottom: 0.75rem;
    border-radius: 100px;
}

.card-text {
    font-size: 85%;
}
style>

sreach.vue文件

<template>
    <section class="jumbotron">
        <h3 class="jumbotron-heading">Search Github Usersh3>
        <div>
            <input
                type="text"
                placeholder="enter the name you search" v-model="keyWord"/> 
                <button @click="searchUsers">Searchbutton>
        div>
    section>
template>

<script>

// 导入axios,之前已经下过了
import axios from 'axios'
export default {
    name: "Search",
    data() {
        return {
            keyWord:''
        }
    },
    methods:{
        // 通过点击按钮向github发送请求
        searchUsers(){
            // https://api.github.com/search/users?q=xxx github免费提供的接口
            axios.get(`https://api.github.com/search/users?q=${this.kayWord}`).then(
                response=>{
                    // console.log("请求成功了",response.data);
                    console.log(response.data.items);
                    this.$bus.$emit("data1",response.data.items); //发送数据

                },
                error=>{
                    console.log("失败",error.message);
                }
            )
        }
    }
};
script>


超级详细的vue2学习笔记_第209张图片
这里面不存在跨域问题
github的后端已经在
运行结果
超级详细的vue2学习笔记_第210张图片

超级详细的vue2学习笔记_第211张图片

完善案例

代码下多写几遍之后再写过来

33.vue-resource(这个插件现在用到比较少)(了解就可)

它在1.0的时候用的比较多
常用的方式
超级详细的vue2学习笔记_第212张图片
vue-resource是对于xhr的封装
安装
超级详细的vue2学习笔记_第213张图片
超级详细的vue2学习笔记_第214张图片
超级详细的vue2学习笔记_第215张图片

34. slot 插槽

34.1默认插槽

超级详细的vue2学习笔记_第216张图片
用到了上面的两个文件夹
App.vue的代码
Appv.ue

<template>
    <div class="container">
        <Category>
            <img src="../public/1.jpg" alt="" />
        Category>

        <Category>
            <ul>
                <li v-for="(g, index) in games" :key="index">{{g}}li>
            ul>
        Category>

        <Category>
            <video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">video>
        Category>
    div>
template>

<script>
import Category from "./components/Category";

export default {
    name: "App",
    components: { Category },
    data() {
        return {
            foods: ["火锅", "烧烤", "小龙虾", "牛排"],
            games: ["红色警戒", "穿越火线", "劲舞团", "超级玛丽"],
            films: [
                "《教父》",
                "《拆弹专家》",
                "《你好,李焕英》",
                "《尚硅谷》",
            ],
        };
    },
};
script>

<style scope> 
.container {
    display: flex;
    justify-content: space-around;
}
img {
    width: 100%;
    height: 120px;
}
video{
    width: 100%;
}
style>

category.vue

<template>
  <div class="category">
      <h3>vvvvh3>
      
      <slot>我是一些默认值,当使用者没有传递具体结构时,我会出现slot>
  div>
template>

<script>
export default {
    name:'Catsgory'
}
script>

<style>
.category{
    width   : 200px;
    height: 200px;
    background-color: skyblue;
}
h3{
    text-align: center;
    background-color: orange;
}
style>

运行结果
超级详细的vue2学习笔记_第217张图片

注意
超级详细的vue2学习笔记_第218张图片
超级详细的vue2学习笔记_第219张图片

34.2 具名插槽

本节要实现的效果如下
在这里插入图片描述
超级详细的vue2学习笔记_第220张图片
App.vue

<template>
    <div class="container">
        <Category title="美食">
            <img slot="center" src="../public/1.jpg" alt="" />
            <a class="foot" slot="footer" href="http://www.baidu.com"
                >更多美食a
            >
        Category>

        <Category title="游戏">
            <ul slot="center">
                <li v-for="(g, index) in games" :key="index">{{ g }}li>
            ul>
            <div slot="footer" class="foot">
                <a href="http://www.baidu.com">单机游戏a>
                <a href="http://www.baidu.com">网络游戏a>
            div>
        Category>

        <Category title="电影">
            <video
                controls
                src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
                slot="center"
            >video>
            <template slot="footer">
                <div  class="foot">
                    <a href="http://www.baidu.com">经典a>
                    <a href="http://www.baidu.com">热门a>
                    <a href="http://www.baidu.com">推荐a>
                div>
                <h4 slot="footer">欢迎前来观看h4>
            template>
        Category>
    div>
template>

<script>
import Category from "./components/Category";

export default {
    name: "App",
    components: { Category },
    data() {
        return {
            foods: ["火锅", "烧烤", "小龙虾", "牛排"],
            games: ["红色警戒", "穿越火线", "劲舞团", "超级玛丽"],
            films: [
                "《教父》",
                "《拆弹专家》",
                "《你好,李焕英》",
                "《尚硅谷》",
            ],
        };
    },
};
script>

<style scope>
.container,.foot{
    display: flex;
    justify-content: space-around;
}
img {
    width: 100%;
    height: 120px;
}
video {
    width: 100%;
}
h4 {
    text-align: center;
}
style>

category.vue

<template>
  <div class="category">
      <h3>{{title}}分类h3>
      
      <slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现slot>
       <slot name="footer">我是一些默认值,当使用者没有传递具体结构时,我会出现slot>
  div>
template>

<script>
export default {
    name:'Category',
    props:['title']
}
script>

<style>
.category{
    width   : 200px;
    height: 250px;
    background-color: skyblue;
}
h3{
    text-align: center;
    background-color: orange;
}
style>

运行结果
超级详细的vue2学习笔记_第221张图片
代码说明
超级详细的vue2学习笔记_第222张图片
超级详细的vue2学习笔记_第223张图片

34.3 作用域插槽(不是很好理解)

分析
超级详细的vue2学习笔记_第224张图片
超级详细的vue2学习笔记_第225张图片
本节用到的两个文件
在这里插入图片描述
category.vue

<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>

<style>
.category {
    width: 200px;
    height: 250px;
    background-color: skyblue;
}
h3 {
    text-align: center;
    background-color: orange;
}
style>

App.vue

<template>
    <div class="container">
        <Category title="游戏">
            <template slot-scope="weijiang">
                <ul>
                    <li v-for="(g, index) in weijiang.games" :key="index">{{ g }}li>
                ul>
            template>
        Category>

        <Category title="游戏">
            <template slot-scope="weijiang">
                <ol>
                    <li style="color:red" v-for="(g, index) in weijiang.games" :key="index">{{ g }}li>
                ol>
                <h4>{{weijiang.msg}}h4>
            template>
        Category>

        <Category title="游戏">
            <template slot-scope="{games}">
                <h4 v-for="(g, index) in games" :key="index">{{ g }}h4>
            template>
        Category>
    div>
template>

<script>
import Category from "./components/Category";

export default {
    name: "App",
    components: { Category },
};
script>

<style scope>
.container,
.foot {
    display: flex;
    justify-content: space-around;
}
img {
    width: 100%;
    height: 120px;
}
video {
    width: 100%;
}
h4 {
    text-align: center;
}
style>

运行结果
超级详细的vue2学习笔记_第226张图片
代码解释
超级详细的vue2学习笔记_第227张图片
超级详细的vue2学习笔记_第228张图片

33.4 总结

  1. 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件

  2. 分类:默认插槽、具名插槽、作用域插槽

  3. 使用方式:

    1. 默认插槽:

      父组件中:
              <Category>
                 <div>html结构1div>
              Category>
      子组件中:
              <template>
                  <div>
                     
                     <slot>插槽默认内容...slot>
                  div>
              template>
      
    2. 具名插槽:

      父组件中:
              <Category>
                  <template slot="center">
                    <div>html结构1div>
                  template>
      
                  <template v-slot:footer>
                     <div>html结构2div>
                  template>
              Category>
      子组件中:
              <template>
                  <div>
                     
                     <slot name="center">插槽默认内容...slot>
                     <slot name="footer">插槽默认内容...slot>
                  div>
              template>
      
    3. 作用域插槽:

      1. 理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)

      2. 具体编码:

        父组件中:
        		<Category>
        			<template scope="scopeData">
        				
        				<ul>
        					<li v-for="g in scopeData.games" :key="g">{{g}}li>
        				ul>
        			template>
        		Category>
        
        		<Category>
        			<template slot-scope="scopeData">
        				
        				<h4 v-for="g in scopeData.games" :key="g">{{g}}h4>
        			template>
        		Category>
        子组件中:
                <template>
                    <div>
                        <slot :games="games">slot>
                    div>
                template>
        		
                <script>
                    export default {
                        name:'Category',
                        props:['title'],
                        //数据在子组件自身
                        data() {
                            return {
                                games:['红色警戒','穿越火线','劲舞团','超级玛丽']
                            }
                        },
                    }
                script>
        

你可能感兴趣的:(#,vue,前端,vue.js,javascript)