vue基本使用
1.基本使用
本篇的主要内容有:
- vue 的安装
- 生命周期钩子
- 模板语法
- 常用指令
- 数据侦听器
- Class、Style 绑定
- 条件渲染
- 列表渲染
- 表单输入绑定
- 组件
vue 的安装
Vue (读音 /vju?/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
官方文档:链接地址
最简单的安装方式是创建一个 .html 文件,然后通过如下方式引入 Vue:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
当然也可以使用 Node.js 的构建工具安装 vue-cli。这种方式主要针对专业前端开发,这里便不再赘述。
为了使 idea 有更好的代码提示效果,建议安装 vue.js 插件。
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统,以操作数据的方式操作 DOM 节点,Vue 不建议使用者直接操作节点内容,目前大部分开发平台都倡导以修改数据的方式操作节点,操作节点被认为是一种落后的技术。
<div id="app"> {{ message }} </div>
渲染代码:
var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } })
如此便成功创建了第一个 Vue 应用!看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。
通过浏览器控制台输入 app.message="测试" 可以修改vue的数据,会发现一旦数据变化了,vue 管理的页面也发生变化。
为了让用户和你的应用进行交互,我们可以用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法:
<div id="app-5"> <p>{{ message }}</p> <button v-on:click="reverseMessage">反转消息</button> </div>
渲染代码:
var app5 = new Vue({ el: '#app-5', data: { message: 'Hello Vue.js!' }, methods: { reverseMessage: function () { this.message = this.message.split('').reverse().join('') } } })
注意在 reverseMessage 方法中,更新了应用的状态,但没有触碰 DOM。所有的 DOM 操作都由 Vue 来处理,编写的代码只需要关注逻辑层面即可。
练习:
1.在页面中编写一个点击次数统计的功能,点击一次值增加一。
参考代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>练习</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app" style="text-align: center"> <h1>{{count}}</h1> <input type="button" value="增加" v-on:click="add()"> </div> <script> new Vue({ el: "#app", data: { count: 0 }, methods: { add() { this.count++; } } }) </script> </body> </html>
生命周期钩子
每个 Vue 实例在被创建时都要经过一系列的初始化过程。例如:需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
比如 created 钩子可以用来在一个实例被创建之后执行代码:
new Vue({ data: { a: 1 }, created: function () { // `this` 指向 vm 实例 console.log('a is: ' + this.a) } }) // => "a is: 1"
也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mounted、updated 和 destroyed。生命周期钩子的 this 上下文指向调用它的 Vue 实例。
下图展示了实例的生命周期。销毁的事件需要在 vue 脚手架中才能使用。
练习:
1.在上一个练习中使用 created 生命周期函数完成数据从缓存中读取。
参考代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>练习</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app" style="text-align: center"> <h1>{{count}}</h1> <input type="button" value="增加" v-on:click="add()"> </div> <script> new Vue({ el: "#app", data: { count: 0 }, methods: { add() { this.count++; sessionStorage.count = this.count; } }, created() { if (sessionStorage.count) { this.count = sessionStorage.count } } }) </script> </body> </html>
模板语法
1.插值
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:
<span>Message: {{ msg }}</span>
Mustache 标签将会被替代为对应数据对象上 msg 属性的值。无论何时,绑定的数据对象上 msg 属性发生了改变,插值处的内容都会更新。
通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:
<span v-once>这个将不会改变: {{ msg }}</span>
2.原始 HTML
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令:
<p>Using mustaches: {{ rawHtml }}</p> <p>Using v-html directive: <span v-html="rawHtml"></span></p>
这个 span 的内容将会被替换成为属性值 rawHtml,直接作为 HTML——会忽略解析属性值中的数据绑定。
3.Attribute
Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind 指令:
<div v-bind:id="dynamicId"></div>
对于布尔 attribute (它们只要存在就意味着值为 true),v-bind 工作起来略有不同,在这个例子中:
<button v-bind:disabled="isButtonDisabled">Button</button>
如果 isButtonDisabled 的值是 null、undefined 或 false,则 disabled attribute 甚至不会被包含在渲染出来的 <button> 元素中。
4.使用 JavaScript 表达式
迄今为止,在我们的模板中,我们一直都只绑定简单的属性键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。
{{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <div v-bind:id="'list-' + id"></div>
练习:
1.制作一个点击一次在页面增加一张照片的按钮。每次点击都将插入一张相同的照片到页面。
参考代码:
<div id="app" style="text-align: center"> <p v-html="content"></p> <input type="button" value="增加" v-on:click="add()"> </div> <script> new Vue({ el: "#app", data: { content: "" }, methods: { add() { this.content += "<img src=http://58.42.239.163:8888/static/img/noteBook/PAZrEvLF.jpg width='100'>"; } } }) </script>
常用指令
指令(Directives)是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。回顾前面看到的例子:
<p v-if="seen">现在你看到我了</p>
这里,v-if 指令将根据表达式 seen 的值的真假来插入/移除 <p> 元素。
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML attribute:
<a v-bind:href="url">...</a>
在这里 href 是参数,告知 v-bind 指令将该元素的 href 与 attribute 与表达式 url 的值绑定。
另一个例子是 v-on 指令,它用于监听 DOM 事件:
<a v-on:click="doSomething">...</a>
在这里参数是监听的事件名。我们也会更详细地讨论事件处理。
从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数,但是变量名会被 vue 转为小写,所以建议使用下划线命名。
<a v-bind:[attribute_name]="url"> ... </a>
这里的 attribute_name 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,Vue 实例有一个 data 属性 attribute_name,其值为 "href",那么这个绑定将等价于 v-bind:href。
同样地,你可以使用动态参数为一个动态的事件名绑定处理函数:
<a v-on:[event_name]="doSomething"> ... </a>
在这个示例中,当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus。
指令缩写
1.v-bind 缩写
<!-- 完整语法 --> <a v-bind:href="url">...</a> <!-- 缩写 --> <a :href="url">...</a> <!-- 动态参数的缩写 (2.6.0+) --> <a :[key]="url"> ... </a>
2.v-on 缩写
<!-- 完整语法 --> <a v-on:click="doSomething">...</a> <!-- 缩写 --> <a @click="doSomething">...</a> <!-- 动态参数的缩写 (2.6.0+) --> <a @[event]="doSomething"> ... </a>
它们看起来可能与普通的 HTML 略有不同,但 : 与 @ 对于 attribute 名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析。而且,它们不会出现在最终渲染的标记中。缩写语法是完全可选的。
练习:
1.在页面上有一张照片和一个按钮,按钮用于控制照片的显示和隐藏,点击后按钮的文字也变成相应的文字“隐藏”或“显示”。
参考代码:
<div id="app" style="text-align: center"> <p><img v-show="show" src=http://58.42.239.163:8888/static/img/noteBook/PAZrEvLF.jpg width='100'></p> <button v-on:click="add()">{{show?'隐藏':'显示'}}</button> </div> <script> new Vue({ el: "#app", data: { show: true }, methods: { add() { this.show = !this.show; } } }) </script>
数据侦听器
当需要监听数据变化时就需要侦听器。Vue 通过 watch 选项提供了一套更通用的方法,来响应数据的变化。
<div id="watch-example"> <p> Ask a yes/no question: <input v-model="question"> </p> <p>{{ answer }}</p> </div>
渲染代码:
var watchExampleVM = new Vue({ el: '#watch-example', data: { question: '', answer: 'I cannot give you an answer until you ask a question!' }, watch: { // 如果 question 发生改变,这个函数就会运行 question: function (newQuestion, oldQuestion) { this.answer = 'Waiting for you to stop typing...' this.debouncedGetAnswer() } } }) question
练习:
1.做一个输入框文本长度校验,当长度大于 5 后文字变成红色,同时 alert 弹窗警告。
参考代码:
<div id="app" style="text-align: center"> <p><input v-model="input" v-bind:style="inputStyle"></p> </div> <script> new Vue({ el: "#app", data: { input: "", inputStyle: { color: "black" } }, watch: { input(newStr, oldStr) { if (newStr.length > 5) { alert("超出范围"); this.inputStyle.color = "red" } } } }) </script>
Class、Style 绑定
我们可以传给 v-bind:class 一个对象,以动态地切换 class:
<div v-bind:class="{ active: isActive }"></div>
上面的语法表示 active 这个 class 存在与否将取决于数据 property isActive 的 truthiness。
你可以在对象中传入更多字段来动态切换多个 class。此外,v-bind:class 指令也可以与普通的 class attribute 共存。当有如下模板:
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
和如下 data:
data: { isActive: true, hasError: false }
结果渲染为:
<div class="static active"></div>
当 isActive 或者 hasError 变化时,class 列表将相应地更新。例如,如果 hasError 的值为 true,class 列表将变为 "static active text-danger"。
绑定的数据对象不必内联定义在模板里:
<div v-bind:class="classObject"></div> data: { classObject: { active: true, 'text-danger': false } }
v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
渲染模板数据:
data: { activeColor: 'red', fontSize: 30 }
直接绑定到一个样式对象通常更好,这会让模板更清晰:
<div v-bind:style="styleObject"></div>
渲染模板数据:
data: { styleObject: { color: 'red', fontSize: '13px' } }
v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上:
<div v-bind:style="[baseStyles, overridingStyles]"></div>
练习:
1.按照如下设计图完成练习,点击对应的按钮完成如下的星级评分模块。
参考代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>练习</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <style> * { margin: 0; padding: 0 } .stars { margin: 10px; padding: 10px; border: 1px saddlebrown solid; } .stars span { float: left; height: 30px; line-height: 30px; } .stars i { width: 30px; height: 30px; line-height: 30px; float: left; margin-right: 30px; background: #ccc; color: #fff; text-align: center; cursor: default; font-style: normal; } .stars .on { color: #a71417; } </style> </head> <body> <div id="app"> <div class="stars"> <span>商品评价:</span> <i v-bind:class="stars1>=1?'on':''" v-on:click="stars1=1">★</i> <i v-bind:class="stars1>=2?'on':''" v-on:click="stars1=2">★</i> <i v-bind:class="stars1>=3?'on':''" v-on:click="stars1=3">★</i> <i v-bind:class="stars1>=4?'on':''" v-on:click="stars1=4">★</i> <i v-bind:class="stars1>=5?'on':''" v-on:click="stars1=5">★</i> <input type="text" v-model="stars1"/> </div> </div> <script> new Vue({ el: "#app", data: { stars1: 0, }, methods: {} }) .stars { margin: 10px; padding: 10px; border: 1px saddlebrown solid; } .stars span { float: left; height: 30px; line-height: 30px; } .stars i { width: 30px; height: 30px; line-height: 30px; float: left; margin-right: 30px; background: #ccc; color: #fff; text-align: center; cursor: default; font-style: normal; } .stars .on { color: #a71417; } </style> }, methods: {} }) </script> </body> </html>
条件渲染
1.v-if 用于条件限制某节点的渲染与否。
<h1 v-if="awesome">Vue is awesome!</h1>
也可以用 v-else 添加一个“else 块”:
<h1 v-if="awesome">Vue is awesome!</h1> <h1 v-else>Oh no </h1>
vue 2.1.0 新增 v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:
<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>
2.v-show 用于根据条件展示元素的指令。用法与 v-if 大致一样。
<h1 v-show="ok">Hello!</h1>
不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
练习:
1.分别使用 v-show 与 v-if 完成如下操作,点击对应的盒子使其隐藏。
参考代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>练习</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <style> #app { width: 80%; } .box { width: 100px; height: 100px; background: yellow; margin: 10px; float: left; text-align: center; line-height: 100px; font-size: 30px; } </style> </head> <body> <div id="app"> <div v-show="box1" v-on:click="box1=false">1</div> <div v-show="box2" v-on:click="box2=false">2</div> <div v-show="box3" v-on:click="box3=false">3</div> <div v-show="box4" v-on:click="box4=false">4</div> </div> <script> new Vue({ el: "#app", data: { box1: true, box2: true, box3: true, box4: true }, }) </script> </body> </html>
参考2:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <style> #app { width: 80%; } .box { width: 100px; height: 100px; background: yellow; margin: 10px; float: left; text-align: center; line-height: 100px; font-size: 30px; } </style> </head> <body> <div id="app"> <h1 class="box" v-for="d in 4" @click="show(d)" v-if="!redIndex.includes(d)">{{d}}</h1> </div> <script> let vm = new Vue({ el: '#app', data: { redIndex:[], }, methods: { show(data) { this.redIndex.push(data); } } }); </script> </body> </html>
列表渲染
我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
<ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul>
渲染代码:
var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
在 v-for 还支持一个可选的第二个参数,即当前项的索引。
<ul id="example-2"> <li v-for="(item, index) in items"> - {{ index }} - {{ item.message }} </li> </ul>
你也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法:
<div v-for="item of items"></div>
在 v-for 里使用对象,也可以用 v-for 来遍历一个对象的属性。
<ul id="v-for-object"> <li v-for="value in object"> {{ value }} </li> </ul>
渲染代码:
new Vue({ el: '#v-for-object', data: { object: { title: 'How to do lists in Vue', author: 'Jane Doe', publishedAt: '2016-04-10' } } })
你也可以提供第二个的参数为 property 名称 (也就是键名):
<div v-for="(value, name) in object"> {{ name }}: {{ value }} </div>
还可以用第三个参数作为索引:
<div v-for="(value, name, index) in object"> {{ index }}. {{ name }}: {{ value }} </div>
表单输入绑定
你可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
- text 和 textarea 元素使用 value 属性和 input 事件
- checkbox 和 radio 使用 checked 属性和 change 事件
- select 字段将 value 作为 prop 并将 change 作为事件
1.单行文本
<input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
2.多行文本
<p>Message is: {{ message }}</p> <textarea v-model="message" placeholder="add multiple lines"></textarea>
3.复选框
单个复选框,绑定到布尔值:
<input type="checkbox" v-model="checked"> <p>选中:{{ checked }}</p>
多个复选框,绑定到同一个数组:
<div id='example-3'> <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span> </div>
4.单选按钮绑定到普通字符串
<div id="example-4"> <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span> </div>
5.选择框
单选时:
<div id="example-5"> <select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span> </div>
多选时 (绑定到一个数组):
<div id="example-6"> <select v-model="selected" multiple> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ selected }}</span> </div>
用 v-for 渲染的动态选项:
<select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <span>Selected: {{ selected }}</span>
渲染数据:
new Vue({ el: '...', data: { selected: 'A', options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ] } })
组件
组件(Component)是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素,封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
注册一个全局组件语法格式如下:
Vue.component(tagName, options)
tagName 为组件名,options 为配置选项。
注册后,我们可以使用以下方式来调用组件:
<tagName></tagName>
组件虽然在单独使用 vue.js 时使用不多,但在 vue 单页面应用即 vue 脚手架中使用颇多。
<div id="app"> <runoob></runoob> </div> <script> // 注册 Vue.component('runoob', { template: '<h1>自定义组件!</h1>' }) // 创建根实例 new Vue({ el: '#app' }) </script>
Prop
prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。 父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop":
<div id="app"> <child message="hello!"></child> </div> <script> // 注册 Vue.component('child', { // 声明 props props: ['message'], // 同样也可以在 vm 实例中像 "this.message" 这样使用 template: '<span>{{ message }}</span>' }) // 创建根实例 new Vue({ el: '#app' }) </script>
动态 Prop
类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件。
<div id="app"> <div> <input v-model="parentMsg"> <br> <child v-bind:message="parentMsg"></child> </div> </div> <script> Vue.component('child', { props: {'message': {type: String, default: ""}}, template: '<span>{{ message }}</span>' }) new Vue({ el: '#app', data: { parentMsg: '父组件内容' } }) </script>
注意:
1.prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。
2.props 里面的键必须是中划线命名,不能使用驼峰命名。
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。 type 可以是下面原生构造器: String Number Boolean Array Object Date Function Symbol type 也可以是一个自定义构造器,使用 instanceof 检测。
子组件向父组件传值,子组件向父组件传值是通过 emit 方法的方式。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>{{formSon}}</h1> <com2 @func="show"></com2> <com2 @func="show"></com2> </div> <template id="tmpl"> <div> <p>这是子组件</p> <input type="button" :value="son.age" @click="sonClick()"> </div> </template> <script> Vue.component('com2', { template: '#tmpl', data() { return { son: { name: '小头儿子', age: 6 } } }, methods: { sonClick() { this.son.age++; this.$emit('func', this.son) } } }); let vm = new Vue({ el: '#app', data: { formSon: {} }, methods: { show(data) { this.formSon = data } } }); Vue.component('com2', { template: '#tmpl', data() { return { son: { name: '小头儿子', age: 6 } } }, methods: { sonClick() { this.son.age++; this.$emit('func', this.son) } } }); let vm = new Vue({ el: '#app', data: { formSon: {} }, methods: { show(data) { this.formSon = data } } }); </script> </body> </html>
练习:
1.如下商品列表,灰色部分为子组件内容,在子组件中点击按钮可以增加购买数量,每次子组件点击都修改父组件的总价。
参考代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>商品列表</h1> <h3>总价:{{allPrice}}</h3> <p v-for="item in goods"> <span>{{item.name}}</span> <button-counter :price="item.price" @increment="increment"></button-counter> </p> </div> <script> Vue.component('button-counter', { template: ` <div style="background-color: #eee"> <p>价格:{{price}},花费:{{price * count}} <button v-on:click="incrementHandler">数量:{{ count }}</button> </p> </div>`, data: function () { return { count: 0 } }, methods: { incrementHandler: function () { this.count += 1 this.$emit('increment', this.price) } }, props: { price: { type: Number, default: 1 } } }) let app = new Vue({ el: '#app', data: { allPrice: 0, goods: [ {name: "商品1", price: 1}, {name: "商品2", price: 2}, {name: "商品3", price: 3}, ] }, methods: { increment(data) { this.allPrice += data; } } }) Vue.component('button-counter', { template: ` <div style="background-color: #eee"> <p>价格:{{price}},花费:{{price * count}} <button v-on:click="incrementHandler">数量:{{ count }}</button> </p> </div>`, data: function () { return { count: 0 } }, methods: { incrementHandler: function () { this.count += 1 this.$emit('increment', this.price) } }, props: { price: { type: Number, default: 1 } } }) let app = new Vue({ el: '#app', data: { allPrice: 0, goods: [ {name: "商品1", price: 1}, {name: "商品2", price: 2}, {name: "商品3", price: 3}, ] }, methods: { increment(data) { this.allPrice += data; } } }) </script> </body> </html>
本站大部分文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了您的权益请来信告知我们删除。邮箱:1451803763@qq.com