第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件)

#课程目标

  1. 掌握vue实例的相关属性和方法的含义和使用
  2. 了解vue的数据响应原理
  3. 熟悉创建组件,了解全局组件与局部组件的区别,掌握组件的相关注意事项

#知识点

#1.vue实例的相关属性和方法ß

#1.1 属性

Vue实例就是通过new Vue()得到的对象。 我们可以在先在控制台中打印一下vue的实例,如图:

  • app.$data 对应组件中data的值
  • app.$props 对应组件中props的值
  • app.$el vue实例挂载到的节点
  • app.$options 用于当前 Vue 实例的初始化选项。需要在选项中包含自定义属性时会有用处
  • app.$parent 父实例,如果当前实例有的话。
  • app.$root 当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。
  • app.$children <item><div></div></item> item的$children就是div
  • app.$slots 用来访问被插槽分发的内容
  • app.$scopedSlots 用来访问作用域插槽
  • app.$refs 一个对象,持有注册过 ref 特性 的所有 DOM 元素和组件实例。(用于所有添加过ref属性的元素)
  • app.$isServer 当前 Vue 实例是否运行于服务器
  • app.$attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。
  • app.$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

在这里主要看这4个属性:

  • app.$el ===> vue实例挂载到的节点
  • app.$data ===> 对应组件中data的值
  • app.$options ===> 用于当前 Vue 实例的初始化选项。需要在选项中包含自定义属性时会有用处
  • app.$refs ===> 用于所有添加过ref属性的元素

app.$options方法实例:

var app = new Vue({
el: "#app",
data:{
msg:"hello vue!"
},
name:"xiaoming",
age:23,
showMe:function(){
console.log("自定义showMe方法");
}
})
console.log(app.$el); // 获得了el的dom对象
console.log(app.$data); // 获得了data对象
console.log(app.$options); // 获得了自定义的属性对象
console.log(app.$options.name); // 获得了自定义的name,值为:xiaoming
app.$options.showMe(); // 获取了自定义的show方法,并执行值为:自定义showMe方法
 

app.$refs方法实例:

<div id="app">
<div class="div1" ref="divDom"></div>
<p class="p1" ref="pDom"></p>
</div> var app = new Vue({
el: "#app",
data:{ }
})
console.log(app.$refs) // 获取到了所有带有 ref的dom标签
console.log(app.$refs.pDom) // 获取到了带有ref属性并且值为pDom的标签
console.log(app.$refs.divDom) // 获取到了带有ref属性并且值为divDom的标签 // 可以这样设置
app.$refs.pDom.style.color = "pink";
 
#1.2方法

而vue实例中的方法,可以展开__proto__对象,如图,可以看见:

其中,以下几个就是vue实例中的方法($emit,$on,$off,等等的方法之后课程再介绍):

  • app.$mount() 手动挂载vue实例
  • app.$destroy() 用于销毁vue实例
  • app.$nextTick(callback) 用于数据更改,dom更新完成后执行
  • app.set(object,key,value) 动态地为对象新增一个值,并且页面上的模版会实时地动态更新渲染值
  • app.$delete(object, key) 删除一个已有的属性,dom也会实时更新
  • app.$watch(data, callback(newValue,oldValue), [option]) 监视数据的变化

app.$mount()===>手动挂载vue实例 有两种写法分别为:

//第一种
var vm = new Vue({
// el: "#app", // 注释了挂载到dom对象
data:{
msg:"hello vue!"
}
})
vm.$mount("#app"); // 这样也可以挂载到dom对象
 
//第二种
var vm = new Vue({
// el: "#app", // 注释了挂载到dom对象
data:{
msg:"hello vue!"
}
}).$mount("#app"); // 在实例最后调用$mount("需要挂载的dom");
 

app.$nextTick(callback) ===> 用于数据更改,dom更新完成后执行

var vm = new Vue({
// el: "#app", // 注释了挂载到dom对象
data:{
msg:"hello vue!"
}
}).$mount("#app"); vm.msg = "hello world!"; // 这里更改了数据 // 这里获取DOM的内容为:hello vue!,因为dom数据还没更新完成
console.log(vm.$refs.pDom.innerHTML); // 这里获取DOM的内容为:hello world!,因为dom数据已经更新完成
vm.$nextTick(function(){
console.log(vm.$refs.pDom.innerHTML);
});
 

app.set(object,key,value) 实例用法

