vue:1、构建用户界面
2、只关注视图层
声明式渲染:Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统。
数据的双向绑定
每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。
computed可以侦听属性,设置object的属性的get和set函数
条件渲染
v-if和v-show
相同点:都可以控制某元素的显示和隐藏
不同:
1、v-if是条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
2、v-show:不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
computed和method
这两种方式的计算结果是一样的,不过是同一个函数放在了不同的地方
computer:
|
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
Original message: "Hello"Computed reversed message: "olleH"method:
Reversed message: "{{ reversedMessage() }}"
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
复制代码
但是计算属性是基于它们的依赖进行缓存的,计算属性只有在它的相关依赖发生改变时才会重新求值,这意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。这样可以提高性能
vue-router
顾名思义:将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们
"app">
Hello App!
"/foo">Go to Foo
"/bar">Go to Bar
复制代码
router-Link组件来导航,
通过传入to属性来指定连接
// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = { template: 'foo' }
const Bar = { template: 'bar' }
// 2. 定义路由//确定映射关系
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')
// 现在,应用已经启动了!复制代码
通过注入路由器,我们可以在任何组件内通过 this.$router
访问路由器,也可以通过 this.$route
访问当前路由:
// Home.vue
export default {
computed: {
username () {
// 我们很快就会看到 `params` 是什么
return this.$route.params.username
}
},
methods: {
goBack () {
window.history.length > 1
? this.$router.go(-1)
: this.$router.push('/')
}
}
}复制代码
该文档通篇都常使用 router
实例。留意一下 this.$router
和 router
使用起来完全一样。我们使用 this.$router
的原因是我们并不想在每个独立需要封装路由的组件中都导入路由。
声明式
模式 | 匹配路径 | $route.params |
---|---|---|
/user/:username | /user/evan | { username: 'evan' } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: 'evan', post_id: 123 } |
一个“路径参数”使用冒号 :
标记。当匹配到一个路由时,参数值会被设置到 this.$route.params
命名路由
"{ name: 'user', params: { userId: 123 }}">User
router.push({ name: 'user', params: { userId: 123 })复制代码
编程导航
router.push({ name: 'user', params: { userId: 123 })复制代码
注意:在 Vue 实例内部,你可以通过 $router
访问路由实例。因此你可以调用 this.$router.push
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
复制代码
跟 router.push
很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
声明式 | 编程式 |
---|---|
|
router.replace(...) |
前进
router.go(1)复制代码
命名视图
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar
(侧导航) 和 main
(主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view
没有设置名字,那么默认为 default
。
"view one">
"view two" name="a">
"view three" name="b"> 复制代码
一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components
配置 (带上 s):
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})复制代码
重定向和命名
重定向也是通过 routes
配置来完成,下面例子是从 /a
重定向到 /b
:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
复制代码
“重定向”的意思是,当用户访问 /a
时,URL 将会被替换成 /b
,然后匹配路由为 /b
,那么“别名”又是什么呢?
/a
的别名是 /b
,意味着,当用户访问 /b
时,URL 会保持为 /b
,但是路由匹配则为 /a
,就像用户访问 /a
一样。
上面对应的路由配置为:
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})复制代码
路由组件传参
函数模式
const router = new VueRouter({
routes: [
{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
]
})复制代码
URL /search?q=vue
会将 {query: 'vue'}
作为属性传递给 SearchUser
组件。
对象模式
如果 props
是一个对象,它会被按原样设置为组件属性。当 props
是静态的时候有用。
const router = new VueRouter({
routes: [
{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
]
})复制代码
虚拟DOM
我做过测试,一个只有id属性的div,遍历一遍,有235个属性或方法,同时浏览器还要计算css属性,如果频繁的操作DOM的话,对于性能影响会很大。
虚拟DOM就是用一个原生的js对象来描述一个DOM节点,现代浏览器运行js的速度非常快,所以在js对象里来对DOM做一些操作会比直接操作DOM代价小的多。
Virtual DOM 除了它的数据结构的定义,映射到真实的 DOM 实际上要经历 VNode 的 create、diff、patch 等过程。那么在 Vue.js 中,VNode 的 create 是通过之前提到的 createElement
方法创建的
Vue把挂载的DOM的子节点都劫持到fragment里,然后保存以js对象的形式,
在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。