VUE深度解析

丈夫欲遂平生志,一载寒窗一举汤。这篇文章主要讲述VUE深度解析相关的知识,希望能为你提供帮助。
VUE深度解析ES6语法-var-const-let用法详解javascript作用域

javascript只有函数作用域,没有块级作用域。即在??dunction??里面定义的变量是有作用域的,if、for等代码块定义的变量是没有作用域的。
< !DOCTYPE html>
< html lang="en">

< head>
< meta charset="UTF-8">
< meta name="viewport" content="width=device-width, initial-scale=1.0">
< meta http-equiv="X-UA-Compatible" content="ie=edge">
< title> ES6语法-var-const-let用法详解< /title>
< /head>

< body>
< div id="app">
< button> 测试1< /button>
< button> 测试2< /button>
< button> 测试3< /button>
< /div>
< script>
//作用域代码
if(true)
//externalVal没有作用域
var externalVal = "externalVal";

function domainTest()
var funVal ="funVal";
//这里可以访问到externalVal和funVal
console.log(externalVal + "----" + funVal);

domainTest()
if(true)
console.log(externalVal); //可以访问到externalVal
//console.log(funVal); 这一行访问不到变量,报错


//使用var定义变量的局限性
var btns = document.getElementsByTagName(button)
for(let i = 0; i < btns.length; i++)
btns[i].onclick = function()
alert("点击了第" + (i+1) + "个按钮");


< /script>
< /body>
< /html>

VUE深度解析

文章图片

var局限性
在上面代码中添加三个button,然后定义监听
VUE深度解析

文章图片

然后测试结果如下:
VUE深度解析

文章图片

为什么会一直出现的是3呢?这是因为作用域,for代码块没有作用域,当循环for结束的时候,监听的i是几?肯定是3,那么当我们点击按钮的时候i就是3。所以打印出来的就是"点击了第三个按钮"
let用法
var作用域在js中存在的缺陷,在ES6版主中,使用新的定义变量let就可以解决。
//使用var定义变量的局限性
var btns = document.getElementsByTagName(button)
for(let i = 0; i < btns.length; i++)
btns[i].onclick = function()
alert("点击了第" + (i+1) + "个按钮");


结果如下:
VUE深度解析

文章图片

点击第1个按钮,打印“点击了第3个按钮”的情况就不会再出现。因为let定义的变量自带块级作用域。
const用法
当我们希望定义的变量不要被二次赋值的时候(也就是常量),使用const关键字来定义。
const c = 80;
c = 100;//报错
const c; //报错,常量定义的时候必须赋值

ES6语法-对象的增强写法ES5对象定义语法
function Player(name,age)//定义对象
this.name = name;
this.age = age;

//定义对象的成员函数
Player.prototype.toPrint = function()
alert(this.name + "---" + this.age)

var player1 = new Player("james",35);
var player2 = new Player("kobe",39);
player1.toPrint()//james---35调用函数方法
player2.toPrint()//kobe---39

结果如下:
VUE深度解析

文章图片

ES5中对象最令人觉得繁琐的就是构造函数、prototyp、依靠原型链实现继承。因为它使用的不是面向对象的语法,所以使用过程比较混乱。下面我们结束如何使用简介的ES6语法定义对象和继承的增强语法。
ES6定义对象语法
ES6语法中,js引入了传统的面向对象编程语法(和java相似)。新的写法比较符合面向对象思想,也比较容易理解。
//class定义对象
class Player
//constructor定义构造函数
constructor(name,age)
console.log(name + fdasfada + age)
this.name = name;
this.age = age;

//定义方法
toPrint()
console.log(this.name + "---" + this.age)


//使用对象
let player1 = new Player("james",35);
//使用对象方法
player1.toPrint()//james---35

  • 引入class关键字,用于定义对象
  • 构造函数方法名称固定,就叫做constructor。
  • 在对象定义类中,this关键字代表当前实例对象
class BestPlayer extends Player
constructor()
super()
this.name = "jordan"
this.age = 49


let bestPlayer = new BestPlayer();
bestPlayer.toPrint()//jordan---49

  • 通过class关键字实现了类的继承
  • 通过super()关键字调用父类构造函数,如果不传参数,默认是undefined
  • super()方法必须显示调用,否则子类找不到this指针。
