Vue基础(2)

目录

深度监视

简写形式

绑定样式

条件渲染

基本列表:

列表过滤

列表排序:

Vue.set使用

收集表单数据

过滤器

内置指令

v-text

v-html

v-cloak

v-once

v-pre

自定义指令:

组件

非单文件组件

组件的嵌套

VueComponents


 

深度监视

在vue中可以配置watch来开启监视,它可以得到数据修改前的值和数据修改后的值,但默认不监视对象内部值的改变。

深度监视:

​            (1).Vue中的watch默认不监测对象内部值的改变(一层)。

​            (2).配置deep:true可以监测对象内部值改变(多层)。

​        备注:

​            (1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!

​            (2).使用watch时根据数据的具体结构,决定是否采用深度监视。

具体写法

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改变了')
					}
				}
			}
<!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+1</button>
			<h3>b的值是:{{numbers.b}}</h3>
			<button @click="numbers.b++">点我让b+1</button>
			<button @click="numbers = {a:666,b:888}">彻底替换掉numbers</button>
			<h3> e的值是{{numbers.c.d.e}}</h3>
			<button @click='changeE'>点我改变e</button>
		
		</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
				},
				changeE(){
                   this.numbers.c.d.e=120;
				}
			},
			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>

简写形式

如果不需要配置immediate和deep配置项是可以使用简写形式

isHot:{
					// immediate:true, //初始化时让handler调用
					handler(newValue,oldValue){
						console.log('isHot被修改了',newValue,oldValue)
					}
				}, 
				//简写
                 isHot(newValue,oldValue){
						console.log('isHot被修改了',newValue,oldValue)
				} 

另一种配置监视的写法

vm.$watch('监视属性',{
					 immediate:true, //初始化时让handler调用一下
					deep:true,
					handler(newValue,oldValue){
						console.log('isHot被修改了',newValue,oldValue)
					})

简写

vm.$watch('isHot',function(newValue,oldValue){
})

注:不要写箭头函数

当然也可以在methods里面配置函数,然后在监视里面handler:'函数名'就可以调用那个函数

绑定样式

 

<!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>Document</title>
    <script src="../js/vue.js"></script>
    <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;
			}

			.zf1{
				background-color: yellowgreen;
			}
			.zf2{
				font-size: 30px;
				text-shadow:2px 2px 10px red;
			}
			.zf3{
				border-radius: 20px;
			}
    </style>
</head>
<body>
    <!-- 
			绑定样式:
					1. class样式
								写法:class="xxx" xxx可以是字符串、对象、数组。
										字符串写法适用于:类名不确定,要动态获取。
										对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
										数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
					2. style样式
								:style="{fontSize: xxx}"其中xxx是动态值。
								:style="[a,b]"其中a、b是样式对象。
		-->
    <div id="root">
        	<!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
        <div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br/><br/>
        <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
			<div class="basic" :class="classArr">{{name}}</div> <br/><br/>

        <div class="basic" :class="classObj">{{name}}</div> <br/><br/>
	   <!-- 绑定style样式--对象写法 -->
       <div class="basic" :style="styleObj">{{name}}</div> <br/><br/>
        <!-- 绑定style样式--数组写法 -->
       <div class="basic" :style="styleArr">{{name}}</div>
    </div>
    
</body>

<script>
    Vue.config.productionTip=false;
    new Vue({
        el:'#root',
        data:{
            name:'蛰伏',
            mood:'normal',
            classArr:['zf1','zf2','zf3'],
            classObj:{
                zf1:true,
                zf2:false
            },
				styleObj:{
					fontSize: '40px',
					color:'red',
				},
				styleObj2:{
					backgroundColor:'orange'
				},
				styleArr:[
					{
						fontSize: '40px',
						color:'blue',
					},
					{
						backgroundColor:'gray'
					}
				]
        },
        methods:{
          changeMood(){
                const x=['happy','sad','normal'];
				console.log(this)
               this.mood=x[Math.floor(Math.random()*3)];
          }
        }
    })