<div class="box" id="app">
<button @click="addFn">添加一个属性</button>
{{user.name}}
{{user.num}}
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
user:{
name:"yang"
}
},
methods:{
addFn:function(){
//this.user.num = "9527"; // 页面上的模版无法渲染
//console.log(this.user); // 能打印出来,但是也页面上的模版未渲染出来
// this.$set(this.user, "num", "9527"); // 页面上的模版渲染出来了值
Vue.set(this.user, "num", "9527") //vm.$set 的全局写法
}
}
})
</script>
 

app.$delete 实例用法

<div class="box" id="app">
<button @click="deleteFn">删除一个属性</button>
{{user.name}}
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
user:{
name:"yang"
}
},
methods:{
deleteFn: function(){
// vm.$delete(this.user, "name"); // 删除页面上已有的一个属性,dom也会实时更新
Vue.delete(this.user, "name"); // vm.$delete 全局写法
}
}
})
</script>
 

vm.$watch(data, callback(newValue,oldValue), [option]) 实例用法

<input type="text" v-model="msg">   // 绑定 vm.$watch 写法1
{{msg}} <input type="text" v-model="id"> // 绑定 watch 写法2
{{id}} <input type="text" v-model="user.name"> // 绑定 watch 写法2
{{user.name}} var vm = new Vue({
el:"#app",
data:{
msg:"hello vue!",
id:"1001",
user:{
name:"yang"
}
},
/* watch:{ // 写法2:vue实例提供的一个选项 - 普通监视数据变化
id:function(newValue, oldValue){
console.log("id更改之后的值"+ newValue +",id更改之前的值"+ oldValue);
}
} */
watch:{ // 写法2:vue实例提供的一个选项 - 深度监视对象数据变化
user:{
handler:function(newValue, oldValue){
console.log("user更改之后的值"+ newValue +",user更改之前的值"+ oldValue);
},
deep: true
}
}
}) // 写法1:vue实例提供的$watch方法 - 普通监视数据变化
vm.$watch("msg",function(newValue, oldValue){
console.log("msg更改之后的值"+ newValue +",msg更改之前的值"+ oldValue);
}) // 写法1:vue实例提供的$watch方法 - 深度监视对象数据变化
vm.$watch("user",function(newValue, oldValue){
// 监视一个对象后,这里的newValue 和 oldValue将会指向同一指针,也就是指向了同一个值,更改前后值会一样
console.log("user更改之后的值"+ newValue +",user更改之前的值"+ oldValue);
},{
deep:true
})
 

#2.数据响应原理

现代主流框架均使用一种数据=>视图的方式,封装了繁琐的dom操作,采用了声明式编程(Declarative Programming)替代了过去的类jquery的命令式编程(Imperative Programming)。

这张图来自vue的官方文档,文档中讲:

当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。

这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

总结为需要三个模块实现数据响应:

  • Observer:也就是vue官方文档第一段提到的使用Object.defineProperty监听数据变化,数据变化则触发setter,并通知订阅者Watcher。
  • Watcher:作为Observer和Compile之间通信的桥梁,在自身实例化时往属性订阅器(dep)里面添加自己,待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调。
  • Compile: 主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。

#3.vue 中的组件

#3.1 组件的基本使用

注册组件就是利用Vue.component()方法,先传入一个自定义组件的名字,然后传入这个组件的配置。这种方式创建的组件也叫做全局组件。

Vue.component('mycomponent',{
template: `<div>这是一个自定义全局组件</div>`,
data () {
return {
message: 'hello world'
}
}
})
 

如上方式,就已经创建了一个自定义组件,然后就可以在Vue实例挂在的DOM元素中使用它。

直接使用Vue.component()创建的组件,所有的Vue实例都可以使用。还可以在某个Vue实例中注册只有自己能使用的组件。也叫做局部组件。

var app = new Vue({
el: '#app',
data: {
},
components: {
'my-component': {
template: `<div>这是一个局部的自定义组件,只能在当前Vue实例中使用</div>`,
}
}
})
 

具体对比实例:

<div id="app1">
<!—全局组件的使用-->
<mycomponent></mycomponent>
<!—局部组件的使用-->
<my-component></my-component>
</div>
<div id="app2">
<!—全局组件的使用-->
<mycomponent></mycomponent>
<!—局部组件的使用 此处的使用会报错-->
<my-component></my-component>
</div>
<script>
//定义全局组件 每个Vue实例中都能使用
Vue.component('mycomponent',{
template: `<div>这是一个自定义全局组件</div>`,
data () {
return {
message: 'hello world'
}
}
})
var app1 = new Vue({
el: '#app1',
data: {
},
components: {
'my-component': {
template: `<div>这是一个局部的自定义组件,只能在当前Vue实例中使用</div>`,
}
}
})
var app2 = new Vue({
el: '#app2',
data: {
}
})
</script>
 
