《Vue.js基础与应用开发实战(微课版) 单元5教案.docx》由会员分享,可在线阅读,更多相关《Vue.js基础与应用开发实战(微课版) 单元5教案.docx(38页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Vue. js基础与应用开发实战(微课版)配套教学教案单元5课时内容Vue组件构建与应用授课时间课时8教学目标 掌握组件基础 掌握组件注册与使用 掌握组件构建 掌握Vue组件选项props 认知组件之间的通信 熟悉Vue自定义事件 掌握Vuc组件动态切换 掌握Vue插槽应用 熟悉Vue混合 能在自定义组件中利用Vue的transition属性实现图片轮换功能,在ElementUI中实现Table与Pagination组件化教学重点组件构建教学难点组件应用教学设计1 .教学思路:通过实例介绍Vue组件构建与应用。2 .教学手段:多媒体展示+软件操作。教学内容5.1 组件基础在Vue里,一个组件本
2、质上是一个拥有预定义选项的Vue实例,主要以页面结构的形式存在。不同的组 件之间具有基本交互功能,可以根据业务逻辑实现较复杂的项目功能。一个组件是一个自定义元素,也可以称 为一个模块,其中包括所需的模板、逻辑和样式。在HTML模板中,组件以一个自定义标签的形式存在,起到 占位符的作用。通过Vue的声明式渲染后,占位符将会被替换为实际的内容。5.1.1 初识组件定义组件是可复用的Vue实例,它有一个名称,以下是一个简单的组件实例。【实例5-1】定义与使用一个名称为button-counter的组件【操作要求】定义一个名称为button-counter的组件,该组件的主要功能是记录与输出单击按钮的
3、次数。【实现过程】使用HTML编辑器Dreamweaver创建网页0501.html ,实现要求的功能。(1 )定义一名为button-counter的组件var app = new Vue(el: *#app)4.使用组件5.3.2 使用template标签构建组件模板代码通常写在HTML结构中,这样可以改善开发体验,提高开发效率。Vue提供了template标签来 定义结构的模板,可以在该标签中书写HTML代码,然后通过id值绑定到template属性上。使用template标签构建组件,需要在template标签上增加id属性,用于以后的组件注册。【示例】demo050302.html代
4、码如下:欢迎登录II创建根实例var vm=new Vue(el: #app,components: app-component: template: #content)5.3.3 使用script标签构建组件使用script标签构建组件时,同样需要增加id属性,同时还得增加type=texVx-template,这是为了告诉 浏览器不执行编译里面的代码。对于以下自定义组件app-component :局部注册组件app-component的示例代码如下。【示例】demo050303.html代码如下:欢迎登录var vm=new Vue(el: app,components: app-com
5、ponent: template: #content)全局注册组件app-component的示例代码如下:欢迎登录Vponent(app-component, template: #content)上面的代码等价于:VponentCapp-component, template:、欢迎登录)【实例5-2】演练实现组件树的效果【操作要求】使用components选项注册组件,实现组件树的效果。HTML将被渲染为: 标题 正文内容对于大型应用来说,有必要将整个应用程序划分为组件,以使开发可管理。一般的组件应用模板如下:5.3.4 构建父子组件1 .使用全局注册方式构建父子组件【示例】demo05
6、0304.html使用全局注册方式构建父子组件的过程如下。(1 )构建子组件代码如下:构建子组件childvar childNode = Vue.extend(template: 这是子组件)注册名为child的组件Vponent(child,childNode)(2)构建父组件代码如下:构建父组件parent ,在其中嵌套child组件var parentNode = Vue.extend(template: 这是父组件)Vponent(parent,parentNode);(3 )定义Vue实例代码如下:var vm=new Vue(el: #app)(4)使用父组件代码如下:2 .使用局
7、部注册方式构建父子组件【示例】demo050305.html使用局部注册方式构建父子组件的过程如下。(1 )构建子组件代码如下:var childNode = Vue.extend(template: 这是子组件v/div)(2)构建父组件代码如下:在父组件中局部注册子组件var parentNode = Vue.extend(template: 这是父组件,components:child:childNode)(3 )定义Vue实例代码如下:在Vue实例中局部注册父组件var vm=new Vue(el: #app,components: parent: parentNode)(4)使用父组
8、件代码如下:5.4 Vue组件选项props组件接受的选项大部分与Vue实例一样,而组件选项props是组件中非常重要的一个选项。在Vue中, 父子组件的关系可以总结为props down和events upo父组件通过props向下传递数据给子组件,子组件通 过events给父组件发送消息。父子组件之间数据传递的示意图如图所示。父子组件之间数据传递的示意图5.4.1 父子组件在一个优秀的接口中尽可能将父子组件解耦是很重要的,这保证了每个组件可以在相对隔离的环境中书写 和理解,也大幅提高了组件的可维护性和可重用性。下面介绍两种父子组件的错误写法。以下这种形式的写法是错误的,因为当子组件注册到父
9、组件时,Vue会编译好父组件的模板,模板的内容已经决定了父组件将要渲染的HTML :parent/parent运行时,它的一些子标签只会被当作普通的HTML来执行,不是标准 的HTML标签,会被浏览器直接忽视。在父组件标签之外使用子组件也是错误的:正确写法如下。【示例】demo050401.html略HTML将被渲染为:这是子组件v/div5.4.2 静态 props组件实例的作用域是孤立的,这意味着不能(也不应该)在子组件的模板内直接引用父组件的数据。要让 子组件使用父组件的数据,需要通过子组件的props选项实现。使用props传递数据包括静态和动态两种形式,本小节先介绍静态propso子
10、组件要显式地用props选项声明它期待获得的数据。例如:var childNode = template: para propsiCpara静态props通过为子组件在父组件中的占位符添加特性的方式来达到传值的目的。【示例】demo050402.html略HTML将被渲染为:abc1235.4.3 组件命名约定HTML中的属性名是对大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当使用 DOM中的模板时,采用驼峰命名法的props名需要使用其等价的短横线分隔命名法命名。例如:Vponent(blog-post, II在JavaScript中是驼峰命名法的写法props: fp
11、ostTitle,template: postTitle )!-在HTML中是短横线分隔命名的写法一如果使用字符串模板,那么这个限制就不存在了。对于props声明的属性来说,在父级HTML模板中,属性名需要使用短横线分隔写法。例如:var parentNode = template:,components: child: childNode);子级props属性声明时,使用小驼峰写法(除第一个单词外其余单词首字母大写)或者短横线分隔写法都 可以;子级模板使用从父级传来的变量时,需要使用对应的小驼峰写法。例如:var childNode = template: appPara ,propsifa
12、ppPara)var childNode = template: appPara ,propsifapp-para)5.4.4 动态 props在模板中动态地绑定父组件的数据到子模板的props的方式,与绑定到任何普通的HTML特性的方式类 似,都是用v-bind指令。每当父组件的数据变化时,该变化也会传导给子组件。【示例】demo050403.html略HTML将被渲染为:abc1235.4.5 传递数字以下示例使用字面量语法传递数值。【示例】demo050404.html略HTML将被渲染为:123 的数据类型是 string因为它是一个字面props ,它的值是字符串123,而不是num
13、ber类型的数据。如果想传递一个实际的 number类型的数据,需要使用v-bind指令,从而让它的值被当作JavaScript表达式计算。【示例】demo050405.html略HTML将被渲染为:123 的数据类型是 number或者可以使用动态props ,在data属性中设置对应的数字1230【示例】demo050406.html略HTML将被渲染为:123的数据类型是number的数据类型是undefined的数据类型是undefined456的数据类型是string5.4.6 props 验证可以为组件的props指定验证要求,如果传入的数据不符合指定要求,Vue会发出警告。为了定
14、制props 的验证方式,可以为props中的值提供一个带有验证需求的对象,而不能使用字符串数组。例如:VuexomponentCexample, props: /基础类型检测(null和undefined会通过任何类型验证) prop A: Number,/多种类型propB: String, Number, /必传且是字符串 propC: type: String, required: true ,/带有默认值的数字propD: type: Number, default: 100 .带有默认值的对象propE: type: Object,/数组或对象的默认值应当由一个工厂函数获取defa
15、ult: function () return message: hello),/自定义验证函数propF: validator: function (value) /这个值必须匹配下列字符串中的一个return success, warning, danger.indexOf(value) != -1 )type可以是下面原生构造器之一。 String Numbero Boolean。 Functiorio Objecto Array0 Dateo SymboLtype也可以是一个自定义构造器函数,使用instanceof检测。当props验证失败的时候,Vue (开发环境构建版本的)将会在
16、控制台界面中抛出一个警告信息(如果使 用的是开发版本卜props会在组件实例创建之前进行校验,所以在default。或validator。函数里,诸如data、 computed或methods等实例属性还无法使用。【实例53】验证传入子组件的数据是否为数字【操作要求】创建父子组件,采用props验证方式验证传入子组件的数据是否为数字,如果不是数字,则在浏览器的控 制台界面中抛出警告信息。如果num的值是数字123,浏览网页0503.html时,浏览器的控制台界面中不会出现警告信息。如果num 的值是字符串123 ,浏览网页0503.html时,浏览器的控制台界面中会出现如下所示的警告信息:v
17、ue.js:634 (Vue warn: Invalid prop: type check failed for prop para. Expected Number with value 123, got String with value 123.【实例5-4使用自定义函数验证传入子组件的数据是否符合指定条件【操作要求】创建父子组件,采用props验证,使用自定义函数验证传入子组件的数据是否符合指定条件,当函数返回 为false时,则表示不符合指定的条件,则浏览器的控制台界面中会出现警告信息。如果在父组件中传入num值为5 ,由于小于10 ,则浏览网页时浏览器的控制台界面中会输出如下的警告
18、 信息:vue.js:634 (Vue warn: Invalid prop: custom validator check failed for prop para.5.4.7 单向数据流props是单向绑定的:当父组件的属性变化时将传给子组件,但是不会反过来传递。这是为了防止子组件 无意中修改了父组件的状态,这样会让应用的数据流难以理解。另外,每次父组件更新时,子组件的所有props都会更新为最新值。这意味着不应该在子组件内部改变 props ,如果这么做了,Vue会在浏览器的控制台界面中显示警告信息。【实例55】验证props的单向绑定特性【操作要求】创建父子组件,采用props单向绑定
19、。父组件的数据变化时,子组件的数据会同步发生变化;子组件的数 据变化时,父组件数据不变,并在浏览器的控制台界面中显示警告信息。浏览网页0505.html时的初始状态如图所示。父组件数据回输入的值为:try子组件数据|歹输入的值为:try浏览网页0505.html时的初始状态将父组件数据”输入框中的“try”修改为“happy”时,“子组件数据输入框中的内容会同步修改为“happy”。而修改子组件数据.输入框中的内容时,浏览器控制台界面中会出现如下所示的警告信息:vue.js:634 Vue warnj: Avoid mutating a prop directly since the valu
20、e will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the props value. Prop being mutated: childData.5.4.8 修改props数据修改props中的数据通常有以下两种原因。props作为初始值传入后,子组件想把它当作局部数据来使用。props作为初始值传入后,由子组件处理成其他数据输出。对于这两种情况,正确的应对方式如下。1 .定义一个局部变量,并将其用props的值初始化p
21、rops:childDatal,data:function() retum temp:this.childData定义的局部变量temp只能接受childData的初始值,当父组件要传递的值发生变化时,temp无法接收到 最新值。2 .定义一个计算属性,处理props的值并返回propsfchildDatal,computed:temp()return this.childData)因为是计算属性,所以只能显示值,不能设置值。3 .使用变量存储props的初始值,并使用watch()方法观察props值的变化一个较为妥帖的方案是使用变量存储props的初始值,并使用watch。方法来观察pro
22、ps的值的变化。当 props的值发生变化时,立即赋值给子组件的data ,更新子组件变量的值。修改子组件的数据时,浏览器控制 台界面中也不会出现警告信息。代码如下: Vponent。方法表示注册组件的API ,参数button-counter为组件名称II组件名称与页面中的标签名称“11M0481示6对应II组件名称还可以使用驼峰法命名,这里也可命名为buttoncounterVponent(button-counter, /组件中的数据必须是一个函数,通过返回值来返回初始数据data: function () return count: 0) ). II表示组件的模板 template:
23、单击 了 count次/button)(2 )在HTML代码中把组件button-counter作为自定义元素使用代码如下:(3 )通过new Vue创建Vue根实例代码如下:var vm=new Vue(el: #app)(4 )浏览网页0501.html网页0501.html的初始状态出现|单击了0次按钮,单击1次后按钮变为|单击了 1次。因为组件是可复用的Vue实例,所以它们与new Vue接收相同的选项(像el这样的根实例特有的选项除 外),例如 data、computedx watch、methods 及钩子函数等。1 .复用组件组件的可复用性很强,可以将组件进行任意次数的复用。创建
24、网页文件demo050101.html ,该文件中自定 义组件button-counter的代码与网页文件0501.html相同,在网页文件demo050101.html中对自定义的组件 button-counter进行复用,即一次定义,多次使用。【示例】demo050101.html代码如下:II定义一个名为button-counter的组件Vponent(button-counter, 在自定义组件中使用vfor指令Vue 220+版本里,当在组件中使用v-for指令时,key是必须的,例如:但是,不能自动传递数据到组件里,因为组件有自己独立的作用域。为了传递迭代数据到组件里,需要使 用p
25、ropso在一些情况下,明确数据的来源可以使组件可重用。【实例56】在自定义组件中使用vfor指令输出列表【操作要求】在自定义组件my-component中使用v-for指令输出图书名称列表。【实现过程】创建网页0506.html ,在该网页中编写以下代码实现要求的功能:/注册Vponentfmy-component, template: index- name ,propsjindex.name)/创建根实例new Vue(el: #appdata()return items:id:1, bookName: HTML5+CSS3 移动 Web 开发实战,id:2, bookName:零基础学
26、 Python,),id:3, bookName:数学之美)网页0506.html的浏览效果如图所示。O-HTM15*CSS3移动We阳好战2gN 类 网页0506.html的浏览效果5.5 组件之间的通信在Vue中,组件之间的通信有父子组件之间、兄弟组件之间、祖先组件与后代组件之间等通信。父组件通过props选项把数据传递给子组件,子组件的props选项能够接收来自父组件的数据。props是从 上到下的单向数据流传递,且父组件的props更新会向下流动到子组件中,但是反过来则不可以。父子组件之间 的数据传递相当于自上而下的下水管子,只能从上往下流,不能从下往上流,这也正是Vue的设计理念单向
27、 数据流。Props可以理解为管道与管道之间的一个衔接口,这样水才能往下流。$emit能够实现子组件向父组件传递数据。子组件使用$emit触发父组件中定义的事件,子组件的数据信 息通过传递参数的方式完成,在父组件中可以使用S。g自定义事件进行监听。【实例57】使用props选项实现父组件向子组件传递数据【操作要求】创建父子组件,使用子组件的props选项接收来自父组件的数据,实现父组件向子组件的数据传递。在页面渲染出的HTML如下:这是父组件传来的数据子组件的props选项接收来自父组件的字符串数据“这是父组件传来的数据,变量content的默认值“这是 子组件的数据”被父组件传来的字符串覆盖
28、。5.5.1 父组件向子组件传递数据父组件传递数据到子组件使用props选项,并且该传递是单向的,只能由父组件传到子组件。下面给以上 示例中的父组件增加一个数据,并传递到子组件中渲染显示,如果父组件需要传多个数据给子组件,依次在后 面加即可。【示例】demo050501.html实现过程如下。(1 )在父组件中增加msg ,并绑定到子组件上代码如下:var parentNode = Vue.extend(template: 这是父组件child :pdata=msg,data()retummsg:这是父组件传给子组件的数据:123),components:child:childNode);中的
29、:pdata是“v-bind:pdata”的缩写;pdata是自定义传递数据的命名,子组 件中也是用该名称获取数据;msg是父组件中数据的命名。(2 )在子组件中通过props选项获取数据,并渲染出来代码如下:var childNode = Vue.extend(template:,这是子组件 pdata , props:pdataJ);由于父组件传递数据到子组件是单向的,一旦父组件中的数据发生变化,子组件中会自动更新,但子组件 不可直接修改通过props选项获取到的父组件中的数据。(3)创建根实例代码如下:var vm=new Vue(el: #appcomponents: parent:
30、parentNode)5.5.2 子组件向父组件传递数据子组件向父组件传递数据是通过$emit事件触发的方式实现的,父组件使用v-on/自定义事件进行监听 即可。在子组件中,可以通过以下方式监听事件:v-on:click=$emit(funcName,a)如果需要传递多个参数,可以通过以下方式实现:v-on:click=M$emit(funcName,a,b.父组件中通过自定义事件来监听子组件的事件,例如自定义事件名称childlistener,可以通过以下方式在 父组件中进行监听:v-on:childlistener=parentMethod($event)$event就是子组件中传过来的参
31、数。如果子组件传过来的是一个参数,则$event等于该参数;如果传过 来的是一个对象,则$6丫6团为该对象。可以通过对象的方式获取对应的参数,例如$eventa$event.b等。【示例】demo050502.html实现过程如下。(1 )构建子组件代码如下:var childNode = Vue.extend(template: 单击给父组件传值:methods:change: function()this.SemitCposttoparent, 10);子组件按钮绑定了一个click事件,单击按钮则执行change。方法,该方法触发emit事件,事件名为 posttoparent ,并且带
32、了一个参数10。(2)构建父组件代码如下:var parentNode = Vue.extend(template: 子组件传递给父组件的值为:datafromchild ,data()retumdatafromchild:),components:(child:childNode,methods: getfromchild: function(val)this.datafromchild = val);父组件通过v-on指令接收emit事件,格式为:v-on:emit方法名=父组件方法父组件将接收到的参数赋值给datafromchildo(3)创建根实例代码如下:var vm=new Vue
33、(el: *#app,components: parent: parentNode)5.5.3 兄弟组件之间的通信兄弟组件之间的通信也是使用$60 ,但原生Vue需要新建一个空的Vue实例来当桥梁。5.6 Vue自定义事件父组件可以使用props传递数据给子组件,那子组件怎么将数据传递给父组件呢?这时,Vue的自定义事 件就派上用场了。5.6.1 事件绑定可以使用v-on绑定自定义事件,每个Vue实例都实现了事件接口( Events Interface卜使用$on(eventName)监听事件。使用$emit(eventName)触发事件。另外,父组件可以在使用子组件的地方直接用v-on来监听
34、子组件触发的事件,但不能使用$on监听子组 件抛出的事件,而必须在模板里直接使用v-on绑定。使用$emit(eventName)触发事件的示例如下。【示例】demo050601.html略本示例中的按钮数字变化是通过改变变量counter的值实现的,变量total用于记录两个按钮数字的变化, 为两个按钮数字之和。5.6.2 自定义事件的命名约定自定义事件的命名约定与组件注册及props的命名约定都不相同由于自定义事件本质上也属于HTML的 属性,所以其在HTML模板中最好使用短横线连接单词形式来表示。例如:而在子组件中触发事件时,同样使用短横线连接单词形式来表示。例如:this.SemitC
35、pass-data.this.childMsg)5.6.3 子组件向父组件传递数据子组件通过$emit可以触发事件,第一个参数为要触发的事件,第二个参数为要传递的数据,语法格式为:this.SemitCpass-data.this.childMsg)父组件通过$on监听事件,事件处理函数的参数则为接收的数据。例如:getData(value)this.msg = value;)【实例5-8使用$emit触发事件实现子组件向父组件的数据传递【操作要求】创建父子组件,并实现子组件向父组件的数据传递。要求子组件的数据变化时,父组件的数据同步发生变 化;而父组件的数据变化时,子组件的数据不改变。浏览网
36、页0508.html时的初始状态如图所示。父组件数据| try子组件数据|浏览网页0508.html时的初始状态修改子组件中的input值,例如“g。”,则父组件接收到相同的值,并显示出来,如图所示。父组件数据尿I go子组件数据|g。I go修改子组件中的input值5.6.4 .sync 修饰符在有些情况下,可能会需要对一个props进行双向绑定。事实上,这正是Vue 1.x中的.sync修饰符 所提供的功能。当一个子组件改变了一个props的值时,这个变化也会同步到父组件中所绑定的值。这 很方便,但也会导致问题,因为它破坏了单向数据流。由于子组件改变props的代码和普通的状态改动 代码
37、毫无区别,当光看子组件的代码时,完全不知道它何时悄悄地改变了父组件的状态。这在调试复杂结 构的应用时会带来很高的维护成本,上面所说的正是在Vue 2.0中移除.sync的原因。从起重新引入了.sync修饰符,但是这次它只是作为一个编译时的语法糖存在。它可以被扩展 为一个自动更新父组件属性的v-on监听器。例如:它可以被扩展为: num = val当子组件需要更新count的值时,它需要显式地触发一个更新事件:this.$emit(update:count, newValue)因此,可以使用.sync来简化自定义事件的操作,实现子组件向父组件的数据传递。【实例5-9使用.sync修饰符实现子组件
38、向父组件传递数据【操作要求】创建父子组件,使用.sync修饰符来简化自定义事件的操作,实现子组件向父组件传递数据,即子组件的 数据变化时,父组件的数据同步发生变化。浏览网页0509.html时的初始状态如图所示。父组件数据:o子组件数据|o|里击一次增加1浏览网页0509.html时的初始状态单击【单击一次增加1按钮,则输入框、子组件数据和父组件数据会同步变化,并显示出来。单击【单 击一次增加1】按钮3次后的结果如图所示。父退件数据:3子蛆件数据:3|3里壬一次戏州单击【单击一次增加1】按钮3次后的结果5.7 Vue组件动态切换让多个组件使用同一个挂载点,并动态切换,这就是动态组件。5.7.1