您当前的位置:首页 > 文章 > vue基本使用

vue基本使用

作者:返回主页柠檬色的橘猫 时间:2023-05-30 阅读数:352 人阅读

1.基本使用

本篇的主要内容有:

  1. vue 的安装
  2. 生命周期钩子
  3. 模板语法
  4. 常用指令
  5. 数据侦听器
  6. Class、Style 绑定
  7. 条件渲染
  8. 列表渲染
  9. 表单输入绑定
  10. 组件
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;
    }

&lt;/style&gt;




</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;
    }

&lt;/style&gt;
    },
    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: `
        &lt;div style="background-color: #eee"&gt;
            &lt;p&gt;价格:{{price}},花费:{{price * count}}
                &lt;button v-on:click="incrementHandler"&gt;数量:{{ count }}&lt;/button&gt;
            &lt;/p&gt;
        &lt;/div&gt;`,
    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: `
        &lt;div style="background-color: #eee"&gt;
            &lt;p&gt;价格:{{price}},花费:{{price * count}}
                &lt;button v-on:click="incrementHandler"&gt;数量:{{ count }}&lt;/button&gt;
            &lt;/p&gt;
        &lt;/div&gt;`,
    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