学习准备:要求note.js是15.0以上版本,熟练cmd命令框命令
创建项目命令:npm init vue@latest
项目名字:小写英文
项目安装:npm/cnpm install
运行项目:npm run dev
文件内容:
一、模版语法
Vue使用一种基于HTML的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的DOM上。所有的Vue模版都是语法层面合法的HTML,可以被符合规范的浏览器和HTML解析器解析!
{{}}插值表达式当中只能是单一表达式!验证如下:
//正确案例
<template>
<h3>练习题1</h3>
<p>{{ statement }}</p>
<p>{{number}}</p>
<p>{{ok? 'yes':'no'}}</p>
//先通过空字符串split进行切割message字符串,然后reverse翻转字符串,后通过join合并字符串
<p>{{message.split("").reverse().join("")}}</p>
</template>
<script>
export default {
data() {
return {
statement:"炫腾的黑马",
number:20,
ok:true,
message:"大家好"
}
}
}
</script>
//错误案例
<p> {{var a = 1}}</p>//这是一条语句,不是单一表达式
<p>{{if(ok){return message}}}</p>//这不是一个单一表达式
v-html指令
如下面代码:
<template>
<h3>练习题1</h3>
<p v-html="Inter"></p>
//{{}}这个插入的是一段纯文本,要想插入的是HTML语言,需要输入指令v-html
<p> {{Inter}} </p>
</template>
<script>
export default {
data() {
return {
Inter:"<a href= https://www.Baidu.com>中国百度</a>"
}
}
}
</script>
运行案例:
二、属性绑定
{{ }}不能在HTML的属性当中使用,这个时候我们想要绑定一个属性就可以使用指令v-bind!
v-bind 绑定属性------------' v-bind: ' 可以简写成 ' : '
当其中的一个绑定,变成null或者undefined,则这个属性(attribute)会被移除!假如displayTitle:null,则调试结果为title属性被移除:
布尔值attribute (true/false) 一般常用于button按钮
disable ------ 这个属性就是默认为按钮不可按动 代码案例如下:
// disabled默认为true,即按钮不能按动!当isButtonDisabled为true时 ,按钮不能按动,当为false时,按钮可按动
//利用了v-bind绑定属性disabled
<template>
<h3>练习题1</h3>
<button v-bind:disabled = "isButtonDisabled" >button</button>
</template>
<script>
export default {
data() {
return {
isButtonDisabled: false
};
},
};
</script>
动态绑定自定义多个值
<template>
<h3>练习题1</h3>
<!-- 绑定属性的作用可能是为了设置css样式等等-->
<div v-bind="Person1">人民日报</div>
<button v-bind:disabled = "isButtonDisabled" >button</button>
</template>
<script>
export default {
data() {
return {
//两个自定义属性
Person1:{
displayId:"appid",
displayClass:"appClass"
},
isButtonDisabled: false
};
},
};
</script>
调试案例:
当我们将displayId改成id,将displayClass改成class的时候,发现就变成我们HTLM当中的id属性和class属性了!
export default {
data() {
return {
Person1:{
id:"appid",
class:"appClass"
},
isButtonDisabled: false
};
},
};
调试案例:
三、条件渲染
条件:v-if v-else-if v-else v-show的案例说明:
<template>
<h3>练习题2</h3>
//v-model数据双向绑定指令
<input type="text" name="username" v-model="type">
<div v-if="type==='A'">A类型</div>
<div v-else-if="type==='B'">B类型</div>
<div v-else-if="type==='C'">C类型</div>
<div v-else>Not A/B/C</div>
<div v-show="type==='A'">A类型</div>
<div v-show="type==='B'">B类型</div>
<div v-show="type==='C'">C类型</div>
</template>
<script>
export default{
data(){
return{
type:'B'
}
}
}
</script>
v-if和v-show 的区别:v-if是条件渲染,当我们是false的时候,该条语句是不做任何处理的,直接被浏览器舍弃,而v-show 是无论是false还是true都会被渲染!
v-if :切换开销大,初次渲染开销小,当我们的代码中频繁的切换会每次都要渲染,则不建议使用v-if 使用v-show
v-show: 初次渲染开销大,但是切换开销小,以为初次以全部渲染,频繁切换不会出现渲染。
总结:
四、列表渲染
指令 v-for 的使用方法:
当我们电脑使用发现v-for="items of item"无故报错则参考:报错问题解决
在items in item 当中,我们可以用of替换掉in,推荐使用of
<template>
//第一种遍历数组
<div v-for="adrs of adr">
<p>{{adrs.name}}</p>
<p>{{adrs.note}}</p>
<p>{{adrs.area}}</p>
</div>
//第二种遍历数组
<p v-for="(item,index) in adr">{{index + 1}}:{{item.name}}</p>
//第三种遍历对象
<p v-for="(Man,key,index) of Person">{{index+1}}-{{key}}-{{Man}}</p>
</template>
<script>
export default{
data(){
return{
adr:[{"name":"天津农业大学" ,"note":"https://www.tjau.edu.cn/","area":12000},{"name":"百度","note":"https://www.Baidu.com","area":600},
{"name":"阳高一中","note":"http://www.tju.edu.cn/index.htm","area":1000000}],
Person:{
name:"张三",
age:14,
high:184,
address:"山西平遥"
}
}
}
}
</script>
运行案例:
五、通过key管理状态
key 一般用与v-for指令当中,做一个标记!当数据增加或减少的时候不用全部重写渲染,而是渲染增加的!
//key当中的内容一般是字符串或数字,用于标记
//一定程度上节省资源的消耗
<template>
<p v-for="(item,index) in adr" :key="item.id">{{index + 1}}:{{item.name}}</p>
</template>
<script>
export default{
data(){
return{
adr:[{"id":23654,"name":"天津农业大学" ,"note":"https://www.tjau.edu.cn/","area":12000},{"id":35654,"name":"百度","note":"https://www.Baidu.com","area":600},
{"id":29654,"name":"阳高一中","note":"http://www.tju.edu.cn/index.htm","area":1000000}],
}
}
}
</script>
六、事件处理
v-on 用来监听DOM事件,v-on:=== @,在应用的时候, 可以写成v-on:click="handler"或者@click="handler"
<template>
<p>事件处理</p>
//内联事件处理器
//事件被触发的时候执行的JS语句
//dblclick属性是指必须双击按钮才可以生效
<button v-on:click="cont++">按钮</button>
<p>{{cont}}</p>
//方法事件处理器
//事件被触发的时候调用方法
<button v-on:click="add">按钮</button>
</template>
<script>
export default{
data(){
return{
cont:0,
}
},
methods:{
add:function(){
//this.cont -----意思是自己data当中的变量++
this.cont++;
}
}
}
</script>
注意事项:this.变量,调用的自己data当中的变量!!!
七、事件传参
1.获取event对象,简称e
<template>
<p>事件处理</p>
<button @click="add">按钮</button>
<p>{{cont}}</p>
</template>
<script>
export default{
data(){
return{
cont:0,
}
},
methods:{
add(e){//event
this.cont++;
console.log(e),//1.相当与获取地址
console.log(e.target);//2.相当于通过地址获取该标签当做的内容
console.log(e.target.innerHTML);//3.获取标签所包裹的内容
}
}
}
</script>
运行案例:
2.当我们方法当中有参数传递的时候,获取event对象,案例如下:
注意一点:当外侧已经使用双引号,内部如果需要用到引号的使用单引号!!!
<template>
<p>事件处理</p>
//下方add方法当中字符串使用单引号
<button @click="add('Hello bit',$event)">按钮</button>
</template>
<script>
export default{
data(){
return{
}
},
methods:{
add(ment1,e){
console.log(ment1),
console.log(e),//相当与获取地址
console.log(e.target);//相当于通过地址获取该标签当做的内容
console.log(e.target.innerHTML);//获取标签所包裹的内容
}
}
}
</script>
案例2:
<template>
<p style="color:red">事件传参</p>
<div @click="getNameConsole(Names,$event)" v-for="(Names,index) of Name" ::key="index">{{index+1}} : {{Names}}</div>
</template>
<script>
export default{
data(){
return{
Name:["links","front","pig","seven"],
}
},
methods:{
getNameConsole(Npc,e){
console.log(Npc);
console.log(e.target);
}
}
}
</script>
八、事件修饰符
在HTML当中有阻止事件冒泡 "event.stoppropagation()" 和阻止默认事件等 " event.preventDefault() " .......
事件冒泡:当我们子元素的事件触发后父元素事件也触发了,当子元素加上.stop 后,父元素当中的事件不触发,只触发子元素当中的事件
默认事件:这个标签本来点击就要默认执行调到Baidu这个网站,这个就是默认事件,当加入.prevent后取消跳转网站
在Vue3当中为v-on提供了很多更加方便的事件修饰符,而不用像HTML当中在方法当中调用!
事件修饰符:.stop、.prevent、.once、.enter...........
修饰符地址:事件处理 | Vue.js
我们以阻止事件冒泡和阻止默认事件为例:
<template>
<a v-on:click.prevent="Handler" href="https://Baidu.com">中国百度</a>//Vue取消默认事件修饰符
//阻止事件冒泡
<div @click="Handler1">
<p @click.stop="Handler2">中国华为</p>//Vue当中阻止事件冒泡的修饰符
</div>
</template>
<script>
export default{
data(){
return{
}
},
methods:{
Handler(){
//e.preventDefault();//HTML方法阻止默认事件
console.log("点击了");
},
//父元素当中的方法
Handler1(){
console.log("Handler1");
},
//子元素当中的方法
Handler2(e){
//e.stopPropagation();//HTML方法阻止事件冒泡
console.log("Handler2");
}
}
}
</script>
九、数组变换侦测
这当中有两类方法,一类为变更数组,一类为替换数组!变更数组会直接改变UI界面,而替换数组不会直接改变UI界面
1.变更数组,当按下增加数据按钮的时候,直接在页面显示增加 “开心超人” 方法:pop() push() shift() unshift() splice() sort() reverse().......
<template>
<button @click="AddPerson">增加数据</button>
<ul>
<li style="list-style-type:none" v-for="(person1,index) of Person" :key="index">{{person1}}</li>
</ul>
</template>
<script>
export default {
data(){
return{
Person:["张三","王五","赵六","李四"]
}
},
methods: {
AddPerson(){
this.Person.push("开心超人");
}
}
}
</script>
2.替换数组 当没有 this.Person =this.Person.concat(["王霸天"]);这个替换旧数组的时候,UI界面不会显示增加数据,但是数组的数据增加了 方法:concat() filter() slice()
<template>
<button @click="AddPerson">增加数据</button>
<ul>
<li style="list-style-type:none" v-for="(person1,index) of Person" :key="index">{{person1}}</li>
</ul>
</template>
<script>
export default {
data(){
return{
Person:["张三","王五","赵六","李四"]
}
},
methods: {
AddPerson(){
this.Person.concat(["王霸天"]);
console.log(this.Person.concat(["王霸天"]));
this.Person =this.Person.concat(["王霸天"]);
}
}
}
</script>
观察控制台上数组增加的数据
案例:数组合并
<template>
<button @click="AddPerson">合并数组</button>
<ul>
<!-- list-style-type:none :清除圆点 -->
<p style="color :red">数组1</p>
<li v-for="(arrays1,index) of num1" :key="index"> {{arrays1}}</li>
<p style="color :red">数组2</p>
<li v-for="(arrays2,index) of num2" :key="index"> {{arrays2}}</li>
</ul>
</template>
<script>
export default {
data(){
return{
num1:[1,2,3,4,5,6],
num2:[7,8,9,10,0],
}
},
methods: {
AddPerson(){
this.num1 = this.num1.concat(this.num2);
}
}
}
</script>
运行案例:
十、计算属性
当我们谈到计算属性的时候,就会谈到计算属性 VS 方法有什么区别呢?
1.计算属性的关键字是computed, 方法的属性是methods.
2.计算属性在整个程序中,多次调用,计算属性当中的方法只会调用计算一次,而方法methods当中定义的方法,每调用一次就计算一次!
3.他们计算的结果是一样的,就是消耗的资源computed比methods少,但是当每一次方法调用的内容都不一样的时候,他们就没有多大区别了!
案例:
注意:方法属性当中的方法调用的时候要加 "()" !!!
<template>
//计算属性当中虽然调用四次但是只计算了一次,其余三个是直接拿来用的
<div>{{ MyTest }}</div>
<div>{{ MyTest }}</div>
<div>{{ MyTest }}</div>
<div>{{ MyTest }}</div>
-----------------------------
//方法属性是调用几次计算几次
<div>{{ MyTest1() }}</div>
<div>{{ MyTest1() }}</div>
<div>{{ MyTest1() }}</div>
<div>{{ MyTest1() }}</div>
</template>
<script>
export default {
data(){
return{
names:["张三","李四","王五","赵六"]
}
},
computed:{
MyTest(){
return this.names.length>0?"yes":"No";
}
},
methods:{
MyTest1(){
return this.names.length>0?"yes":"No";
}
}
}
</script>
十 一、Class绑定
因为class也是属性,我们就想到了用Vue当中的v-bind和class结合起来使用,这样我们class=“ ”当中就可以不单单是字符串,也可以是对象和数组!!!
注意:这里的绑定只能是数组当中包含对象,而不能对象包含数组,也就是说[{ }],而不能是{[ ]}
<template>
//第一种是绑定对象(绑定多个对象)
<p :class="{ mas: Judge1, tag: isError }">Class样式绑定1</p>
<p :class="{mas:Judge1}">Class样式绑定1</p>//单个对象绑定
//对象绑定,将两个对象整个到一个对象当中绑定
<p :class="option1" >Class样式绑定2</p>
//数组绑定
<p :class="[arrMas,arrTag]" >Class样式绑定3</p>
//对象数组混合绑定
<p :class="[{mas:Judge1},arrTag]" >Class样式绑定4</p>
//三目运算符和数组绑定
<p :class="[Judge1? 'mas' :'',arrTag]" >Class样式绑定5</p>
</template>
<script>
export default {
data() {
return {
Judge1: true,
isError: true,
option1:{
mas: true,
tag: true
},
arrMas:"mas",
arrTag:"tag",
}
}
};
</script>
<style>
.mas {
font-size: 30px;
}
.tag {
color: red;
}
</style>
案例运行:
十二、style绑定
style与v-bind结合后同样不单单是字符串,可以是对象和数组,但是这里数组不建议使用!
<template>
//style绑定对象
<p :style="{color:ColorRed,fontSize:big + 'px'}">style绑定</p>
<p :style="Person">style绑定2</p>//创建一个对象后绑定对象就ok
</template>
<script>
export default{
data(){
return{
ColorRed:"red",
big:30,
Person:{
color:"red",
fontSize:"30px"
}
}
}
}
</script>
十三、侦听器
侦听器只能监听动态的内容,而不能改变的内容是无法被监听的!
侦听器当中的watch:{}属性是与data平级的,而且当中定义的方法名要与被监听内容保持一致!
<template>
<p>{{message}}</p>
<button @click="check()">修改数据</button>
</template>
<script>
export default{
data(){
return{
message:"Hello",
}
},
methods:{
//修改内容
check(){
this.message = "world";
}
},
watch:{
//方法message要与被监听的message一致
//当被监听的内容发生修改的时候自动调用!
//newValue ----表示修改后的值
//oldValue ----表示修改前的值
message(newValue,oldValue){
console.log(newValue,oldValue);
}
}
}
</script>
运行案例:
十四、表单输入绑定
在前端开发当中,我们要实时在text文本框当中获取数据到JS当中,这个时候我们就需要到Vue当中一个强大的指令v-model
v-model:就是HTML当中和JS当中数据的绑定
<template>
<input type="checkbox" id="message" v-model="Message">
//该标签一般与<input>标签联用,是聚焦作用
//label一般都与input绑定使用
<label for="message">{{Names}}</label>//聚焦作用,点在该标签下的文本上,也会自动选择与该标签绑定的<input>
<input type="text" v-model="Message">
<p>{{Message}}</p>
</template>
<script>
export default {
data(){
return{
Message:false,
Names:"点我"
}
},
}
</script>
和v-model相关联的修饰符有.lazy、.number .trim
.lazy:作用主要是当我们在文本框当中输入文字内容的时候,下面和其用v-model绑定的Js数据不会马上发生改变,只有敲回车、鼠标不聚焦于文本框才可以同步储存于JS当中绑定的数据当中!!!
.number:使用修饰符.number可以将输入的数据转换为Number类型,否则虽然你输入的是数字.但它的类型其实是String!!!
.trim:当文本框当中输入的字符串前后都有空格,他会自动帮忙去掉!!!
<template>
<input type="text" v-model.lazy="Message">1<br><br>
<input type="text" v-model.number="Names">2<br><br>
<input type="text" v-model.trim="Person">3<br><br>
<p>{{Message}}</p>
<p>{{Names}}</p>
<p>{{Person}}</p>
</template>
<script>
export default {
data(){
return{
Message:"",
Names:"",
Person:""
}
},
}
</script>
运行案例:
十五.模版引用
Vue当中的ref属性=====》操作DOM元素,我们可以通过ref和this.$refs这一套属性联用可获取DOM元素当中输入的值和标签元素或修改DOM元素当中的内容 ,代码案例:
<template>
<div ref="getElement1" class="dateInner">{{message}}</div>
<button @click="GetElement2()">获取元素</button>
<input ref="getElement2" type="text">
</template>
<script>
export default {
data(){
return{
message:"盒子模型"
}
},
methods:{
GetElement2(){
this.$refs.getElement1.innerHTML = "我被修改了";
console.log(this.$refs.getElement2.value);//获取的是这个文本框当中的值,就用value
}
}
}
</script>
this.$refs.getElement1获取的是一个绑定的标签这个元素:
运行案例:
十六、组件组成
在外面组件当中可分为三个部分<template>、<script>、<style>
当我们在Vue项目当中,总是把所有Vue组件(import)导入到APP.vue当中的script标签当中,并且在APP.vue这个页面当中的template标签当中注册组件,这样才能再页面当中显示!
代码案例如下(组件):
/* 页面显示的地方 */
//test1.vue文件
<template>
</template>
/* 逻辑实现的地方 */
<script>
export default {
//对象形式存放数据
data(){
return{
}
},
//方法
methods:{
},
//计算属性
computed:{
}
}
</script>
/* 样式实现的地方 */
<style >
</style>
scoped 属性:类似于作用域,当加上scoped后,这个style就不是属于整个项目的了,而是属于本.vue文件!!!
加scoped:
没有加scoped: 该样式就属于整个项目,在其他组件当中也可以利用该属性!!!
scoped设计的初衷就是不能让当前组件的样式修改其他任何地方的样式
十七、组件的嵌套关系和注册方式
一个好看的UI界面是由大大小小的 组件嵌套组成的,他们构造了这一个复杂的UI界面,组件的嵌套是任意的嵌套的,Vue我们中,我们只需要在不同的组件当中封装其逻辑的实现和自定义内容。
组件的注册分为两个方式:一种是局部注册,一种是全局注册!
局部注册:
将Test1 插入Test2 组件当中!!!这样就形成了一个类似于父组件和子组件的关系,当父组件存在显示的时候,子组件就可以显示,就无需在APP.vue 当中注册了!!
全局注册:
当全局注册的时候,我们就可以在任意一个.vue 文件当中使用了,只需要在每一个文件当中的template 当中加入显示: 例如
注意:在后续开发当中,我们一般不推荐使用这个全局组件的,因为当我们有的项目当中没有使用这个组件,但是依旧会被打包,造成资源的浪费。并且在后期维护当中,不利于维护!!!
十八、组件传递数据(_props)
组件与组件当中不是相互独立的,而是相互存在交集的,组件与组件之间的关系不仅仅是嵌套关系,还可以传递数据!!
静态数据传递:
动态数据传递:
利用v-bind 实现动态数据绑定,让数据传递更加灵活!!
运行案例:
注意:利用props传递数据的时候只能从父级到子级,不能逆向传递!!
组件传递props接收任何数据类型:
例如 : Number Arrays Object.
运行结果:
十九、组件传递数据props的效验
数据传输的限制:
当我们子组件继承父组件后,子组件当中的继承数据可以限制继承的范围!
下面可以得出子组件继承父组件的 title 只能传递字符串类型,否则会虽然不会影响显示,但是还是会报出一个警告!
当然,我们也可以不单单让title只能传递Number ,我们可以让他传递多一些类型的数据!例如:
这样 title 就可以接收父组件传递过来的这四种类型就都能接收了!
默认值(default):
当我们子组件想要让父组件传递某一些数据的时候,但是父组件并没有给传递过来,这样当我们什么也不规定的时候,不会报错,也不会报警告,只是不会在UI上显示。
这样如果我们想让他告诉我们父组件没有给传递过来的时候,这个时候我们就可以在屏幕打印一些东西告诉我们父组件没有传递过来数据。
这个时候我们需要用到默认值:default: .....设置一些值来提醒程序员
必选项(required):
这个属性会虽然不会报错,但是会报警告!!!类似于default 但是我认为屏幕没有像default一样显示,如果不打开网页检测,可能会忘记操作///
注意事项:props 是只读的,不能修改父组件当中的数据!例如:
<template>
<p>test2测试</p>
<p>{{title}}</p>
<p v-for="(item,index) of sex" :key="index">{{item}}</p>
<p>{{ number }}</p>
<button @click="ModifyWord">Modify word</button>
</template>
<script>
export default{
data(){
return{
}
},
props:{
title:{
type:[Number,String,Array,Object,Boolean],
},
sex:{
type:Object
},
number:{
type:Number,
required:true,
},
},
methods:{
ModifyWord(){
console.log(this.number);
this.number = 20;
}
}
}
</script>
这个时候,我们看运行结果:(可以显示值,但是不能修改)
二十、组件事件 和 组件事件配合v-model 的使用
我们平时有子类组件继承父类组件,当我们父类组件想利用子类组件的数据的时候,我们就可以用$emit()(触发自定义事件),可以将子类组件当中的数据传入到父类当中,让父类组件利用子类组件当中的数据!
组件事件:
1.我们先在子组件当中设置一个button按钮,v-on调用一个方法,然后通过在这个方法当中设置this.$emit来向父类传递数据!
子组件当中:
父组件当中:
运行结果:
组件事件配合v-model 和 侦听器 watch 向父组件传递数据
首先我们需要用v-model 绑定data当中的数据,然后当我们在text文本当中输入字符串的时候,我们就会改变data当中绑定的数据,接下来我们就可以利用侦听器监听数据改变,然后再利用this.$emit将数据传输给父组件,在父组件当中显示出来。
test1(父组件)
<template>
<p>test1测试</p>
<test2 @SomeData ="deliverData" />
<p >传递数据:{{this.dataOK}}</p>
</template>
<script>
import test2 from './test2.vue'
export default{
data(){
return{
dataOK:""
}
},
components:{
test2
},
methods:{
deliverData(data){
this.dataOK = data;
}
}
}
</script>
test2(子组件)
<template>
<p>test2测试</p>
搜索:<input type="text" v-model="message">
</template>
<script>
export default{
data(){
return{
message:""
}
},
watch:{
message(newValue,oldValue){
this.$emit("SomeData",newValue);
}
}
}
</script>
运行结果:
_组件数据传递(利用props函数实现子传父)-------回调函数
子组件:
<template>
<p>test2测试</p>
<p>{{title}}:{{getValue(message)}}</p>
</template>
<script>
export default{
data(){
return{
message:"中国万岁"
}
},
props:{
title:String,
getValue:Function,
}
}
</script>
父组件:
<template>
<p>test1测试</p>
<test2 :getValue="dataAb" :title="message"/>
<p>父组件:{{ dataOK }}</p>
</template>
<script>
import test2 from './test2.vue'
export default{
data(){
return{
dataOK:"",
message:"标题"
}
},
components:{
test2
},
methods:{
dataAb(data){
this.dataOK = data;
}
}
}
</script>
运行结果:
二十一、插槽slot
插槽slot 属性的作用是一个插槽出口,slot属性写在那个子组件当中表明父组件当中的数据将在那个组件当中渲染出来!
//test1
<template>
<test2>
<div>
<p>插槽基础</p>
<h3>学习认真的基础</h3>
</div>
</test2>
</template>
<script>
import test2 from './test2.vue'
export default{
components:{
test2
}
}
</script>
//test2
<template>
<slot></slot>
<p>test2测试</p>
</template>
<script>
</script>
打印效果:
理解图:
渲染作用域:
插槽内容可以访问到父组件的data数据作用域,让父组件当中的数据 在slot 修饰的子组件当中渲染出来。
//父组件
<template>
<test2>
<p>{{ message }}</p>
<p>{{ high }}</p>
<p>{{ age }}</p>
</test2>
</template>
<script>
import test2 from './test2.vue'
export default {
data(){
return{
message:"data数据传递作用域",
high:325,
age:65
}
},
components:{
test2,
}
}
</script>
//父组件
<template>
<p>Vue前端项目开发测试</p>
<slot>插槽默认值</slot>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
运行结果:
插槽的默认内容:
当父组件没有给传递数据的时候,会输出一个默认值,传递后这个默认值将不再输出。
运行结果:
具名插槽:
顾名思义,当我们父组件向子组件传递的数据的时候,我们需要在子组件当中不同的地方打印同一父组件当中的不同的内容,这样我们就需要通过命名来区别不同的内容,达到不同的目的。
这个时候我们需要一个指令v-slot: 同时这个指令可以简写成 #
父组件:
<template>
<test2>
//用v-slot来命名
//切记要用<template>标签包裹
<template v-slot:title>
<p>{{ message }}</p>
</template>
//同时可以简单写成 #
<template #person>
<p>{{ high }}</p>
<p>{{ age }}</p>
</template>
</test2>
</template>
<script>
import test2 from './test2.vue'
export default {
data(){
return{
message:"data数据传递作用域",
high:325,
age:65
}
},
components:{
test2,
}
}
</script>
//子组件
<template>
<p>Vue前端项目开发测试</p>
<slot name="title">插槽默认值</slot>
<hr>
<slot name="person">插槽默认值</slot>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
当我们在子组件当中同时使用父组件当中的数据和本子组件当中的数据:具体方法就要用到 ‘ :’ 从子组件当中发送数据到父组件当中,然后使用v-slot = ""来接收数据,再整体通过插槽发送给子组件,这个时候子组件当中就能同时使用父组件和子组件当的数据了。
具名插槽传递数据:
当我们子组件向父组件传递其所有子组件数据的时候,我们就可以不需要具名插槽,我们就可以直接传递数据,具体方法就可以参考:
当我们传递一条数据的时候:
我们可以利用v-slot=""传递数据
//子组件
<template>
<p>Vue前端项目开发测试</p>
<slot :sob="earth">插槽默认值</slot>
<!-- <slot :ear="schoolBag"></slot> -->
</template>
<script>
export default {
data(){
return{
schoolBag:45,
earth:"地球属性"
}
}
}
</script>
//父组件
<template>
<test2 v-slot="SlotProps">
<p>{{message}}-{{ SlotProps.sob }}</p>
</test2>
</template>
<script>
import test2 from './test2.vue'
export default {
data(){
return{
message:"data数据传递作用域",
high:325,
age:65
}
},
components:{
test2,
}
}
</script>
运行结果:
注意:当我们传递多条数据的时候,我们就不能这样写了,看的可以传递,其实传递后会秩序混乱。
所以当我们传递多条数据的时候,我们就需要到具名插槽了,这个时候,就需要为不同的名字用标签包裹起来,这样就可以实现某一个子组件向父组件传递多条数据了!
//子组件
<template>
<p>Vue前端项目开发测试</p>
<slot name="handle" :sob="earth">插槽默认值</slot>
<slot name="Person" :ear="schoolBag">插槽默认值</slot>
</template>
<script>
export default {
data(){
return{
schoolBag:45,
earth:"地球属性"
}
}
}
</script>
//父组件
<template>
<test2>
<template #handle="SlotProps">
<p>{{message}}-{{ SlotProps.sob }}</p>
</template>
<template #Person="SlotProps">
<p>{{high}}--{{ SlotProps.ear}}</p>
</template>
</test2>
</template>
<script>
import test2 from './test2.vue'
export default {
data(){
return{
message:"data数据传递作用域",
high:325,
age:65
}
},
components:{
test2,
}
}
</script>
运行结果:
二十二、组件的生命周期
我们的Vue项目当中要经历四个阶段:
创建期:beforeCreat、created
挂载期:beforeMount、mounted
更新期:beforeUpdate、updated
销毁期:beforeUnmount、unmounted
<template>
<p>Vue前端项目开发测试</p>
<p>{{ message }}</p>
<button @click="updateBefore">点击更新</button>
</template>
<script>
export default {
data(){
return{
message:"更新之前"
}
},
methods:{
updateBefore(){
this.message = "更新之后"
}
},
beforeCreate(){
console.log("创建之前");
},
created(){
console.log("创建之后");
},
beforeMount(){
console.log("渲染之前");
},
mounted(){
console.log("渲染之后");
},
beforeUpdate(){
console.log("更新之前");
},
updated(){
console.log("更新之后");
},
beforeUnmount(){
console.log("销毁之前");
},
unmounted(){
console.log("销毁之后");
}
}
</script>
当我们没有点击数据更新的时候:
当我们没有点击数据更新的时候:
组件生命周期的应用:
当我们想要获取DOM元素当中的标签时候,我们就要利用属性ref 和 this.$refs.属性名 结合 mounted方法来获取标签(其实created开始就能获取标签)!
不使用方法beforeCreat 、created、beforeMounted ,因为当我们想要获取标签,必须是渲染完之后,当我们渲染之前的创建和渲染前是无法拿到标签的。
看代码截屏:
注意:我们在制作网页的时候,先是把框架搞出来,然后再往其中放入数据,所以我们在制作过程当中,一般是将数据传输防止mounted当中,因为mounted 是渲染完后(也就是组件安装后)。
二十三、动态组件
动态的组件:就是可以实现组件之间的相互切换,让我们的组件实现切换。
这个时候,我们需要标签和 v-bind 的vue指令和 is 属性。
代码如下:
//APP.vue
//test1.vue 和 test3.vue 很简单
<template>
<component :is="initData"></component>
<button @click="changeData">切换组件</button>
</template>
<script>
import test1 from './components/test1.vue'
import test3 from './components/test3.vue'
export default{
data(){
return{
initData:"test1",
}
},
methods:{
changeData(){
this.initData = this.initData == "test1"? "test3" : "test1"
}
},
components:{
test1,
test3
}
}
</script>
组件销毁(unmounted):
当我们切换的组件的时候,其实就存在一个组件的挂载和销毁。
我们可以在下面的代码体现运行一下。
<template>
<p>组件一</p>
<p>{{ message }}</p>
<button @click="replaceData">更新数据</button>
</template>
<script>
import test2 from './test2.vue'
export default {
data(){
return{
message:"更新前"
}
},
components:{
test2,
},
methods:{
replaceData(){
this.message = "更新后";
}
},
beforeUnmount(){
console.log("卸载前");
},
unmounted(){
console.log("卸载后");
}
}
</script>
运行结果:
如果我们不想让组件卸载,那么我们就涉及到一个新的组件
这个时候,我们切换组件的时候,另一个组件不会卸载,而是保存下来,等待下一次使用!!!
我们需要这个组件将包裹
二十四、异步组件
异步组件作用:就是在我们加载项目的时候,需要的一开始就加载出来,不需要的先不网络请求,需要的时候,再进行网络请求,提高了网络性能!!!!
其实异步组件就是在 APP.vue 当中不是正常添加 一个组件,而是采用异步的方法添加一个组件:
第一步:
第二步:
二十五、依赖注入
在父组件向子组件传递数据的时候,利用props 传递数据,当层次嵌套的多的时候,我们如果利用props一层一层传递会非常的麻烦!
这个时候嵌套多的时候,我们就可以利用provide 和 inject 来进行 嵌套多的组件来进行传递了!
注意:provide 和 inject 的使用必须是从上向下传递.........
当我们使用props的时候:
代码案例:
//爷爷
<template>
<p>爷爷</p>
<test1 :title="message"/>
</template>
<script>
import test1 from './components/test1.vue'
export default {
components:{
test1
},
data(){
return{
message:"爷爷的财产"
}
}
}
</script>
//儿子
<template>
<p>父亲</p>
<test2 :title1="title"/>
</template>
<script>
import test2 from './test2.vue'
export default {
components:{
test2
},
data(){
return{
}
},
props:{
title:{
type:String
}
}
}
</script>
//孙子
<template>
<p>孙子</p>
<p>{{ title1 }}</p>
</template>
<script>
export default {
props:{
title1:{
type:String
}
}
}
</script>
运行结果:
当我们使用provide 和 inject:
//爷爷
<template>
<p>爷爷</p>
<test1 />
</template>
<script>
import test1 from './components/test1.vue'
export default {
components:{
test1
},
provide:{
message:"爷爷的财产"
}
}
</script>
//儿子
<template>
<p>父亲</p>
<test2/>
</template>
<script>
import test2 from './test2.vue'
export default {
components:{
test2
},
}
</script>
//孙子
<template>
<p>孙子</p>
<p>{{ message }}</p>
</template>
<script>
export default {
inject:["message"]
}
</script>
运行结果:
当我们provide 当中的数据不是写死的时候,而是来自data当中的数据的时候,我们就需要改变这个爷爷组件当中的provide格式就ok,其他组件不变,如下操作:
同时当子组件获取数据后也可以保存在自己的data数据当中:
当我们想要声明一个全局数据的时候,我们就可以在main.vue 当中设置,这样无论哪一个组件都可以利用 inject 使用这个全局变量!!!
第一步:
第二步:
运行结果:
二十六、Vue应用
Vue 这个前端框架其实就是从src 目录当中的 main.js组件当中开始运行的:
首先我们要在main.js当中创建一个对象app,我们通过这个对象引入我们的根组件APP.vue
我们的组件当中APP.vue 就是根组件,而components 当中放的就是子组件,我们把根组件引入到入口main.js 当中,把子组件引入到根组件当中,然后 通过 app.mount(' #app' ) 来渲染挂载到HTML当中运行。
其中的#app 其实就是index.htlm 这个文件当中的,如下:
为什么放在HTML当中呢?
我们都知道浏览器只能识别一些HTML,CSS,JS,wepack,vite等,而不能识别vue框架,所以我们需要将其中的内容全部放在index.html当中的div属性当中包裹起来,然后形成一个main.js 文件让浏览器运行。
assets文件的作用:保存一些你vue项目当中共享的图片,Css样式等等
二十七、Vue路由
Vue路由就是url hash(#号)与组件 的 关系
我们可以实现给不同的文字名称赋予超链接,而实现通过点击不同的文子名称实现组件的跳转!
在安装Vue项目过程当中如果你忘记在cmd命令当中yes,即可以之后下载插件:npm install vue-router@+匹配的版本号
1.配置路由:
2.路由请求:
3.更新:
看运行案例:
(基础完结)
没有讲解:自定义hook等内容。在watch的模块时,也没有讲到它的deep属性
这篇是我学习Vue过程当中的笔记,希望可以帮助更多人做好复习!可能有许多笔误!往大家多多指正!