vue相关语法知识点
一、文本传值
<template>
<div id="app">
{{title}}
</div
</template>
<script>
export default {
name: 'App',
data(){
return{
title:"第一个vue项目",
}
}
}
</script>
<style>
#app {
color: red;
margin-top: 60px;
}
</style>
首先通过这个例子来介绍vue的一些基础语法和基础结构,一个vue项目主要由html结构,处理逻辑和样式组成,对应的就是这里的template,script,style,从这个例子就是可以看出一个最基础的vue项目的模板,为了规范,一般来说,根容器div 的id和下面的name会和该vue项目取一样的名字,script中的data用于数据的存储,一般这里就是在data中申明属性,也可以给出属性的初始值,在实例代码中,定义了一个title的属性并给它的初始值为“第一个vue项目”,现在属性已经申明并且给出了初始值,想要让这句话展示在我们的页面上,就需要让html拿到我们的属性的值,这就需要完成数据绑定,在vue中是通过使用{{}}来完成数据绑定,同时在下面的style中完成对样式的设置。
二、属性(v-bind)
<template>
<div id="app">
<span v-bind:title="message">
<a :href="url">
鼠标悬停查看此处动态绑定的提示信息!
</a>
</span>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
message: '页面加载于 ' + new Date().toLocaleString(),
url:"https://www.baidu.com/",
}
}
}
</script>
<style>
#app {
margin-top: 60px;
}
</style>
在这个例子中首先申明了两个属性message 和url ,message 显示的是一条页面加载的时间,url定义了一个网址,在html结构中,使用了属性绑定v-bind指令,通过v-bind:title把message 属性绑定到了这个span标签上,在vue中属性的绑定可以把v-bind省略,就像这里把url属性绑定到a标签上,通过鼠标悬浮可以看到页面加载时间,这个就是message属性,点击跳转页面,这里页面的网址就是url。
三、条件判断(v-if)
<template>
<div v-if="seen">
你看到我啦
</span>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
seen:false
}
}
}
</script>
<style>
#app {
margin-top: 60px;
}
</style>
在这一个例子中介绍v-if条件判断指令,同样定义seen属性为false,在html结构中在根容器div上使用了vif条件判断指令对seen属性进行判断,若为真则在页面上会显示文字,若为假则不显示。通过对seen的值的判断,可以决定是都显示文本内容。
四、循环(v-for)
<template>
<div>
<ul>
<li v-for="character in characters">{{character}}</li>
</ul>
<ul>
<li v-for="(ninja, index) in ninjas">{{ index }} . {{ ninja.name }} - {{ ninja.age }}</li>
</ul>
<ul>
<li v-for="(value, key) in object">{{ key }} : {{ value }}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
characters: ['Mario', 'Luigi', 'Yoshi', 'Bowser'],
ninjas: [
{ name: 'Ryu', age: 25 },
{ name: 'Yoshi', age: 35 },
{ name: 'Ken', age: 55 }
],
object: {
name: 'app',
url: 'http://www.baidu.com',
slogan: '开心最重要!'
}
}
}
}
</script>
<style>
#app {
margin-top: 60px;
}
</style>
这个例子主要介绍的是v-for循环指令,定义了一个characters 数组,ninjas对象数组和object对象,现在要做的就是去遍历数组拿到里面的内容,可以直接通过数组下标的形式拿到内容,但是这样在实际项目中是不切实际的,就可以通过ul标签中的li标签使用循环指令vfor去遍历出characters 数组中的所有内容,同样通过{{}}来数据绑定。
同样,也可以提供两个参数,当前ninjas 是数组,ninja 拿到的就是一个对象,就可以用对象.属性的形式拿到里面具体的内容。
五、绑定事件(v-on)
<template>
<div>
<button v-on:click="num++">+1</button>
<button @click="num--">-1</button>
<button v-on:click="addtwo()">+2</button>
<button v-on:click="subtract(5)">-5</button>
<p>num is {{num}}</p>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
num:10,
}
},
methods:{
addtwo:function(){
this.num=this.num+2;
},
subtract:function(dec){
this.num=this.num-dec;
}
},
}
</script>
<style>
#app {
margin-top: 60px;
}
</style>
这个例子介绍的是事件,通过这个例子介绍通过事件去改变属性,v-on就是用来绑定事件的 ,click事件,doubleclick事件,鼠标事件,键盘事件,在data中申明了num,初始值为10,在这里通过v-on绑定了点击事件,点击之后num加1,同样v-on可以简写为一个@,这里实现了num减1,但是在实际中我们不会就在这里对属性做一些操作,我们会把这一块的业务逻辑在我们script中去实现,我们把这些对属性的操作写在指定的方法里面,这里加2就是写在addtwo 这个方法中,在vue中所有的方法就写在methods里面,这是固定写法,addtwo:function() ,接下来就要操作当前属性,要拿到属性就只要this.num就可以了,这样就实现了加2的这个方法并且绑定事件到按钮上了,需要说明一点,这里加不加括号都是可以的,但是在使用{{}}去使用方法的时候就一定要加括号,不然它会识别为属性,在事件中如果有传参的话也是一定要有括号的,就比如这里通过参数的形式去是减5这个方法,就用dec来接收参数。
六、双向数据绑定(v-model)
<template>
<div>
<label>姓名:</label>
<input type="text" v-model="name">
<span>{{name}}</span>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
name:""
}
}
}
</script>
<style>
label{
display: block;
margin: 20px 0 10px
}
</style>
双向数据绑定一定是和input,select,textarea相关的,因为这第三个标签可以去输入,输入后就可以输出,在vue中是通过v-model 实现数据的双向绑定的,在这里我们把name这个属相绑定在input输入框上,同时我们在span标签中把name显示出来,可以观察到随着输入框中的变化,span标签中的文本也会跟着变化。
七、组件嵌套
实现组建的嵌套4个vue文件来实现。其中app.vue为父组件,header.vue组件、content.vue组件和footer.vue组件为子组件。
app.vue的代码如下:
<template>
<div>
<div class="text" v-bind:title="title">{{title}}</div>
<app-header></app-header>
<app-content></app-content>
<app-footer></app-footer>
<app-header></app-header>
</div>
</template>
<script>
// Imports
import Header from './components/Header.vue';
import Content from './components/Content.vue';
import Footer from './components/Footer.vue';
export default {
components: {
'app-header': Header,
'app-content': Content,
'app-footer': Footer,
},
data () {
return {
title:"hello"
}
},
methods:{
}
}
</script>
<style scoped>
body{
margin: 0;
font-family: 'Nunito SemiBold';
}
.text{
font-size: 200px;
color:pink;
}
</style>
header.vue的代码如下:
<template>
<header @click="changetitle">
<h1>{{ title }}</h1>
</header>
</template>
<script>
export default {
data(){
return{
title: '这是header'
}
},
methods:{
changetitle:function(){
this.title="已经改变title啦!!"
// this.$emit("tc","子向父传值成功啦");
}
},
}
</script>
<style scoped>
header{
background: lightgreen;
padding: 10px;
}
h1{
color: #222;
text-align: center;
}
</style>
content.vue的代码如下:
<template>
<div id="content">
<ul>
<li v-for="arr in arrs" v-on:click="arr.show = !arr.show">
<h2>{{ arr.name }}</h2>
<h3 v-show="arr.show">{{ arr.age }}</h3>
</li>
</ul>
</div>
</template>
<script>
export default {
data(){
return{
arrs: [
{name: 'AA', age: 10, show: false},
{name: 'BB', age: 20, show: false},
{name: 'CC', age: 30, show: false}
],
}
},
}
</script>
<style scoped>
#content{
width: 100%;
max-width: 1200px;
margin: 40px auto;
padding: 0 20px;
box-sizing: border-box;
}
ul{
display: flex;
flex-wrap: wrap;
list-style-type: none;
padding: 0;
}
li{
flex-grow: 1;
flex-basis: 300px;
text-align: center;
padding: 30px;
border: 1px solid #222;
margin: 10px;
}
</style>
footer.vue的代码如下:
<template>
<footer>
<p>{{ copyright }}</p>
</footer>
</template>
<script>
export default {
data(){
return{
copyright: '这是footer'
}
}
}
</script>
<style scoped>
footer{
background: #222;
padding: 6px;
}
p{
color: lightgreen;
text-align: center;
}
</style>
效果图如下:
首先,header.vue组件中实现的是显示title属性,并且还绑定了一个点击事件,当点击是可以实现tltle的改变。content.vue组件中实现的是通过v-for循环遍历出arrs数组中的对象并且显示对象中的属性,同时绑定了点击事件来改变show属性的值,根据show的值可以改变arr.age的可见性。footer.vue组件中实现的是显示copyright。
本来这三个组件都是相对独立的组件,想要在一个页面中同时显示这三个组件就需要通过组件嵌套来实现,如实例代码,将header、content、footer三个组件作为子组件全部显示在父组件app中。想要在父组件app中使用其他的组件,只需要import+注册即可。
八、组件传值--父组件向子组件
在组件嵌套的实例代码中,子组件content中的数组是直接定义在它自己的data中,但是在实际项目中,假如有很多组件都要用到arrs数组,开发者是不可能在每一个子组件中去定义一遍arrs数组的。最好的解决办法就是将arrs数组抽离出来,定义在父组件中,然后再传递给需要的子组件去调用。
如果将arrs数组写在父组件app中,那么,如何才能将arrs数组传递到子组件中呢?这就需要找到父组件app和子组件content的契合点,就是在父组件app的template中的<app-content></app-content>,在这个契合点将arrs数组绑定上去,再去子组件content中去拿就可以了。
而对于子组件content,只需要用props属性中去接收数据即可。这样通过父组件向子组件传值的效果和组件嵌套中的实例代码中效果是一致的。
app.vue的代码如下:
<template>
<div>
<div class="text" v-bind:title="title">{{title}}</div>
<app-header></app-header>
<app-content v-bind:arrs="arrs"></app-content>
<app-footer></app-footer>
<app-header></app-header>
</div>
</template>
<script>
// Imports
import Header from './components/Header.vue';
import Content from './components/Content.vue';
import Footer from './components/Footer.vue';
export default {
components: {
'app-header': Header,
'app-content': Content,
'app-footer': Footer,
},
data () {
return {
arrs: [
{name: 'AA', age: 10, show: false},
{name: 'BB', age: 20, show: false},
{name: 'CC', age: 30, show: false}
],
title:"hello"
}
},
methods:{
}
}
</script>
<style scoped>
body{
margin: 0;
font-family: 'Nunito SemiBold';
}
.text{
font-size: 200px;
color:pink;
}
</style>
content.vue的代码如下:
<template>
<div id="content">
<ul>
<li v-for="arr in arrs" v-on:click="arr.show = !arr.show">
<h2>{{ arr.name }}</h2>
<h3 v-show="arr.show">{{ arr.age }}</h3>
</li>
</ul>
</div>
</template>
<script>
export default {
data(){
return{
}
},
props:["arrs"]
}
</script>
<style scoped>
#content{
width: 100%;
max-width: 1200px;
margin: 40px auto;
padding: 0 20px;
box-sizing: border-box;
}
ul{
display: flex;
flex-wrap: wrap;
list-style-type: none;
padding: 0;
}
li{
flex-grow: 1;
flex-basis: 300px;
text-align: center;
padding: 30px;
border: 1px solid #222;
margin: 10px;
}
</style>
九、组件传值--子组件向父组件
在实际的项目开发,也经常会有子组件向父组件传值的情况。还是以组件嵌套中的代码为例,子组件header中有title这个属性,现想要通过子组件header的点击事件来改变父组件app中的title,就需要用到子组件向父组件传值。
首先需要在子组件header的changetitle方法中去注册一个事件,注册事件用到的就是this.emit(),注册事件时,第一个参数表示你要注册的时间的名字,第二个参数表示你要传递的内容。比如注册一个叫tc的事件,传递的内容就是“子组件向父组件传值成功”。
接下来就需要在父组件app中去绑定tc,绑定的时间名字应该和注册时取的名字一样。在父组件app和子组件header的契合点<app-header></app-header>处绑定tc事件,执行的是updatetitle的方法,而该方法只需要在父组件app中去定义即可。
app.vue的代码如下:
<template>
<div>
<div class="text" v-bind:title="title">{{title}}</div>
<!-- <app-header></app-header> -->
<app-header v-on:tc="updatetitle($event)"></app-header>
<app-content v-bind:arrs="arrs"></app-content>
<app-footer></app-footer>
<app-header></app-header>
</div>
</template>
<script>
// Imports
import Header from './components/Header.vue';
import Content from './components/Content.vue';
import Footer from './components/Footer.vue';
export default {
components: {
'app-header': Header,
'app-content': Content,
'app-footer': Footer,
},
data () {
return {
arrs: [
{name: 'AA', age: 10, show: false},
{name: 'BB', age: 20, show: false},
{name: 'CC', age: 30, show: false}
],
title:"hello"
}
},
methods:{
updatetitle(title){
this.title=title;
}
}
}
</script>
<style scoped>
body{
margin: 0;
font-family: 'Nunito SemiBold';
}
.text{
font-size: 200px;
color:pink;
}
</style>
header.vue的代码如下:
<template>
<header @click="changetitle">
<h1>{{ title }}</h1>
</header>
</template>
<script>
export default {
data(){
return{
title: '这是header'
}
},
methods:{
changetitle:function(){
this.title="已经改变title啦!!"
this.$emit("tc","子向父传值成功啦");
}
},
}
</script>
<style scoped>
header{
background: lightgreen;
padding: 10px;
}
h1{
color: #222;
text-align: center;
}
</style>
效果图如下:
image.png