#3.2 template模板的要求

注意:组件的模板只能有一个根元素。下面的情况是不允许的。

template: `<div>这是一个局部的自定义组件,只能在当前Vue实例中使用</div>
<button>hello</button>`,
 
#3.3 组件中的data必须是函数

可以看出,注册组件时传入的配置和创建Vue实例差不多,但也有不同,其中一个就是data属性必须是一个函数。

这是因为如果像Vue实例那样,传入一个对象,由于JS中对象类型的变量实际上保存的是对象的引用,所以当存在多个这样的组件时,会共享数据,导致一个组件中数据的改变会引起其他组件数据的改变。

而使用一个返回对象的函数,每次使用组件都会创建一个新的对象,这样就不会出现共享数据的问题来了。

#3.4 关于DOM模板的解析

当使用 DOM 作为模版时 (例如,将 el 选项挂载到一个已存在的元素上), 你会受到 HTML 的一些限制,因为 Vue 只有在浏览器解析和标准化 HTML 后才能获取模板内容。尤其像这些元素<ul>,<ol>,<table>,<select>限制了能被它包裹的元素,而一些像 <option> 这样的元素只能出现在某些其它元素内部。

通俗点说,虽然 vue 渲染页面可以自定义,非常强大,但是他一定遵从遵循我们的浏览器正常解析,html 正常规范。

在自定义组件中使用这些受限制的元素时会导致一些问题,例如:

<table>
<my-row>...</my-row>
</table>
 

自定义组件 被认为是无效的内容,因此在渲染的时候会导致错误。

这时应使用特殊的 is 属性:

<table>
<tr is="my-row"></tr>
</table>
 

又或者是select这样的:

<select>
<my-component></my-component>
</select>
 

select 内置固定标签 option, 所以不能随意渲染

也就是说,标准HTML中,一些元素中只能放置特定的子元素,另一些元素只能存在于特定的父元素中。比如table中不能放置div,tr的父元素不能div等。所以,当使用自定义标签时,标签名还是那些标签的名字,但是可以在标签的is属性中填写自定义组件的名字。

#4.属性Props

Vue组件通过props属性来声明一个自己的属性,然后父组件就可以往里面传递数据。

Vue.component('mycomponent',{
template: '<div>这是一个自定义组件,父组件传给我的内容是:{{myMessage}}</div>',
props: ['myMessage'],
data () {
return {
message: 'hello world'
}
}
})
 

然后调用该组件

<div id="app">
<mycomponent my-message="hello"></mycomponent>
</div>
 

注意,由于HTML特性是不区分大小写的,所以传递属性值时,myMessage应该转换成 kebab-case (短横线隔开式)my-message="hello"。

#授课思路

#案例和作业

使用vue完成一个tab切换