</script>
</html>

条件渲染

条件渲染:

1.v-if

写法:

(1).v-if="表达式"

(2).v-else-if="表达式"

(3).v-else="表达式"

适用于:切换频率较低的场景。

特点:不展示的DOM元素直接被移除。

注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。

2.v-show

写法:v-show="表达式"

适用于:切换频率较高的场景。

特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。

<!-- 使用v-show做条件渲染 -->
			<!-- <h2 v-show="false">欢迎来到{{name}}</h2> -->
			<!-- <h2 v-show="1 === 1">欢迎来到{{name}}</h2> -->

			<!-- 使用v-if做条件渲染 -->
			<!-- <h2 v-if="false">欢迎来到{{name}}</h2> -->
			<!-- <h2 v-if="1 === 1">欢迎来到{{name}}</h2> -->

			<!-- v-else和v-else-if -->
			<!-- <div v-if="n === 1">Angular</div>
			<div v-else-if="n === 2">React</div>
			<div v-else-if="n === 3">Vue</div>
			<div v-else>哈哈</div> -->

			<!-- v-if与template的配合使用 -->
			<template v-if="n === 1">
				<h2>你好</h2>
				<h2>尚硅谷</h2>
				<h2>北京</h2>
			</template>
<!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>Document</title>
    <script src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
    <h2  v-show='false'>欢迎你{{name}}</h2>
    <h2  v-show='1===1'>欢迎你{{name}}</h2>
    <h2  v-show='a'>欢迎你{{name}}</h2>

    <h2  v-if='false'>欢迎你{{name}}</h2>

    </div>
</body>

<script>
    Vue.config.productionTip=false;
   const vm= new Vue({
        el:'#root',
        data:{
              name:'蛰伏',
              a:false
        }
    })
</script>
</html>

 

基本列表:

v-for指令:

1.用于展示列表数据

2.语法:v-for="(item, index) in xxx" :key="yyy"

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>Document</title>
    <script src="../js/vue.js"></script>
</head>
<body>

    	<!-- 
				v-for指令:
						1.用于展示列表数据
						2.语法:v-for="(item, index) in xxx" :key="yyy"
						3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
		-->
    <div id="root">
        <h2>人员列表</h2>
    <ul>
    <!--  <li  v-for="p in persons"  :key="p.id">
         {{p.name}}-{{p.age}}
     </li> -->
     <li  v-for="(p,index) in persons"  :key="index">
         {{p.name}}-{{p.age}}
     </li>
   </ul>
   <h2>遍历汽车</h2>
   <ul>
       <li  v-for="(value,k) in car" :key="k">
          {{k}} -{{value}}
       </li>
   </ul>

   <h2>遍历字符串</h2>
   <ul>
       <li  v-for="(char,index) in str" :key="index">
          {{char}} -{{index}}
       </li>
   </ul>


   <h2>遍历制定次数</h2>
   <ul>
       <li  v-for="(number,index) in 5 " :key="index">
          {{index}} -{{number}}
       </li>
   </ul>

    </div>
</body>

<script>
    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:'奔驰',
                price:'600000',
                color:'黑色'
            },
            str:'hello'
        }
    })
</script>
</html>

key的原理

面试题:react、vue中的key有什么作用?(key的内部原理)

1. 虚拟DOM中key的作用:

key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,

随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:

2.对比规则:

