前言
本篇内容是第一章vue语法的最后一篇,通过本篇内容,我们将大致了解vue中的v-bind指令和组件的一些概念。大家可以通过下面链接了解vue的其他语法基础。
【Vue3从零开始-第一章】1-1 Hello world和计数器
【Vue3从零开始-第一章】1-3 v-for和v-model指令
下面的内容将在1-3
的代码基础上带大家一起学习。
v-bind
在前面的几篇内容里面,我们经常会用到{{}}
这样的格式去显示动态值,那么{{}}
是什么意思呢?为啥可以显示出动态的值呢?
- 在vue里面,
{{}}
表示插值表达式,在表达式里面可以做一些简单的js
操作,也可以动态渲染data
方法里面的值
- 在
1-3
的代码中,我们知道了双向数据绑定,在数据绑定的时候,我们也会用到这样的插值表达式去动态显示input
中绑定的值。
Vue.createApp({ data() { return { inputValue: '' } }, template: ` <div> <input v-model="inputValue" /> <div>{{inputValue}}</div> </div> ` }).mount('#root'); 复制代码
如果我们要在button
标签上面,当鼠标放到标签上时,会显示inputValue
的值,也就是给标签上的某个属性绑定一个动态值,我们可以不可以直接这样写呢?
template: ` <div> <input v-model="inputValue" /> <button v-on:click="handleAddItem" title="inputValue">增加</button> </div> ` 复制代码
在浏览器中打开后,我们发现按钮上的title
属性显示的是一个字符串
inputValue
,那我们可不可以在title
属性中使用上面说的插值表达式呢?
template: ` <div> <input v-model="inputValue" /> <button v-on:click="handleAddItem" title="{{inputValue}}">增加</button> </div> ` 复制代码
- 现在我们看到的是
title
属性直接显示了{{inputValue}}
字符串,没有渲染出我们想要的效果,那么这时候我们就要用到一个新的指令:v-bind
- 在使用
v-bind
时,不需要添加{{}}
插值表达式的写法
template: ` <div> <input v-model="inputValue" /> <button v-on:click="handleAddItem" v-bind:title="inputValue">增加</button> </div> ` 复制代码
现在我们可以在浏览器中看到一个另类的双向数据绑定的效果了,也就是用v-bind
将data
中的值动态绑定到标签的属性值中显示。
小结一下
{{}}
插值表达式是在标签之间使用,且可以动态输出data
中的值。
v-bind
指令是在标签上使用,也可以动态输出data
中的值。
component组件
组件的概念不仅仅在vue里面有效,在整个前端的发展中都是有效的。那什么是组件呢?
- 组件就是一个页面上的一部分 下面的图片中显示的红色框和蓝色框都可以看做是一个又一个的组件
<li v-for="(item, index) of list"> <div> <span>{{index}}</span> <span> - </span> <span>{{item}}</span> </div> </li> 复制代码
在项目中,我们往往会在一个标签里面嵌套很多标签来渲染我们需要显示出来的内容,但是这样的标签太多了之后,就会显得页面很臃肿,那么我们就可以把一些公共的地方拆分出来,单独做成一个组件去渲染。
下面我们就把1-3
中的TodoList
代码拆分出来。
首先我们要给vue的实例取一个名字
const app = Vue.createApp() 复制代码
为什么要取一个名字呢?因为我们要在这个app
上去注册一些组件
app.component() 复制代码
注册组件之后呢,也要给这个组件取一个名字todo-item
,后面跟着一个对象描述了这个组件对应的内容
app.component('todo-item', {}) 复制代码
组件有了,我们就要将TodoList
代码中的li
标签拆分出来,然后开始写组件中的代码
const app = Vue.createApp({ data(){ return { inputValue: '', list: [] } }, methods: { handleAddItem(){ this.list.push(this.inputValue) this.inputValue = '' } }, template: ` <div> <input v-model="inputValue" /> <button v-on:click="handleAddItem">增加</button> <ul> <todo-item v-for="(item, index) of list" /> </ul> </div> ` }).mount('#root'); app.component('todo-item', { template: '<div>hello world</div>' }) 复制代码
- 我们在vue实例
app
上注册了一个组件,这个组件的名字叫todo-item
,然后将组件放到ul
标签中渲染出来
但是这时候我们刷新页面会发现,浏览器的Console
报错了,找不到app.component
这个方法。
那是因为我们在vue实例之后直接就挂载到root
上了,挂载之后再去注册组件,是找不到组件的,那么我们就要改一下注册和挂载的逻辑顺序了。
const app = Vue.createApp({ data(){ return { inputValue: '', list: [] } }, methods: { handleAddItem(){ this.list.push(this.inputValue) this.inputValue = '' } }, template: ` <div> <input v-model="inputValue" /> <button v-on:click="handleAddItem" v-bind:title="inputValue">增加</button> <ul> <todo-item v-for="(item, index) of list" /> </ul> </div> ` }); app.component('todo-item', { template: '<div>hello world</div>' }); app.mount('#root'); 复制代码
先注册一个vue实例,取名为
app
,然后在实例上注册一个组件todo-item
,最后将实例挂载到root
上渲染出来
一个组件里面,不仅包含了这个组件的DOM
结构,还应该包含这个组件的数据和js
逻辑,从上面的组件代码中可以看到,我们在DOM
结构上直接写死了数据,那下面我们就写一下组件上动态的渲染。
app.component('todo-item', { data(){ return { item: 'Hello Dell' } }, template: '<div>{{item}}</div>' }); 复制代码
- 通过组件代码可以看出,组件里面的逻辑代码和vue实例里面的逻辑代码基本是一致的,都是通过
data
方法来定义动态的渲染值。
虽然组件已经动态渲染了data
里面定义的值,但是不能每次都渲染同样的数据,应该让组件渲染vue实例中的list
里面的每一项数据,那么我们就可以通过上面学到的v-bind
指令来定义了。
<ul> <todo-item v-for="item of list" v-bind:content="item" /> </ul> 复制代码
- 在组件上绑定一个属性,这个属性的名字叫
content
,值是item
,item
就是list
中的每一项值
app.component('todo-item', { props: ['content'], template: '<div>{{content}}</div>' }); 复制代码
- vue实例中调用
todo-item
组件的时候,在组件上绑定了一个content
的属性,那么组件上就要接收这个属性,在组件上用props
接收一个叫content
的属性值,并把这个属性值放到DOM
中的插值表达式中渲染出来。
在1-3
中的例子中,我们还渲染了list
的下标index
,那么在组件中渲染出来也是需要从实例传给组件的,方法和上面的一样。
<ul> <todo-item v-for="(item, index) of list" v-bind:content="item" v-bind:index="index" /> </ul> 复制代码
app.component('todo-item', { props: ['content', 'index'], template: '<div>{{index}} - {{content}}</div>' }); 复制代码
- 在调用
todo-item
组件的时候,同样绑定一个属性index
,然后在组件中去接收index
,同时用插值表达式渲染出来。
总结
在上面的例子中,我们都用到了v-bind
指令来绑定一些属性值,同时也用到了组件和组件之间的传值的过程,有什么不明白的地方,可以在评论区留言讨论讨论哦~