ES6定义对象简写
let name = "curry"
let age = 33
let player3 =
name :name,
age : age,
toPrint:function()
console.log(player3) //name: "curry", age: 33


player3.toPrint() //name: "curry", age: 33, toPrint: ?

ES6语法-箭头函数与this指针箭头函数简写形式
VUE深度解析

文章图片

可以发现,箭头函数方法写的很简单,箭头左侧定义参数,右侧定义函数体。
对象中this指针
//class 定义对象
class Player
//constructor 定义构造函数
constructor(nickname,age)
this.nickname = nickname;
this.age = age;

//定义成员方法
toPrint()
console.log(this.nickname + "---" + this.age)


在对象中,this指针指向的就是对象本身。可以this可以引用对象的属性和方法。
VUE组件化
graph LR
调用Vue.extend定义组件 --> 调用Vue.component组测组件 --> 在vue实例试图范围内使用组件

< !DOCTYPE html>
< html lang="en">

< head>
< meta charset="UTF-8">
< meta name="viewport" content="width=device-width, initial-scale=1.0">
< meta http-equiv="X-UA-Compatible" content="ie=edge">
< title> 嵌套组件< /title>
< /head>

< body>
< div>
< div id="app" style="background-color: aqua; ">
< first-component> < /first-component>
< /div>
< div id="app2" style="background-color: aquamarine; ">
< second-component> < /second-component>
< /div>
< div id="app3" style="background-color: blue; ">
< third-component> < /third-component>
< /div>

< !--父子组件的嵌套-->
< template id="child">
< p style="font-size: larger; "> 子组件< /p>
< /template>
< template id="parent">
< div>
< h2> 父组件 template< /h2>
< child> < /child>
< child> < /child>
< /div>
< /template>
< div id="app4" style="background-color: brown; ">
< parent> < /parent>
< /div>
< /div>
< !--从CDN引入vue.js-->
< script src="http://img.readke.com/220421/11134RG0-6.jpg"> < /script>
< script>

const firstComponent= Vue.extend(
template:`
< div>
< span> template用于定义组件试图< /span>
< h3> 测试组件< /h3>
< h2> 测试组件内容< /h2>
< /div>
`
);
//组测组件
Vue.component("firstComponent",firstComponent);

var app = new Vue(
el: #app
);
< /script>
< script>
var app2 = new Vue(
el: #app4,
components:
parent:
template: #parent,
components:
child: template: #child,



);
< /script>
< script>
//组测组件
Vue.component("secondComponent",
template:`
< div>
< span> template用于定义组件二合一试图< /span>
< h3> 测试组件二合一< /h3>
< h2> 测试组件二合一内容< /h2>
< /div>
`
);

var app = new Vue(
el: #app2,
data: function()
return count: 0
,
methods:
incr()
this.count ++

,
);
< /script>

< script>
var app = new Vue(
el: #app3,
components:
thirdComponent:
template:`
< div>
< span> template用于定义私有组件试图< /span>
< h3> 测试私有组件< /h3>
< h2> 测试私有组件内容2< /h2>
< /div>
`


);
< /script>
< /body>
< /html>

VUE深度解析

文章图片

  • 全局组件要先定义vue.extend(),在注册vue.component(),任何再使用。
  • ??template??用于定义组件视图
  • 如果用new VUE()定义多个vue实例,全局组件可以跨多个实例使用
  • 通常组件定义的名称为首字母大写,驼峰标志。如:firstComponent
  • 在dom中使用组件,通常遵循使用“-”分隔单词,小写规范。如:first-component
最终结果如下:
VUE深度解析

文章图片

全局组件简写
使用Vue.component()方法 + template组件视图层模板一步完成全局组件的定义与注册
//组测组件
Vue.component("secondComponent",
template:`
< div>
< span> template用于定义组件二合一试图< /span>
< h3> 测试组件二合一< /h3>
< h2> 测试组件二合一内容< /h2>
< /div>
`
);

局部私有组件
局部私有组件和全局组件的区别在于,私有组件只能在定义它的实例或者父组件里面使用。如下:定义的组件thirdComponent只能在??< div id="app3"> ??里面使用,其他vue实例无法使用该组件。
< script>
var app = new Vue(
el: #app3,
components:
thirdComponent:
template:`
< div>
< span> template用于定义私有组件试图< /span>
< h3> 测试私有组件< /h3>
< h2> 测试私有组件内容2< /h2>
< /div>
`


);
< /script>