(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:

①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!

②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。

(2).旧虚拟DOM中未找到与新虚拟DOM相同的key

创建新的真实DOM,随后渲染到到页面。

3. 用index作为key可能会引发的问题:

1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:

会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。

2. 如果结构中还包含输入类的DOM:

会产生错误DOM更新 ==> 界面有问题。

4. 开发中如何选择key?:

1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。

2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,

使用index作为key是没有问题的。

key的作用是给节点进行标识,在进行虚拟DOM对比算法是key是参照的关键

 对比初始虚拟DOM和新虚拟DOM,如果key相同,数据不同,数据不同就替换,但是如果有一样的虚拟DOM比如input,是相同的,就把原来解析过得拿过来使用

 如果不写key,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>Document</title>
    <script src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>人员列表</h2>
        <input type="text" placeholder="请搜索名字" v-model="keyword">
        <ul>
            <li v-for="(p,index) in filPersons" :key="index">
                {{p.name}}-{{p.age}}-{{p.sex}}
            </li>
        </ul>

    </div>
</body>

<script>
    Vue.config.productionTip=false;
    new Vue({
        el:'#root',
        data:{
            keyword:'',
            persons:[
                {id:'001',name:'马冬梅',age:'19',sex:'女'},
                {id:'002',name:'周冬雨',age:'20',sex:'女'},
                {id:'003',name:'周杰伦',age:'21',sex:'男'},
                {id:'003',name:'温兆伦',age:'22',sex:'男'}
            ],
          //  filPersons:[]    //用watch实现
            },
           /*  watch:{
               keyword:{
                   immediate:true,
                   handler(val){
                      this.filPersons=this.persons.filter((p)=>{
                          return p.name.indexOf(val)!=-1;
                      })
                   }
               }
            } */
           computed:{
               filPersons(){
                  return this.persons.filter((p)=>{
                       return p.name.indexOf(this.keyword)!=-1;
                   })
               }
           }


    })
</script>
</html>

在实现某些功能的时候记得不要轻易修改原数据

列表排序:

 

<!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>Document</title>
    <script src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>人员列表</h2>
        <input type="text" placeholder="请搜索名字" v-model="keyword">
        <button @click='sortType=2'>年龄升序</button>
        <button @click='sortType=1'>年龄降序</button>
        <button @click='sortType=0'>原顺序</button>
        <ul>
            <li v-for="(p,index) in filPersons" :key="p.id">
                {{p.name}}-{{p.age}}-{{p.sex}}
            </li>
        </ul>

    </div>
</body>

<script>
    Vue.config.productionTip=false;
    new Vue({
        el:'#root',
        data:{
            sortType:0,
            keyword:'',
            persons:[
                {id:'001',name:'马冬梅',age:'30',sex:'女'},
                {id:'002',name:'周冬雨',age:'31',sex:'女'},
                {id:'003',name:'周杰伦',age:'18',sex:'男'},
                {id:'003',name:'温兆伦',age:'19',sex:'男'}
            ]
            },
            computed:{
               filPersons(){
                  const arr=this.persons.filter((p)=>{
                       return p.name.indexOf(this.keyword)!=-1;
                   })
                   if(this.sortType){
                       arr.sort((p1,p2)=>{
                           return this.sortType===1?p2.age-p1.age:p1.age-p2.age;
                       })
                   }
                   return  arr;
               }
          
            }
    })
</script>
</html>

Vue.set使用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Vue监测数据改变的原理</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 准备好一个容器-->
		<div id="root">
			<h1>学校信息</h1>
			<h2>学校名称:{{school.name}}</h2>
			<h2>学校地址:{{school.address}}</h2>
			<h2>校长是:{{school.leader}}</h2>
			<hr/>
			<h1>学生信息</h1>
			<button @click="addSex">添加一个性别属性,默认值是男</button>
			<h2>姓名:{{student.name}}</h2>
			<h2 v-if="student.sex">性别:{{student.sex}}</h2>
			<h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}</h2>
			<h2>朋友们</h2>
			<ul>
				<li v-for="(f,index) in student.friends" :key="index">
					{{f.name}}--{{f.age}}
				</li>
			</ul>
		</div>
	</body>

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

		const vm = new Vue({
			el:'#root',
			data:{
				school:{
					name:'尚硅谷',
					address:'北京',
				},
				student:{
					name:'tom',
					age:{
						rAge:40,
						sAge:29,
					},
					friends:[
						{name:'jerry',age:35},
						{name:'tony',age:36}
					]
				}
			},
			methods: {
				addSex(){
					// Vue.set(this.student,'sex','男')
					this.$set(this.student,'sex','男')
				}
			}
		})
	</script>
