Vue基础
声明式渲染:
<div id="app">
{{ message }}
<button v-on:click="reverseMessage">反转消息</button>
<p>"{{ reversedMessage }}"</p>
</div>
//每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的
var app = new Vue({
el: '#app', // 挂载dom
data: {
message: 'Hello Vue!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
})
new Vue 创建Vue对象;
el: 指定id绑定DOM,接管DOM操作;
data:当一个 Vue 实例被创建时,它将 data
对象中的所有的属性加入到 Vue 的响应式系统中。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值;
{{xxxxx}} 显示数据;
{{xxx}}还可以显示单个表达式:
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
methods: 在 methods
对象中定义方法
computed: 计算属性(计算属性是基于响应式依赖进行缓存的,就是只要 message
还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数值不变)
watch:侦听属性,用于观察和响应 Vue 实例上的数据变动,用于执行异步或开销较大的操作
created: function ():Vue对象创建时执行的函数,定义在这里语句在开始就会执行
Vue常用指令
v-text
v-html <span v-html=“rawHtml”> 解析html
v-once <span v-once>只显示一次
v-if <v-if=“seen”>条件渲染
如果想切换多个元素,可以把一个 template
元素当做不可见的包裹元素,并在上面使用v-if
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
v-else
v-else-if
v-show 根据条件展示元素,但是带有 v-show
的元素始终会被渲染并保留在 DOM 中。v-show
只是简单地切换元素的 CSS 属性 display
v-for <li v-for=“item in items”>列表循环(items
是一个数组[ ]),也可以用 of
替代 in
作为分隔符
<li v-for="(item, index) in items">
也可以用 v-for
来遍历一个对象的属性,对于如下对象:
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
遍历<div v-for="(value, name, index) in object">分别对应属性,键名和索引
建议尽可能在使用 v-for
时提供 key
attribute,给 Vue 一个提示,以便它能跟踪每个节点的身份,从 而重用和重新排序现有元素。用字符串或数值类型的值来作为key
的参数
<div v-for="item in items" v-bind:key="item.id">
<!-- 内容 -->
</div>
v-on :参数,绑定相应的事件
v-on:click <button v-on:click=“reverseMessage”>绑定点击事件
@click 缩写,等价于<a v-on:click=“doSomething”>
@change
Vue.js 为 v-on
提供了事件修饰符
.stop
<a v-on:click.stop=“doThis”></a>阻止单击事件继续传播.prevent
.capture
.self
.once
.passive
v-on:keyup.enter 在监听键盘事件时,检查详细的按键,这里enter可以替换为其他任何按键
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
还可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器
.ctrl
.alt
.shift
.meta
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
v-bind >div v-bind:id=“dynamicId”<绑定元素的特性
在这里 id
是参数,告知 v-bind
指令将该元素的 id
attribute 与表达式 dynamicId
的值绑定
动态参数:<a v-bind:[attributeName]=“url”>
Vue 实例有一 data
属性 attributeName
,其值为 "href"
,那么这个绑定将等价于 v-bind:href
缩写 <a :href=“url”>等价于<a v-bind:href=“url”>
v-model <input v-model=“message”>可以实现数据双向绑定,改变了这里的值,其他地方也根据改变
v-ref
v-el
v-pre
v-cloak
number
debounce
transition
:is
Vue的生命周期
组件
直接使用Vue.component()
创建的组件,所有的Vue实例都可以使用
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
// 组件里面data必须是一个函数
data: function () {
// 必须返回才能使用
return {
count: 0
}
},
// Prop 属性可以在组件上注册的一些自定义 attribute
props: ['title'],
// 组件的模板 template 里面只能有单个根元素
template: '<div>
<h3>{{ title }}</h3>
button v-on:click="count++">You clicked me {{ count }} times.</button>
</div>'
})
组件是可复用的 Vue 实例,且带有一个名字。我们可以在一个通过 new Vue
创建的 Vue 根实例中,把这个组件作为自定义元素来使用:
<div id="components-demo">
<button-counter title="My journey with Vue"></button-counter>
</div>
new Vue({ el: '#components-demo' })
组件有data
、computed
、watch
、methods
以及生命周期钩子等。但是el
是根实例特有的选项
某个Vue实例中注册只有自己能使用的组件:
var app = new Vue({
el: '#app',
data: {
},
components: {
'my-component': {
template: `<div>这是一个局部的自定义组件,只能在当前Vue实例中使用</div>`,
}
}
})
Vue中的全局变量是通过 Vue.prototype实现的
Vue.prototype.appName = 'My App';
但是如果在new Vue 实例中data添加了appName,那么就会出现冲突。所以可以把全局变量设置为:
Vue.prototype.$appName = 'My App'
这样就可以在任何Vue实例中使用该全局变量
还有一点是,在使用vue的时候我们会有用户自定义的属性与方法,同时还存在vue定义好属性和方法(实例属性/实例方法),在使用实例属性/方法的时候需要用$符号,以便与用户自定义的定义的属性区分开来
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true(三等号严格相等判断)
// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})
路由
参考https://router.vuejs.org/zh/guide/#html
用 Vue.js + Vue Router 创建单页应用,是非常简单的。将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
// 1. 定义 (路由) 组件
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2. 定义路由
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')
的属性to表示目标路由的链接。 当被点击后,内部会立刻把 to 的值传到 router.push()。其实就是自动在导航栏更改路径而已。
所以完全可以用脚本实现路由跳转:
<div v-on:click="foo">Go to Foo</div> 把router替换掉
methods:{ //在Vue实例中添加
foo(){
this.$router.push({path:'/foo'});
}
}
router.push
方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),导航后不会留下 history 记录。
<router-link to="abc" replace></router-link>
也可以用脚本实现:
methods:{
abc(){
this.$router.replace({path:'/abc');
}
}
动态路由: 一个“路径参数”使用冒号 :
标记。当匹配到一个路由时,参数值会被设置到 this.$route.params
,可以在每个组件内使用。
首先添加路由出口:
<div id="app">
<router-view></router-view>
</div>
下面添加到script脚本:
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
const User = {
template: '<div>User {{ $route.params.id }}</div>'
//这里可以显示接收到的参数
}
const app = new Vue({
router,
}).$mount('#app')
之后再导航路径上修改就可以了
file:///D:/JavaWeb/Node/hello.html#/user/foo
嵌套路由:在 VueRouter
的参数中使用 children
配置:
<html>
<head>
<mate charset="utf-8">
<title>vue路由测试</title>
</head>
<body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<router-view></router-view>
</div>
<script>
const User = {
template: `
<div>
<h2>User {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`
}
const UserProfile = {
template: `
<div>
<h2>UserProfile</h2>
</div>
`
}
const UserPosts = {
template: `
<div>
<h2>UserPosts</h2>
</div>
`
}
const router = new VueRouter({
routes: [{
path: '/user/:id',
component: User,
children: [{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile
},
{
path: 'posts',
component: UserPosts
}
]
}]
})
const app = new Vue({
router,
}).$mount('#app')
</script>
</body>
</html>
命名路由:
在创建 Router 实例的时候,在 routes
配置中给某个路由设置名称
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
链接到这个路由:
router.push({ name: 'user', params: { userId: 123 }})
等价于:
router.push({ path: `/user/${123}` })
又等价于:
router.push({ path: 'user', query: { userId: 123 }})
重定向和别名:
“重定向”的意思是,当用户访问 /a
时,URL 将会被替换成 /b
,然后匹配路由为 /b
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
/a
的别名是 /b
,意味着,当用户访问 /b
时,URL 会保持为 /b
,但是路由匹配则为 /a
,就像用户访问 /a
一样。
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
导航守卫:
元信息:
补充jQuery
DOM操作如下:
// 按ID查找:
var a = document.getElementById('dom-id');
// 按tag查找:
var divs = document.getElementsByTagName('div');
jQuery选择器:
// 查找<div id="abc">:
var div = $('#abc');
// 按tag查找只需要写上tag名称就可以了
var ps = $('p'); // 返回所有<p>节点
// 按class查找注意在class名称前加一个.:
var a = $('.red'); // 所有节点包含`class="red"`都将返回
// 例如:
// <div class="red">...</div>
// <p class="green red">...</p>
// 按属性查找
var email = $('[name=email]'); // 找出<??? name="email">
ar icons = $('[name^=icon]'); // 找出所有name属性值以icon开头的DOM
// 例如: name="icon-1", name="icon-2"
var names = $('[name$=with]'); // 找出所有name属性值以with结尾的DOM
// 例如: name="startswith", name="endswith"
// 组合查找
var emailInput = $('input[name=email]');
var tr = $('tr.red'); // 找出<tr class="red ...">...</tr>
// 层级选择器
// 如果两个DOM元素具有层级关系,就可以用$('ancestor descendant')来选择,层级之间用空格隔开
<!-- HTML结构 -->
<div class="testing">
<ul class="lang">
<li class="lang-javascript">JavaScript</li>
<li class="lang-python">Python</li>
<li class="lang-lua">Lua</li>
</ul>
</div>
$('ul.lang li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
$('div.testing li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
// 因为<div>和<ul>都是<li>的祖先节点,所以上面两种方式都可以选出相应的<li>节点
mvvm设计模式
第一m是 model 也就是vm的data属性
第二个v是 view 视图 网页模版
最后vm就是中间vue的 viewmodel 代码体现就是vm对象或者vm实例;