父子组件嵌套
< !--父子组件的嵌套-->
< template id="child">
< p style="font-size: larger; "> 子组件< /p>
< /template>
< template id="parent">
< div>
< h2> 父组件 template< /h2>
< child> < /child>
< child> < /child>
< /div>
< /template>
< div id="app4" style="background-color: brown; ">
< parent> < /parent>
< /div>

一个父组件Parent里面包含两个子组件Child,并将父组件放在app2实例页面渲染范围内。下文中是使用私有局部组件的方式定义的。也就是Parent组件是app2实例的私有局部组件,Child是Parent组件的私有局部组件。
< script>
var app4 = new Vue(
el: #app4,
components:
parent:
template: #parent,
components:
child: template: #child,



);
< /script>

结果如下:
VUE深度解析

文章图片

父子组件间数据定义和访问
< !DOCTYPE html>
< html lang="en">

< head>
< meta charset="UTF-8">
< meta name="viewport" content="width=device-width, initial-scale=1.0">
< meta http-equiv="X-UA-Compatible" content="ie=edge">
< title> 父子组件间数据定义和访问< /title>
< /head>

< body>
< div>
< template id="secondComponent">
< div>
< span> count< /span> < br>
< button @click="incr"> +< /button>
< /div>
< /template>
< div id="app2" style="background-color:burlywood; ">
< h2> secondComponent< /h2> < br>
< second-component> < /second-component>
< /div>
< /div>
< !--从CDN引入vue.js-->
< script src="http://img.readke.com/220421/11134RG0-6.jpg"> < /script>
< script>

var app = new Vue(
el: #app2,
components:
secondComponent:
template:#secondComponent,
data:function()
return count:0
,
methods:
incr()
this.count++;





);
< /script>
< /body>
< /html>

  • ??secondComponent??组件有自己的视图模板template#secondComponent
  • ??secondComponent??组件有自己的数据定义,data()函数。这里定义的是一个函数,而不是对象,通过函数返回对象数据。
  • ??secondComponent??组件有自己的操作方法,定义在methods代码块中
父子组件的数据访问
< !DOCTYPE html>
< html lang="en">

< head>
< meta charset="UTF-8">
< meta name="viewport" content="width=device-width, initial-scale=1.0">
< meta http-equiv="X-UA-Compatible" content="ie=edge">
< title> 父子组件的数据定义与访问< /title>
< /head>
< body>
< div>
< !--父子组件的嵌套-->
< !-- < template id="Child">
< div>
< p> childMessage< /p>
< input type="text" v-model="childMessage"> < br>
< button @click="parentInfo()"> 打印父组件信息< /button>
< /div>
< /template> -->


< template id="Child">
< div style="background-color: brown; ">
< p> childMsg< /p>
< input type="text" v-model="childMsg"> < br>
< button @click="parentInfo()"> 调用父组件信息< /button>
< h2> txt< /h2>
< /div>
< /template>
< template id="Parent">
< div>
< p> parentMsg< /p>
< input type="text" v-model="parentMsg"> < br>
< button @click="childInfo()"> 打印子组件信息< /button>
< child ref="childRef"> < /child>
< h2> msgL< /h2>
< !-- < child> < /child> -->
< /div>
< /template>
< div id="app">
< parent> < /parent>
< /div>
< /div>
< !--从CDN引入vue.js-->
< script src="https://www.songbingjia.com/android/vue.min.js"> < /script>
< script>
var app2 = new Vue(
el: #app,
components:
Parent:
template: #Parent,
data: function()
return
parentMsg: "父组件的数据",
msgL:""

,
methods:
childInfo()
//console.log(this.$children[0].childMsg)
this.msgL="msgL: "+this.$children[0].childMsg
//console.log(this.$refs.childRef.childMsg)

,
components:
Child:
template: #Child,
data: function()
return
childMsg: "我是子组件的数据",
txt:""

,
methods:
parentInfo()
this.txt="txt: "+this.$parent.parentMsg
//console.log(this.$parent.parentMsg)






);
< /script>
< /body>

< /html>

父组件是没有办法直接访问子组件的数据的,子组件也没有办法直接使用父组件的数据,那么就出现了
、children、$ref
VUE深度解析

文章图片