vue第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件)的更多相关文章

  1. 理解Python中的类对象、实例对象、属性、方法

    class Animal(object): # 类对象 age = 0 # 公有类属性 __like = None # 私有类属性 def __init__(self): # 魔法方法 self.na ...

  2. vue第十六单元(element-ui vue-lazyload 等常用插件)

    第十六单元(element-ui vue-lazyload 等常用插件) #课程目标 1.掌握插件的引入方式 2.精通UI框架 3.掌握前端常见的几种效果实现 #知识点 一.elementUI的使用 ...

  3. day 87 Vue学习六之axios、vuex、脚手架中组件传值

      本节目录 一 axios的使用 二 vuex的使用 三 组件传值 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 axios的使用 Axios 是一个基于 promise 的 HT ...

  4. Vue系列(二):发送Ajax、JSONP请求、Vue生命周期及实例属性和方法、自定义指令与过渡

    上一篇:Vue系列(一):简介.起步.常用指令.事件和属性.模板.过滤器 一. 发送AJAX请求 1. 简介 vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 ...

  5. day 84 Vue学习六之axios、vuex、脚手架中组件传值

    Vue学习六之axios.vuex.脚手架中组件传值   本节目录 一 axios的使用 二 vuex的使用 三 组件传值 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 axios的 ...

  6. vue第十单元(动态组件 keep-alive(钩子函数) 递归组件(name) 组件命名约定)

    第十单元(动态组件 keep-alive(钩子函数) 递归组件(name) 组件命名约定) #课程目标 熟练掌握动态组件的实现 掌握keep-alive缓存组件,以及相应的钩子函数 熟练掌握递归组件, ...

  7. vue第八单元(组件通信 子父,父子组件通信 自定义事件 事件修饰符 v-model props验证 )

    第八单元(组件通信 子父,父子组件通信 自定义事件 事件修饰符 v-model props验证 ) #课程目标 掌握使用props让父组件给子组件传参(重点) 掌握props属性的使用以及prop验证 ...

  8. vue第七单元(vue的单文件组件形式-单文件组件的加载原理-vue-cli构建的开发环境以及生命周期)

    第七单元(vue的单文件组件形式-单文件组件的加载原理-vue-cli构建的开发环境以及生命周期) #课程目标 掌握安装 vue-cli 命令行工具的方法,掌握使用命令行在本地搭建开发环境,使用命令行 ...

  9. vue第四单元(初识vue-在页面中直接引入vue框架-学习使用vue语法-vue的指令-介绍data用法-methods用法)

    第四单元(初识vue-在页面中直接引入vue框架-学习使用vue语法-vue的指令-介绍data用法-methods用法) #课程目标 了解 vue 框架的特点 掌握创建 vue 实例 掌握 data ...

随机推荐

  1. 关于steam平台“wallpaper engine”软件出现界面黑屏,但壁纸能播放的问题

    前阵子重装电脑后,在使用wallpaper engine这款软件时发现了以下令人疑惑的画面: 点击"设置"和"壁纸选择"界面全是黑的......这还没完,更气人 ...

  2. MathType输入矩阵和行列式的技巧

    高等代数里,经常要使用到矩阵和行列式,尤其是在写论文时,如何编辑矩阵和行列式呢?比较好的方法就是使用专业的公式编辑器MathType进行编辑,下面就一起来学习具体的编辑技巧. 具体步骤如下: 步骤一 ...

  3. 如何用思维导图软件MindManager制作项目管理图表

    项目管理的官方解释为:运用各种相关技能.方法与工具,为满足或超越项目有关各方对项目的要求与期望,所开展的各种计划.组织.领导.控制等方面的活动. 其实使用MindManager思维导图软件来创建项目管 ...

  4. 文档丢失不用怕,EasyRecovery帮你一键恢复

    我们在使用电脑的过程中,有时会因为各种原因,导致我们所写的文档丢失了.遇到这种情况,该怎么办呢? 下面,就给大家分享一下用EasyRecovery如何恢复被丢失的文档. 1.双击进入EasyRecov ...

  5. 苹果电脑怎么给浏览器安装Folx扩展程序

    Folx是一款MacOS专用的老牌综合下载管理软件,它的软件界面简洁,应用简单方便,下载管理及软件设置灵活而强大.Folx不但能够进行页面链接下载.Youtube视频下载,而且还是专业的BT下载工具. ...

  6. vue集成高德地图

    vue集成高德地图 前言 二.使用步骤 1.注册高德开发平台 2.vue 结尾 前言 之前玩Thymeleaf的时候玩过高德地图,现在无聊Vue项目也整个地图进去~ 二.使用步骤 1.注册高德开发平台 ...

  7. 方格取数(number) 题解(dp)

    题目链接 题目大意 给你n*m个方格,每个格子有对应的值 你从(1,1)出发到(n,m)每次只能往下往上往右,走过的点则不能走 求一条路线使得走过的路径的权值和最大 题目思路 如果只是简单的往下和往右 ...

  8. 什么是SSL双向认证,与单向认证证书有什么区别?

    SSL/TLS证书是用于用户浏览器和网站服务器之间的数据传输加密,实现互联网传输安全保护,大多数情况下指的是服务器证书.服务器证书是用于向浏览器客户端验证服务器,这种是属于单向认证的SSL证书.但是, ...

  9. ES6简单理解基本使用

    let const 原来的var声明标识符:可以重复声明,编译不报错. let,const声明标识符:不能重复声明,再声明编译报错. var声明的标识符作用域是当前函数,let和const是当前{块} ...

  10. PyQt(Python+Qt)学习随笔:QListView的itemAlignment属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QListView的itemAlignment属性用于控制每个数据项的对齐方式,其类型为枚举类Qt. ...