</html>

 Vue数据监测总结

Vue监视数据的原理:
                1. vue会监视data中所有层次的数据。

                2. 如何监测对象中的数据?
                                通过setter实现监视,且要在new Vue时就传入要监测的数据。
                                    (1).对象中后追加的属性,Vue默认不做响应式处理
                                    (2).如需给后添加的属性做响应式,请使用如下API:
                                                    Vue.set(target,propertyName/index,value) 或 
                                                    vm.$set(target,propertyName/index,value)

                3. 如何监测数组中的数据?
                                    通过包裹数组更新元素的方法实现,本质就是做了两件事:
                                        (1).调用原生对应的方法对数组进行更新。
                                        (2).重新解析模板,进而更新页面。

                4.在Vue修改数组中的某个元素一定要用如下方法:
                            1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
                            2.Vue.set() 或 vm.$set()
                
                特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!

收集表单数据

 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>收集表单数据</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 
			收集表单数据:
					若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。
					若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。
					若:<input type="checkbox"/>
							1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
							2.配置input的value属性:
									(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
									(2)v-model的初始值是数组,那么收集的的就是value组成的数组
					备注:v-model的三个修饰符:
									lazy:失去焦点再收集数据
									number:输入字符串转为有效的数字
									trim:输入首尾空格过滤
		-->
		<!-- 准备好一个容器-->
		<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>

 

过滤器

内置指令

先总结一下已经学习过的指令

v-bind:单向数据绑定 可以简写为:×××

v-model:双向数据绑定

v-for:进行数据的遍历,比如对象,数组和字符串的遍历

v-on:绑定时间监听,可以简写为@

v-if:条件渲染,动态控制节点是否存在

v-else:条件渲染

v-show:条件渲染

v-text

向其所在的节点渲染文本内容,与插值语法存在区别{{}}

v-text会替换掉节点里面的内容

<div id="root">
			<div>你好,{{name}}</div>
			<div v-text="name">哈哈哈</div>
			<div v-text="str"></div>
		</div>
new Vue({
			el:'#root',
			data:{
				name:'蛰伏',
				str:'<h3>你好啊!</h3>'
			}
		})

v-text会让数据变为name变量中的内容,不管v-text的节点里面有没有初始值

v-html

v-html和v-text有相似之处,但也有区别

v-html可以渲染html结构,v-text则不会

1.作用:向指定节点中渲染包含html结构的内容。

2.与插值语法的区别:

(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。

(2).v-html可以识别html结构。

3.严重注意:v-html有安全性问题!!!!

(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。

(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!

 

v-cloak

v-cloak指令(没有值):

1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。

2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。

 

v-once

v-once指令:

1.v-once所在节点在初次动态渲染后,就视为静态内容了。

2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。

v-pre

v-pre指令:

1.跳过其所在节点的编译过程。

2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。

自定义指令:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>自定义指令</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 
				需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
				需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
				自定义指令总结:
						一、定义语法:
									(1).局部指令:
												new Vue({															new Vue({
													directives:{指令名:配置对象}   或   		directives{指令名:回调函数}
												}) 																		})
									(2).全局指令:
													Vue.directive(指令名,配置对象) 或   Vue.directive(指令名,回调函数)

						二、配置对象中常用的3个回调:
									(1).bind:指令与元素成功绑定时调用。
									(2).inserted:指令所在元素被插入页面时调用。
									(3).update:指令所在模板结构被重新解析时调用。

						三、备注:
									1.指令定义时不加v-,但使用时要加v-;
									2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。
		-->
		<!-- 准备好一个容器-->
		<div id="root">
			<h2>{{name}}</h2>
			<h2>当前的n值是:<span v-text="n"></span> </h2>
			<!-- <h2>放大10倍后的n值是:<span v-big-number="n"></span> </h2> -->
			<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
			<button @click="n++">点我n+1</button>
			<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){
						element.value = binding.value
					},
					//指令所在元素被插入页面时
					inserted(element,binding){
						element.focus()
					},
					//指令所在的模板被重新解析时
					update(element,binding){
						element.value = binding.value
					}
				}
			}
		})
		
	</script>