我们希望在子组件中使用this.打印父组件信息,在父组件中调用children[0]打印子组件信息
VUE深度解析

文章图片

上面的方法中,父组件使用this.$children[0]来获取多个子组件的数据。如果我们希望快速的,从父组件获取子组件的数据,还可以为子组件加上一个属性ref。相当于为子组件起了一个别名,便于查找。
VUE深度解析

文章图片

然后父组件通过如下代码即可打印子组件的属性数据:
console.log(this.$refs.childRef.childMsg)

使用props父组件向子组件传递数据
< !DOCTYPE html>
< html lang="en">

< head>
< meta charset="UTF-8">
< meta name="viewport" content="width=device-width, initial-scale=1.0">
< meta http-equiv="X-UA-Compatible" content="ie=edge">
< title> 使用props父组件向子组件传递数据< /title>
< /head>
< body>
< div id="app">
< child :child-msg="msg" :child-ary="ary"> < /child>
< example :prop-a="propA" :prop-c="propC"> < /example>
< /div>
< template id="child">
< div>
< h2> childMsg< /h2>
< h2> childAry< /h2>
< /div>
< /template>
< template id="example">
< div>
< span> "propA"< /span> < h2> propA< /h2> < br>
< span> "propC"< /span> < h2> propC< /h2> < br>
< span> "propD"< /span> < h2> propD< /h2> < br>
< span> "propE"< /span> < h2> propE< /h2> < br>
< /div>
< /template>
< script src="http://img.readke.com/220421/11134RG0-6.jpg"> < /script>
< script>
const child =
template: #child,
props: [childMsg,childAry]

const example =
template: #example,
props:
propA:type: Number,
propC:
type: String,
required: true
,
propD:
type: Number,
default: 100
,
propE:
type: Object,
default: function ()
returnmessage: hello




const app = new Vue(
el: #app,
data:
ary:
name: 张三,age: 39,sex:"男"
,
msg: 父组件数据-> 子组件,
propA:10,
propC:"propC",
propD:40,
propF:5
,
components:
child,
example

)
< /script>
< /body>
< /html>

VUE深度解析

文章图片

  • 父实例将自己数据msg,传递给child
  • 子组件通过绑定属性child-msg绑定父组件数据msg
  • 子组件标签属性child-msg对应子组件模型定义属性props:childMsg
  • childMsg属性可以使用插值表达式,显示template模板里面
props数据
通常我们定义一个组件是应该可以提供给其他模块或其他人使用的。使用者可能对该组件的用法并不熟悉,可能会导致错误。所以有必要在子组件内,对父组件传递过来数据进行校验。
VUE深度解析

文章图片

子组件向父组件传播事件 父组件可以通过和ref的方式获取子组件的数据。但是在实际开发过程中,还有另外一种需求,即:子组件中发生了某些动作,从而改变了子组件的数据。那么父组件如何实时的监听到子组件数据的变化呢?那就是我们这一小节需要讲的核心内容
  • 在子组件使用$emit(‘事件名称’,参数),触发并发送事件,并且可以通过参数传值
methods:
incr()
this.count++
this.$emit(increment,this.count)
,
decr()
this.count--
this.$emit(decrement,this.count)


  • 在父组件中嵌入子组件,并使用v-on指令(简写为@)监听事件,从而触发回调函数,回调函数接受子组件发送的参数。图中changePcounter就是针对increment事件和decrment事件监听的回调函数
< div id="app">
< child-cpn @increment="changePCounter" @decrement="changePCounter"> < /child-cpn>
< h2> PCounter: pCounter< /h2>
< /div>

  • 父组件定义回调函数接收实践触发源传递的参数,即$emit的第二个参数
changePCounter(counter)
this.pCounter = counter

整体需求的实现
子组件与视图的定义。子组件点击加一按钮触发incr函数,incr函数触发increment事件,并将当前cCounter作为事件参数传递出去。父组件范围监听到increment事件,从而触发changePCounter方法,该方法接受cCounter作为参数。
VUE深度解析

文章图片

父组件的定义
VUE深度解析

文章图片

如果您觉得本文不错,欢迎关注,点赞,收藏支持,您的关注是我坚持的动力!
原创不易,转载请注明出处,感谢支持!如果本文对您有用,欢迎转发分享!
【VUE深度解析】


    推荐阅读