一、介绍
(一) Vue.js是什么
Vue
(读音 /vjuː/,类似于view
)是一套用于构建用户界面的渐进式框架。Vue
被设计为可以自底向上逐层应用。
Vue.js
使用了基于HTML
的模板语法,允许开发者声明式地将DOM绑定至底层Vue
实例的数据。所有Vue.js
的模板都是合法的HTML,所以能被遵循规范的浏览器和HTML
解析器解析。
在底层的实现上,Vue将模板编译成虚拟DOM渲染函数。结合响应系统,Vue能够智能地计算出最少需要重新渲染多少组件,并把DOM操作次数减到最少。
Vue.js的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进DOM的系统,只关注视图层,易于上手。所有东西都是响应式的。
(二) vue相比传统js的开发优势
在传统开发中,用原生的JavaScript DOM
操作函数对DOM
进行频繁操作的时候,浏览器要不停的渲染新的DOM
树,导致页面看起来非常卡顿。
vue
是单页面应用,使页面局部刷新,不用每次跳转页面都要请求所有数据和DOM
,这样大大加快了访问速度和提升用户体验。
1、vue的优势
-
轻量级渐进式框架
-
视图、数据和结构的分离
-
响应式双向数据绑定
-
组件化
-
虚拟DOM
-
运行速度快,易于上手
-
便于与第三方库或既有项目整合
2、文件类型
-
以前是
.html
文件,开发也是html
,运行也是html
。 -
现在是
.vue
文件,开发是vue
,经过编译后,运行时已经变成了js
文件。 -
现代前端开发,很少直接使用
HTML
,基本都是开发、编译、运行。所以uni-app
有编译器、运行时的概念。
3、文件内代码架构的变化
-
以前一个
html
大节点,里面有script
和style
节点。<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> </script> <style type="text/css"> </style> </head> <body> </body> </html>
-
现在
template
是一级节点,用于写tag
组件,script
和style
是并列的一级节点,也就是有3个一级节点。<template> <view> 注意必须有一个view,且只能有一个根view。所有内容写在这个view下面。 </view> </template> <script> export default { } </script> <style> </style>
[操作] 在pages
目录下新建vue
目录,新增old.html
与new.vue
文件,对比代码架构。
4、外部文件引用方式变化
-
以前通过
script src
、link href
引入外部的js
和css
。
<script src="js/jquery-1.10.2.js" type="text/javascript"></script> <link href="css/bootstrap.css" rel="stylesheet" type="text/css"/>
-
现在是es6的写法,
require
或import
引入外部的js模块(注意不是文件)或css。
js要require进来,变成了对象。
function formatTime(time) { return time; // 这里面写逻辑 } module.exports = { formatTime: formatTime }
<script> var util = require('../../common/util.js'); // require这个js模块 var formatedPlayTime = util.formatTime(playTime); // 调用js模块的方法 </script>
[操作] 在根目录下新建common
目录,新增util.js
文件,添加脚本代码。在pages/vue
目录下,新增external.vue
文件,引用util.js
,调用其方法。
css外部文件导入。
<style> @import "./common/uni.css"; .uni-hello-text{ color:#7A7E83; } </style>
另外,vue支持组件导入,可以更方便的封装一个包括界面、js、样式的库。
5、组件/标签的变化
以前是html标签,比如<div>
,现在是小程序组件,比如<view>
。
那么标签和组件有什么区别,不都是用尖括号包围起来一段英文吗?
-
其实标签是老的概念,标签属于浏览器内置的东西。
-
但组件,是可以自由扩展的。类似你可以把一段js封装成函数或模块,你也可以把一个ui控件封装成一个组件。
6、js的变化
-
以前的 DOM 操作,如果你想改变某个 DOM 元素的显示内容,比如一个view的显示文字:给view设id,然后js里通过选择器获取 DOM 元素,进一步通过js进行赋值操作,修改 DOM 元素的属性或值。
<html> <head> <script type="text/javascript"> document.addEventListener("DOMContentLoaded",function () { document.getElementById("spana").innerText="456" }) function changetextvalue () { document.getElementById("spana").innerText="789" } </script> </head> <body> <span id="spana">123</span> <button type="button" οnclick="changetextvalue()">修改为789</button> </body> </html>
-
现在的做法,是vue的绑定模式,给这个DOM元素绑定一个js变量,在script中修改js变量的值,DOM会自动变化,页面会自动更新渲染(MVVM)。
<template> <view> <text>{{textvalue}}</text><!-- 这里演示了组件值的绑定 --> <button :type="buttontype" @click="changetextvalue()">修改为789</button><!-- 这里演示了属性和事件的绑定 --> </view> </template> <script> export default { data() { return { textvalue:"123", buttontype:"primary" }; }, onLoad() { this.textvalue="456"//这里修改textvalue的值,其实123都来不及显示就变成了456 }, methods: { changetextvalue() { this.textvalue="789"//这里修改textvalue的值,页面自动刷新为789 } } } </script>
[操作] 在
pages/vue
目录下新增oldjs.html
与newjs.vue
文件,对比脚本变化。
(三) 在uni-app中使用差异
uni-app
在发布到H5
时支持所有vue
的语法;发布到App
和小程序
时,由于平台限制,无法实现全部vue
语法,但uni-app
仍是对vue
语法支持度最高的跨端框架。
二、基础
(一) 模版语法
1、插值
a. 插值
数据绑定最常见的形式就是文本插值:
<template> <view> <view>Message: {{msg}}</view> </view> </template> <script> export default { data() { return { msg: 'Hello Vue!' } } } </script>
[注] {{msg}}
里的内容将会被替代为对应数据对象上msg
的值。无论何时,绑定的数据对象上msg
发生了改变,插值处的内容都会更新。
[操作] 在page
目录下新建basic
目录,新增data.vue
文件,实现文本插值绑定。
b. 使用JavaScript表达式
迄今为止,在我们的模板中,我们一直都只绑定简单的property
键值。但实际上,对于所有的数据绑定,Vue.js
都提供了完全的JavaScript
表达式支持。
<template> <view> <view>{{ number + 1 }}</view> <view>{{ ok ? 'YES' : 'NO' }}</view> <!-- 把一个字符串分割成字符串数组,颠倒其元素的顺序,把数组中的所有元素放入一个字符串 --> <view>{{ message.split('').reverse().join('') }}</view> </view> </template> <script> export default { data() { return { number:1, ok:true, message: 'Hello Vue!' } } } </script>
[操作] 编辑data.vue
文件,实现JavaScript表达式绑定。
<template> <view> <view v-for="(item,index) in 10"> <!-- 通过%运算符求余数,实现隔行换色的效果 --> <view :class="'list-' + index%2">{{index%2}}</view> </view> </view> </template> <script> export default { data() { return { } } } </script> <style> .list-0{ background-color: #aaaaff; } .list-1{ background-color: #ffaa7f; } </style>
[操作] 编辑data.vue
文件,实现隔行换色。
这些表达式会在所属Vue
实例的数据作用域下作为JavaScript
被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
<template> <view> <!-- 这是语句,不是表达式 --> <view>{{ var a = 1 }}</view> <!-- 流控制也不会生效,请使用三元表达式 --> <view>{{ if (ok) { return message } }}</view> </view> </template> <script> export default { data() { return { ok:true, message: 'Hello Vue!' } } } </script>
2、指令
指令是带有 v- 前缀的特殊属性。
-
v-bind
:动态地绑定一个或多个属性,或一个组件prop
到表达式。v-bind
缩写为“:
”。<image v-bind:src="imgUrl"></image> <!-- 缩写 --> <image :src="imgUrl"></image> <button v-bind:disabled="isButtonDisabled">Button</button>
[操作] 在
pages/basic
目录新增instruct.vue
文件,实现v-bind
绑定。 -
v-on
:用于监听DOM事件。v-on
缩写为“@
”。<!-- 完整语法 --> <view v-on:click="doSomething">点击</view> <!-- 缩写 --> <view @click="doSomething">点击</view>
[操作] 编辑
instruct.vue
文件,实现v-on
绑定。
(二) Data属性
data必须声明为返回一个初始数据对象的函数(注意函数内返回的数据对象不要直接引用函数外的对象);否则页面关闭时,数据不会自动销毁,再次打开该页面时,会显示上次数据。
// 正确用法,使用函数返回对象 data() { return { title: 'Hello' } } // 错误写法,会导致再次打开页面时,显示上次数据 data: { title: 'Hello' } // 错误写法,同样会导致多个组件实例对象数据相互影响 const obj = { title: 'Hello' } data() { return { obj } }
(三) Class
与Style
绑定
可以传给v-bind:class
一个对象,实现动态地切换class
。
也可以在对象中传入更多字段来动态切换多个class
。此外,v-bind:class
指令也可以与普通的class
共存。
<template> <view> <!-- class --> <view class="static" :class="{ active: isActive}">111</view> <view class="static" :class="{ active: isActive, 'text-danger': hasError }">222</view> <!-- style --> <view v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">333</view> </view> </template> <script> export default { data() { return { isActive: true, hasError: true, activeColor:"green", fontSize:50 } } } </script> <style> .static{ color: #2C405A; } .active{ background-color: #007AFF; } .text-danger{ color: #DD524D; } </style>
[操作] 在pages/basic
目录新增style.vue
文件,实现Class
与Style
绑定。
(四) 条件渲染
1、v-if和v-else
v-if指令
:用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true
值的时候被渲染。
v-else指令
:表示v-if
的“else
块”。
<template> <view> <view v-if="seen">现在你看到我了</view> <view v-else>你看不到我了</view> </view> </template> <script> export default { data() { return { seen: true } } } </script>
[操作] 在pages/basic
目录新增condition.vue
文件,使用v-if
和v-else
指令。
2、v-else-if
v-else-if指令
:充当v-if
的“else-if
块“,可以连续使用。
<template> <view> <view v-if="type === 'A'">A</view> <view v-else-if="type === 'B'">B</view> <view v-else-if="type === 'C'">C</view> <view v-else>Not A/B/C</view> </view> </template> <script> export default { data() { return { type:'B' } } } </script>
[操作] 编辑condition.vue
文件,使用v-else-if
指令。
3、条件渲染分组
因为v-if
是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个template
元素当做不可见的包裹元素,并在上面使用v-if
。最终的渲染结果将不包含template
元素。
<template v-if="seen"> <view>标题</view> <view>内容:现在你看到我了</view> </template>
[操作] 编辑condition.vue
文件,使用条件渲染分组。
4、v-show
v-show
指令:根据条件展示元素选项的指令。用法大致和v-if
一样。
<view v-show="ok">Hello!</view>
不同的是带有v-show
的元素始终会被渲染并保留在DOM中。v-show
只是简单地切换元素的CSS
属性的display
。
[注] v-show
不支持template
元素,也不支持v-else
。
[操作] 编辑condition.vue
文件,使用v-show
指令。
(五) 列表渲染
1、在v-for里使用数组
v-for
指令可以实现基于一个数组来渲染一个列表。
v-for
指令需要使用item in items
形式的特殊语法,其中items
是源数据数组,而item
则是被迭代的数组元素的别名。
<template> <view> <view v-for="(item, index) in items"> {{ index }} - {{ item.message }} </view> </view> </template> <script> export default { data() { return { items: [ { message: 'Foo' }, { message: 'Bar' } ] } } } </script>
[注] 第一个参数item
是被迭代的数组元素的别名。第二个参数,即当前项的索引index
,是可选的。
[操作] 在pages/basic
目录下,新增list.vue
文件,实现列表渲染。
2、在v-for里使用对象
也可以用v-for
来遍历一个对象的property
。
<template> <view> <view v-for="(value, name, index) in object"> {{ index }}. {{ name }}: {{ value }} </view> </view> </template> <script> export default { data() { return { object: { title: 'How to do lists in Vue', author: 'Anley', publishedAt: '2021-07-10' } } } } </script>
[注] 第一个参数value
是被迭代的对象元素的属性值。第二个参数为property
名称 (也就是键名)。第三个参数作为索引。
[操作] 编辑list.vue
文件,实现对象property
遍历。
3、列表渲染分组
类似于v-if
,可以利用带有v-for
的template
来循环渲染一段包含多个元素的内容。
<template v-for="item in items"> <view>{{ item.message }}</view> <view class="divider" role="presentation"></view> </template>
[操作] 编辑list.vue
文件,使用template
实现列表渲染。
4、key
当Vue
正在更新使用v-for
渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue
将不会移动DOM元素
来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如input
中的输入内容,switch
的选中状态),需要使用:key
来指定列表中项目的唯一的标识符。
:key
的值以两种形式提供
-
使用
v-for
循环array
中item
的某个property
,该property
的值需要是列表中唯一的字符串或数字,且不能动态改变。 -
使用
v-for
循环中item
本身,这时需要item
本身是一个唯一的字符串或者数字。
当数据改变触发渲染层重新渲染的时候,会校正带有key
的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
<template> <view> <!-- array 中 item 的某个 property --> <view v-for="(item,index) in objectArray" :key="item.id"> {{index +':'+ item.name}} </view> <!-- item 本身是一个唯一的字符串或者数字时,可以使用 item 本身 --> <view v-for="(item,index) in stringArray" :key="item"> {{index +':'+ item}} </view> </view> </template> <script> export default { data () { return { objectArray:[{ id:0, name:'li ming' },{ id:1, name:'wang peng' }], stringArray:['a','b','c'] } } } </script>
[操作] 编辑list.vue
文件,实现列表渲染时key
的赋值。
5、在组件上使用v-for
在自定义组件上,你可以像在任何普通元素上一样使用v-for
。
<my-component v-for="item in items" :key="item.id"></my-component>
当在组件上使用v-for
时,key
是必须的。
(六) 事件处理器
1、监听事件
可以用@
事件监听DOM
事件,并在触发时运行一些JavaScript
代码。
<template> <view> <button @click="counter += 1">Add 1</button> <text>The button above has been clicked {{ counter }} times.</text> </view> </template> <script> export default { data() { return { counter:0 } } } </script>
[操作] 在pages/basic
目录下,新增event.vue
文件,实现列表渲染。
2、事件处理方法
然而许多事件处理逻辑会更为复杂,所以直接把JavaScript
代码写在@
事件中是不可行的。因此@
事件还可以接收一个需要调用的方法名称。
<template> <view> <!-- greet是在下面定义的方法名 --> <button @click="greet">Greet</button> </view> </template> <script> export default { data() { return { name: 'Vue.js' } }, // 在methods对象中定义方法 methods: { greet(event){ // event是原生DOM事件 console.log(event); uni.showToast({ title: 'Hello ' + this.name + '!' }); } } } </script>
[操作] 编辑event.vue
文件,实现较复杂的事件处理。
3、内联处理器中的方法
除了直接绑定到一个方法,也可以在内联JavaScript
语句中调用方法:
<template> <view> <button @click="say('hi')">Say hi</button> <button @click="say('what')">Say what</button> </view> </template> <script> export default { methods: { say(message) { uni.showToast({ title: message }); } } } </script>
[操作] 编辑event.vue
文件,实现内联处理方法。
4、事件修饰符
修饰符(modifier)是以半角句号.
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。
@事件
(v-on
)提供了以下事件修饰符:
-
.stop
:阻止冒泡,各平台均支持。 -
.prevent
:阻止默认事件,仅在H5
平台支持。 -
.capture
:添加事件侦听器时使用事件捕获模式,仅在H5
平台支持。 -
.self
:只当事件在该元素本身(比如不是子元素)触发时触发回调,仅在H5
平台支持。 -
.once
:事件只触发一次,仅在H5
平台支持。
<!-- 阻止单击事件继续传播 --> <view @click.stop="doThis"></view>
[操作] 编辑event.vue
文件,使用.stop
修饰符阻止冒泡。
(七) 表单控件绑定
1、v-model
你可以用v-model
指令在表单input
、textarea
及select
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。
<template> <view> <input v-model="message" placeholder="edit me"> <text>Message is: {{ message }}</text> </view> </template> <script> export default { data() { return { message:"" } } } </script>
[注] v-model
会忽略所有表单元素的value
、checked
、selected
等attribute的初始值而总是将Vue
实例的数据作为数据来源。你应该通过JavaScript在组件的data
选项中声明初始值。
[操作] 在pages/basic
目录下,新增form.vue
文件,实现双向数据绑定。
2、uni-app表单组件
-
H5
的select
标签用picker
组件进行代替。<template> <view> <picker @change="bindPickerChange" :value="index" :range="array"> <view class="picker"> 当前选择:{{array[index]}} </view> </picker> </view> </template> <script> export default { data() { return { index: 0, array: ['A', 'B', 'C'] } }, methods: { bindPickerChange(e) { console.log(e) } } } </script>
[操作] 编辑
form.vue
文件,实现picker
组件。 -
表单元素
radio
用radio-group
组件进行代替。<template> <view> <radio-group class="radio-group" @change="radioChange"> <label class="radio" v-for="(item, index) in items" :key="item.name"> <radio :value="item.name" :checked="item.checked" /> {{item.value}} </label> </radio-group> </view> </template> <script> export default { data() { return { items: [{ name: 'USA', value: '美国' }, { name: 'CHN', value: '中国', checked: 'true' }, { name: 'BRA', value: '巴西' }, { name: 'JPN', value: '日本' }, { name: 'ENG', value: '英国' }, { name: 'TUR', value: '法国' } ] } }, methods: { radioChange(e) { console.log('radio发生change事件,携带value值为:', e.target.value) } } } </script>
[操作] 编辑
form.vue
文件,实现radio-group
组件。
三、组件
组件是视图层的基本组成单元。
组件是一个单独且可复用的功能模块的封装。
一个组件包括开始标签和结束标签,标签上可以写属性,并对属性赋值。
(一) 注册
在注册一个组件的时候,我们始终需要给它一个名字。 定义组件名的方式有两种:
-
使用
kebab-case
当使用kebab-case
(短横线分隔命名)定义一个组件时,你也必须在引用这个自定义元素时使用kebab-case
,例如<my-component-name>
。
-
使用
PascalCase
当使用PascalCase
(驼峰式命名)定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说<my-component-name>
和<MyComponentName>
都是可接受的。
在uni-app
工程根目录下的components
目录,创建并存放自定义组件:
│─components 符合vue组件规范的uni-app组件目录 │ └─componentA 符合‘components/组件名称/组件名称.vue’目录结构,easycom方式可直接使用组件 │ └─componentA.vue 可复用的componentA组件 │ └─component-a.vue 可复用的component-a组件
1、全局注册
uni-app
支持配置全局组件,需在main.js
里进行全局注册,注册后就可在所有页面里使用该组件。
-
main.js
里进行全局导入和注册import Vue from 'vue' import pageHead from './components/page-head.vue' Vue.component('page-head',pageHead)
[注]
Vue.component
的第一个参数必须是静态的字符串。 -
index.vue
里可直接使用组件<template> <view> <page-head></page-head> </view> </template>
[操作] 新建components
目录,新增page-head.vue
文件,完成组件设计。在main.js
中进行全局导入和注册。在pages
目录中新建component
目录,新增page1.vue
文件,设计页面,引用page-head
组件。
2、局部注册
局部注册之前,在需要引用该组件的页面,导入你想使用的组件。
-
传统vue规范
在
.vue
页面中,通过import
方式引入组件,在components
选项中定义你想要使用的组件。<!-- 在index.vue引入 uni-badge 组件--> <template> <view> <uni-badge text="1"></uni-badge><!-- 3.使用组件 --> </view> </template> <script> // 1.导入组件(这步属于传统vue规范,但在uni-app的easycom下可以省略这步) import uniBadge from '@/components/uni-badge/uni-badge.vue'; export default { // 2.注册组件(这步属于传统vue规范,但在uni-app的easycom下可以省略这步) components:{ uniBadge } } </script>
[操作] 在
components
目录新建uni-badge
目录,新增uni-badge.vue
文件,完成组件设计。在pages/component
目录中新增page2.vue
文件,注册并引用uni-badge
组件。 -
通过
uni-app
的easycom
将组件引入精简为一步。只要组件安装在项目的
uni_modules
目录下,并符合uni_modules/组件名称/components/组件名称/组件名称.vue
目录结构。就可以不用引用、注册,直接在页面中使用。<!-- 在index.vue引入 uni-badge 组件--> <template> <view> <uni-badge text="1"></uni-badge><!-- 3.使用组件 --> </view> </template> <script> // 这里不用import引入,template里就可以直接用 export default { data() { return { } } } </script>
[注]
easycom
是自动开启的,不需要手动开启。[操作] 新建
/uni_modules/uni-badge/components/uni-badge
目录,新增uni-badge.vue
文件,完成组件设计。在pages/component
目录中新增page3.vue
文件,直接引用uni-badge
组件。
(二) props
props
可以是数组或对象,用于接收来自父组件的数据。props
可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。
<template> <view> <!-- 我是子组件componentA --> <view>{{age}}</view> </view> </template> <script> export default { props: { // 检测类型 + 其他验证 age: { type: Number, // type:会检查一个prop是否是给定的类型,否则抛出警告。 default: 0, // default:为该prop指定一个默认值。如果该prop没有被传入,则换做用这个值。对象或数组的默认值必须从一个工厂函数返回。 required: true, // required:定义该prop是否是必填项。 validator: function(value) { // 自定义验证函数会将该prop的值作为唯一的参数代入。 return value >= 0 } } } } </script>
<template> <view> <!-- 我是父组件 --> <componentA :age="10"></componentA> </view> </template>
[操作] 在pages/component
目录下,新增componentA.vue
文件,完成子组件设计。新增props.vue
文件,完成父组件设计,引用componentA
子组件。
如果你想要将一个对象的所有property
都作为prop
传入,你可以使用不带参数的v-bind
(取代v-bind:prop-name
)。
post: { id: 1, title: 'My Journey with Vue' }
<blog-post v-bind="post"></blog-post> <!-- 上面的模板等价于: --> <blog-post v-bind:id="post.id" v-bind:title="post.title" ></blog-post>
[操作] 在pages/component
目录下,新增blogPost.vue
文件,完成子组件设计。编辑props.vue
文件,引用blogPost
子组件。
所有的prop
都使得其父子prop
之间形成了一个单向下行绑定:父级prop
的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
(三) ref
ref
是被用来给元素或子组件注册引用信息的。引用信息将会注册在父组件的$refs
对象上。
<template> <!-- 父组件 --> <div> <h1>我是父组件!</h1> <child ref="msg"></child> </div> </template> <script> import child from '../components/child1.vue' export default { components: {child}, mounted: function () { console.log(this.$refs.msg); this.$refs.msg.setMessage('我是子组件一!') } } </script>
<template> <!-- 子组件 --> <h3>{{message}}</h3> </template> <script> export default { data(){ return{ message:'' } }, methods:{ setMessage(m){ this.message=m; } } } </script>
[操作] 在pages/component
目录下,新增child1.vue
文件,完成子组件设计。新增ref.vue
文件,完成父组件设计,引用child1
子组件,并调用其方法。
[prop与ref之间的区别] prop
着重于数据的传递,它并不能调用子组件里的属性和方法。ref
着重于索引,主要用来调用子组件里的属性和方法,其实并不擅长数据传递。
(四) emit
prop
与ref
主要都是父组件向子组件通信,而通过emit
实现子组件向父组件通信。
<template> <div> <h1>{{title}}</h1> <child @setMessage="showMsg"></child> </div> </template> <script> import child from '../components/child2.vue' export default { components: {child}, data(){ return{ title:'' } }, methods:{ showMsg(title){ this.title = title; } } } </script>
<template> <h3>我是子组件!</h3> </template> <script> export default { mounted: function () { this.$emit('setMessage', '我是父组件!') } } </script>
[操作] 在pages/component
目录下,新增child2.vue
文件,完成子组件设计。新增emit.vue
文件,完成父组件设计,引用child2
子组件,并调用其方法。
(五) 自定义事件
如果想要在一个组件的根元素上直接监听一个原生事件。这时可以使用@
事件的.native
修饰符。
<template> <!-- 我是父组件 --> <view> <componentB @click.native="clickComponentB" style="height: 200px;"></componentB> </view> </template> <script> import componentB from './componentB.vue' export default { components: { componentB }, methods: { clickComponentB(){ console.log("clickComponentB"); } } } </script>
<template> <!-- 我是子组件 --> <view> <view type="default" @click.stop="open" style="height: 30px;">点击</view> </view> </template> <script> export default { methods:{ open(){ console.log("open"); } } } </script>
[操作] 在pages/component
目录下,新增componentB.vue
文件,完成子组件设计。新增native.vue
文件,完成父组件设计,引用componentB
子组件。点击子组件时,会触发子组件内的点击事件。如果在父组件中添加native
关键词,点击子组件时,会触发子组件内和父组件内的点击事件。如果在子组件中添加stop
关键字,点击子组件时,会触发子组件内的点击事件。
目录