</html>

生命周期

  

 from 尚硅谷Vue视频

组件

非单文件组件

Vue中使用组件的三大步骤:

一、定义组件(创建组件)

二、注册组件

三、使用组件(写组件标签)

一、如何定义一个组件?

使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;

区别如下:

1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。

2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。

备注:使用template可以配置组件结构。

二、如何注册组件?

1.局部注册:靠new Vue的时候传入components选项

2.全局注册:靠Vue.component('组件名',组件)

三、编写组件标签:

<school></school>

<!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:`
				<div class="demo">
					<h2>学校名称:{{schoolName}}</h2>
					<h2>学校地址:{{address}}</h2>
					<button @click="showName">点我提示学校名</button>	
				</div>
			`,
			// el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
			data(){
				return {
					schoolName:'尚硅谷',
					address:'北京昌平'
				}
			},
			methods: {
				showName(){
					alert(this.schoolName)
				}
			},
		})

		//第一步:创建student组件
		const student = Vue.extend({
			template:`
				<div>
					<h2>学生姓名:{{studentName}}</h2>
					<h2>学生年龄:{{age}}</h2>
				</div>
			`,
			data(){
				return {
					studentName:'张三',
					age:18
				}
			}
		})
		
		//第一步:创建hello组件
		const hello = Vue.extend({
			template:`
				<div>	
					<h2>你好啊!{{name}}</h2>
				</div>
			`,
			data(){
				return {
					name:'Tom'
				}
			}
		})
		
		//第二步:全局注册组件
		Vue.component('hello',hello)

		//创建vm
		new Vue({
			el:'#root',
			data:{
				msg:'你好啊!'
			},
			//第二步:注册组件(局部注册)
			components:{
				school,
				student
			}
		})

		new Vue({
			el:'#root2',
		})
	</script>
</html>

 

几个注意点:

1.关于组件名:

一个单词组成:

第一种写法(首字母小写):school

第二种写法(首字母大写):School

多个单词组成:

第一种写法(kebab-case命名):my-school

第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)

备注:

(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。

(2).可以使用name配置项指定组件在开发者工具中呈现的名字。

2.关于组件标签:

第一种写法:<school></school>

第二种写法:<school/>

备注:不用使用脚手架时,<school/>会导致后续组件不能渲染。

3.一个简写方式:

const school = Vue.extend(options) 可简写为:const school = options

组件的嵌套

 

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

        const student=Vue.extend({
            template:`
            <div>
					<h2>学生名字:{{name}}</h2>	
					<h2>学生年龄:{{age}}</h2>	
				</div>
            `,
            data(){
                return{
                   name:'蛰伏',
                    age:18 
                }
            }
        })

		const school = Vue.extend({
			name:'atguigu',
			template:`
				<div>
					<h2>学校名称:{{name}}</h2>	
					<h2>学校地址:{{address}}</h2>	
                    <student></student>
				</div>
			`,
			data(){
				return {
					name:'尚硅谷',
					address:'北京'
				}
			},
            components:{
                student
            }
		})
		
          const hello=Vue.extend({
              template:`<h2>{{msg}}</h2>`,
              data(){
                  return{
                      msg:'你好hello'
                  }
              }
          })

        new Vue({
			el:'#root',
			components:{
				school
			}
		})
	</script>
</html>

VueComponents

关于VueComponent:

*1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

2.我们只需要写<school/>或<school></school>,Vue解析时会帮我们创建school组件的实例对象,

即Vue帮我们执行的:new VueComponent(options)。

3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!

4.关于this指向:

(1).组件配置中:

data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。

(2).new Vue(options)配置中:

data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。

Vue的实例对象,以后简称vm。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值