- 声明式渲染:
v-bind
数据双向绑定
v-bind:title="message"
和浏览器控制台执行app.message="new message"
,这就是MVVM
数据双向绑定实时修改数据的体现,另外表单输入和应用状态之间的双向绑定可以使用v-model="message"
和{{ message }}
,数据的具体内容由vue
实例中data
控制。
- 条件
v-if
与循环v-for
v-if="seen"
之后你只要js控制data
中seen
的bool
值即可控制数据的显示和隐藏,您也可以利用数据双向绑定在浏览器控制台输入app.seen = false
查看。
<li v-for = "todo in todos">
在数据内容中使用模版语法双大括号{{ todo.text}}
即可在li标签中循环输出数据。当然,data
数组中的todos
需要写上这样的三个对象数据{ text: '第一,学习JavaScript' }
。
至于在列表中添加或者删除数据项,您可以使用js
修改todos
内容,或者在浏览器控制台输入app.todos.push({ text: '新项目' })
测试添加列表项。
- 处理用户输入:
v-on
事件监听器
<button v-on:click="reverseMessage">逆转消息</button>
,这时在methods
的reverseMessage
方法中反转字符顺序:this.message = this.message.split('').reverse().join('')
。我们并没有进行DOM
操作,因为Vue
已经在背后帮我们做完了。
- 组件化思想:注册
todo-item
全局组件:
Vue.component('todo-item', {
template: '<li>这是个新注册的待办项组件</li>'
})
在
html
页面中你可以直接使用todo-item
标签创建组件实例:<todo-item></todo-item>
。但是这样会为每个待办项实例渲染同样的文本,我们应该能从父组件将数据传到子组件才对。让我们来修改一下组件的定义,使之能够接受一个 props:
Vue.component('todo-item', {
// todo-item 组件现在接受一个"prop",类似于一个自定义特性
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
这时候我们重新构建起来:在
html视图
中使用绑定循环输出data
中todo-list
变量数据:
<ol>
<!--
现在我们为每个 todo-item 提供 todo 对象
todo 对象是变量,即其内容可以是动态的。
我们也需要为每个组件提供一个“key”,稍后再
作详细解释。
-->
<todo-item v-for="item in todo-list" v-bind:todo="item" v-bind:key="item.id">
</todo-item>
</ol>
data: {
todo-list: [
{ id: 0, text: '蔬菜' },
{ id: 1, text: '奶酪' },
{ id: 2, text: '随便其它什么人吃的东西' }
]
}
-
那么重点来了:实现同样的效果,为什么我们推荐使用更为麻烦且代码量更多的后者呢?首先我们使用了组件化思想将一整个系统划分为了互不干扰的几个组件,并且这几个组件之间可以存在内外层或者同级间的通讯关系,子组件可以通过
prop
接口与父组件进行了良好的通讯解耦。因此我们认为一个优秀的vue项目最终视图上的代码格式使用vue
组件后应该是这样的:
<div id="app">
<app-nav></app-nav>
<app-view>
<app-sidebar></app-sidebar>
<app-content></app-content>
</app-view>
</div>
-
Vue
组件与自定义元素的关系
w3c
草案正在准备的内容有自定义web
组件,和vue
组件及其类似但也有很大不同。比如vue
组件有独特的跨组件数据流
、自定义事件通信
以及构建工具集成
,但草案中的web
组件需要考虑浏览器原生支持能力,还要做更多的兼容适配。
-
Vue
实例和组件拆分
一个
Vue
应用由一个通过new Vue
创建的 根 Vue 实例,以及可选的嵌套的、可复用的组件树组成,简单说就是Vue项目=Vue实例+组件树
。举个例子,一个todo
应用的组件树可以是这样的:
根实例
└─ TodoList
├─ TodoItem
│ ├─ DeleteTodoButton
│ └─ EditTodoButton
└─ TodoListFooter
├─ ClearTodosButton
└─ TodoListStatistics
- 数据和方法
vue
官方把mvvm
导致的data
属性值和视图效果绑定这种现象称谓vue响应式系统
:
// 我们的数据对象
var data = { a: 1 }
// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
data: data
})
// 获得这个实例上的属性
// 返回源数据中对应的字段
vm.a == data.a // => true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // => 2
// ……反之亦然
data.a = 3
vm.a // => 3
- 属性绑定
v-bind
v-bind:title="'this is ' + title"
这种形式,可以简写成:title="xxxx"
。v-on:click=""
这种事件绑定也可以简写成@click
。这种属性绑定用于input
时并不能达到数据双向绑定的效果,所以会使用v-model
进行数据双向绑定。
- 计算属性和侦听器
计算属性
fullName
的值是由firstName
和lastName
共同计算得出,这时候在computed
中定义fullName
和返回语句即可。在watch
中设置监听某个数据发生改变后触发的函数,该函数可以进行计数器count
的增减操作,也可以进行一些其他提示等等,这就是侦听器。
-
v-if
和v-show
数据的显示和隐藏
首先定义
show: true
,其次在模板中v-if= "show"
这就是mvvm
思想。虽然可以不定义show
这个数据,直接v-if="true/false"
也可以实现效果,但这不是以数据为中心的思想哦。使用两者的效果都是一样的,但是v-show
仅仅是添加display: none
属性隐藏内容,而v-if
会进行DOM结点的销毁,一般更推荐使用前者v-show
。
- 数据列表的循环显示
v-for
数据定义数组,模板中使用
<li v-for="item of list"> {{ item }} </li>
这种语法。使用v-for
时候必须使用:key="item"
以提高效率,其中key
值不能重复。当循环列表中又重复数据时显然会出现点问题,于是我们重新改动一下模板代码:li v-for="(item,index) of list :key="index"> {{ item }} </li>
,添加了一个index
索引方便查找每一项。其实在排序列表时,使用index
一样存在一些问题。
一个简单的的
image.pngTodo-List
- 关于
vue
组件通讯后的Todo-List
image.png
介绍:vue
组件包括全局组件和局部组件,局部组件需要在data.components
中一对一声明才能使用。推荐使用图中的方式让vue
指令换行显示。外层app
父组件往todo-list
子组件传递一个名为item
的数据时,使用:content="item"
,但这样子组件中还是无法用插值表达式输出item
。这时候我们在定义组件的同时声明一个pros
数组用来接收content
数据就可以了。
注意:指令:content
,pros数组接收值
和插值表达式值三者的命名都应该是一样的,不局限于叫做content
。
- 也就是说在
Vue
中,父组件是通过属性的形式向子组件传递值。
- 那么子组件怎么告诉父组件删除某个父组件数据呢,这就是
发布订阅模式
了。首先局部组件模板中当子组件内容被点击后需要触发handleClick
函数,并且这个函数需要获取你点击的index
,我们可以通过:index=index
,pros:['index']
将index
从父组件传递到子组件中,同时当子组件中的index
项被点击后,通过发布订阅模式我们将index
传递回父组件,这时候我们要使用v-on:delete="handleDel"
设置侦听器监听handleClick
函数中this.$emit('delete', this.index)
的delete
事件,这个事件发生后触发父组件的handleDel
函数。
- 把父子组件传值说的再简单一点吧:父组件import子组件,并在components中注册得到子组件模版名称。
- 在template中渲染子组件的同时传递一个对象给子组件:<cart :foodIns="food"></cart>
这里的food就是父组件data中的变量,传递到子组件中给了个别名叫做foodIns。
- 子组件使用props接受到这个food之后,在子组件中相当于data多出了一个名为foodIns的变量。
- 那么子组件如何向父组件发送数据?Vue中有两个不成文规定:子组件中不能修改pros值,子组件不能向父组件传递值。实际上两者都可以,而且都很常用。
- 首先父组件发送数据给子组件时,预先定义好一个名为XXX=YYY的监听函数,然后在子组件中定义一个事件触发子组件中的A函数。
A函数中使用this.$emit('XXX',data)这种发布订阅模式的写法,将子组件的data值通过父子组件都有的XXX这个监听事件绑定发送给了父组件的YYY函数去处理。
YYY函数在定义时只需要带上这个data参数就可以使用子组件的这个值。
由于此时子组件需要删除的项的index
已经传递出来,在父组件的handleDel
方法中我们可以带上参数index
,并通过this.list.splice(index, 1)
删除该index
项。
- 请注意父子组件点击函数中的两个方法,还有父子组件数据传递的方法:
props
和$emit发布订阅模式
。
image.png
-
vue-cli
的安装和基本使用
`npm i --global vue-cli` 全局安装该脚手架工具
`vue-cli init webpack todolist` 创建基于webpack的vue项目
`cd todolist && npm run dev` 安装依赖并热启动项目
注意,npm源请手动修改为`taobao repo`。
-
vue-cli
使用单文件组件,
网友评论