vue对比jquery
vue
:mvvm
数据驱动影响视图 适用于复杂数据
jquery
:mvc
视图塞入数据 适用于复杂视图动效
生命周期
以下都是钩子函数
beforeCreate
(创建前)
created
(创建后)
beforeMount
(载入前)
mounted
(载入后)
beforeUpdate
(更新前)
updated
(更新后)
beforeDestroy
(销毁前)
destroyed
(销毁后)
计算属性
computed
:计算属性
区别与methods
:
性能相比methods
要高 因为有缓存 只有在相关值发生改变时才会触发 在第一次渲染页面也会主动触发
计算属性的数据源未发生变化 则不会触发响应的计算属性
属性区分于方法
<div id="app">
<p>原始字符串: {{ message }}</p>
<p>计算后反转字符串: {{ reversedMessage }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Runoob!'
},
computed: {
// 以下的函数将提供给计算属性的 getter 计算属性默认只有getter
reversedMessage: function() {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
</script>
计算属性中默认存在getter方法 我们可以手动添加setter方法:
<div id="app">
<p>{{ site }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
name: 'Google',
url:
},
computed: {
site: {
// getter
get: function() {
return this.name + ' ' + this.url
},
// setter
set: function(newValue) {
var names = newValue.split(' ')
this.name = names[0]
this.url = names[names.length - 1]
}
}
}
})
// 调用 setter, vm.name 和 vm.url 也会被对应更新
vm.site = '菜鸟教程 //触发set方法
document.write('name: ' + vm.name); //动态更新dom树
document.write('<br>');
document.write('url: ' + vm.url);
</script>
相关指令
v-text
等同大胡子效果 但是会转换为字符串
v-html
绑定html属性
例如:
<div id="app">
<div v-html="message"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
message: '<h1>菜鸟教程</h1>'
}
})
</script>
v-if
三兄弟 只会渲染判断为真的dom
v-show
绑定值的布尔值来判断是否显示 会渲染整个dom
只是会根据布尔只能判断是否增加display none
这个内联样式
v-if
和v-show
的区别:
v-if
有更高的切换消耗;
v-show
有更高的初始渲染消耗;
v-if
适合运营条件不大可能改变;
v-show
适合频繁切换
v-for
: 循环
v-once
只会渲染一次 即使数据改变
v-bind
用来响应地更新html属性 使用场景:绑定接口请求得到的数据 简写: : ,可以绑定class和内联样式 例如:
<style>
.class1 {
background: #444;
color: #eee;
}
</style>
<body>
<script
<div id="app">
<label for="r1">修改颜色</label><input type="checkbox" v-model="class1" id="r1">
<br><br>
<!-- 单引号只是对下面对两个class1作出区分 不使用也可以 前面是class 样式 后面是bool值 -->
<div v-bind:class="{'class1': class1}">
directiva v-bind:class
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
class1: false
}
});
</script>
</body>
v-on
:用来监听dom
事件 其修饰符可以指定键盘事件
v-on:click
简写@click
:事件监听
v-model
:双向绑定 一般结合input
textarea
(多行) 使用 其有修饰符.lazy
.number
.trim
过滤器
vue中可以自定义过滤器 被用作常见地文本格式化
<!-- 在两个大括号中 -->
{{ message | capitalize }}
<div id="app">
<!-- 过滤器的用法 -->
{{ message | capitalize }}
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'runoob'
},
filters: {
capitalize: function(value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1) //对字符串的第一个字母进行大写
}
}
})
</script>
监听属性
watch
:响应数据变化
<div id="computed_props">
<!-- 分别绑定kilometers和meters -->
千米 : <input type="text" v-model="kilometers"> 米 : <input type="text" v-model="meters">
</div>
<p id="info"></p>
<script type="text/javascript">
var vm = new Vue({
el: '#computed_props',
data: {
kilometers: 0,
meters: 0
},
methods: {},
computed: {},
watch: {
kilometers: function(val) { //dom中的相关绑定会触发对应的观察属性
this.kilometers = val;
this.meters = val * 1000;
},
meters: function(val) {
this.kilometers = val / 1000;
this.meters = val;
}
}
});
// $watch 是一个实例方法 $作用与vue自带的属性区别u与自定义的属性
vm.$watch('kilometers', function(newValue, oldValue) {
// 这个回调将在 vm.kilometers 改变后调用
document.getElementById("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
</script>
样式绑定
- 单样式绑定:
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
</style>
<body>
<div id="app">
<!-- 主要是v-bind的使用 -->
<div v-bind:class="{ active: isActive }"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true
}
})
</script>
- 多样式绑定:
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
<body>
<div id="app">
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true,
hasError: false
}
})
</script>
组件
组件是整个vue知识体系中最重要的一个模块
组件的作用是:复用
前端路由相对于传统路由 请求少 节省资源
mode:history
//不使用html5 实现前进和后退 默认设置
关于组件的引用 除了直接引用自定义标签 is
标签也可以引用组件到指定的位置,动态绑定组件
全局组件
<div id="app">
<runoob></runoob>
</div>
<script>
// 注册 此中注册方式为全局组件 所有的外部组件中都可以引用
{
template: '<h1>自定义组件!</h1>'
})
// 创建根实例
new Vue({
el: '#app'
})
</script>
局部组件
区分于全局组件
<div id="app">
<runoob></runoob>
</div>
<script>
var Child = {
template: '<h1>自定义组件!</h1>'
}
// 创建根实例
new Vue({
el: '#app',
components: {
// <runoob> 将只在父模板可用
'runoob': Child
}
})
</script>
template
template
模版 用来承载dom
树 常在组件中使用
props
自定义组件属性:通过props申明属性 可以通过v-bind动态绑定自定义属性
<div id="app">
<child message="hello!"></child>
</div>
<script>
// 注册
{
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 “this.message” 这样使用
template: '<span>{{ message }}</span>' //可以这样理解:此处message既是属性也是变量
})
// 创建根实例
new Vue({
el: '#app'
})
</script>
动态props
通过v-bind
实现
<div id="app">
<div>
<input v-model="parentMsg">
<br>
<!-- 通过v-bind绑定父组件中的parentMsg 实现动态绑定-->
<child v-bind:message="parentMsg"></child>
</div>
</div>
<script>
// 注册
{
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 “this.message” 这样使用
template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
el: '#app',
data: {
parentMsg: '父组件内容'
}
})
</script>
组件间交互
父组件往子组件传入数据使用props
反过来则用emit
父传子:
子组件props
定义属性 子组件标签引用v-bind
将父组件参数与子组件属性绑定
<div id="counter-event-example">
<button-todo v-bind:todo="item"></button-todo>
</div>
<script>
{
props: ['todo'],
template: '<button >{{ todo }}</button>'
})
new Vue({
el: '#counter-event-example',
data: {
item: '我是item'
}
})
</script>
子传父:
父组件定义method:fv_fuc 接受参数arg
子组件 this.$.emit(<fuc>,<arg>)
子组件标签引用 v-on:<fuc>="fv_fuc"
流程: 子组件的emit触发标签引用的fuc继而触发父组件的fv_fuc
<div id="app">
<div id="counter-event-example">
<p>{{ counter }}</p>
<button-counter v-on:increment="setCounter"></button-counter>
</div>
</div>
<script>
{
template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
data: function() {
return {
counter: 0
}
},
methods: {
incrementHandler: function() {
this.counter += 1
this.$emit('increment', this.counter)
}
},
})
new Vue({
el: '#counter-event-example',
data: {
counter: 0
},
methods: {
setCounter: function(somedata) {
this.counter = somedata //接收子组件的数据
}
}
})
</script>
自定义指令
directive
定义指令名称
inserted
当绑定元素插入到dom中会触发
<div id="app">
<p>页面载入时,input 元素自动获取焦点:</p>
<input v-focus>
</div>
<script>
// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
// 当绑定元素插入到 DOM 中。
inserted: function(el) {
// 聚焦元素
el.focus()
}
})
// 创建根实例
new Vue({
el: '#app'
})
</script>
vue.directive
定义全局指令 directives: {}
的方式定义局部指令 这点和component(组件)
相似
<div id="app">
<p>页面载入时,input 元素自动获取焦点:</p>
<input v-focus>
</div>
<script>
// 创建根实例
new Vue({
el: '#app',
directives: {
// 注册一个局部的自定义指令 v-focus 和components的使用相似
focus: {
// 指令的定义
inserted: function(el) {
// 聚焦元素
el.focus()
}
}
}
})
</script>
directive
可以和钩子函数配合使用 不需要钩子函数也可以简写 第二个参数是function
,默认的第一个参数是el
Vue.directive('runoob', {
// 绑定bind的钩子函数
bind: function(el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#app',
data: {
message: '菜鸟教程!'
}
})
</script>
路由
路由:
需要下载 vue_router
库 然后vue.use(VRouter)
使用步骤:
1.定义路由组件
2.定义路由:映射组件
3.通过routes配置新建router实例
4.通过router参数注入路由 并且挂载根实例
页面跳转 rooter-link
<!-- 导入路由用到的js -->
<script
<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>
<script>
// 0. 如果使用模块化机制编程,導入Vue和VueRouter,要调用 Vue.use(VueRouter)
// 1. 定义(路由)组件。
// 可以从其他文件 import 进来
const Foo = {
template: '<div>foo</div>'
}
const Bar = {
template: '<div>bar</div>'
}
// 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')
// 现在,应用已经启动了!
</script>
路由参数
在映射表里设置 如:path:'/apple/:color'
ex6 语法
import
配合export default
使用以page的形式导出组件 这都是ex6的语法
另外一种写法: 区别与上一种写法 需要 {}
的使用
let com={ //let 在当前作用域下声明一个变量,不会泄漏到外部 区别与var const:常量
}
export { com } //注意{}的使用
引用的时候:
import { com } from ...
脚手架
vue-cli
官方脚手架工具
优势
- 成熟的vue项目架构设计
- 本地测试服务器 热加载服务器 热更新
- 集成打包上线方案 webpack
系统要求:
node
>4.0
指令
vue list
:查看模版方案
vue init webpack demo
利用脚手架 初始化项目
项目结构
利用vue_lic
生成的项目结构:
build
: 项目构建(webpack)相关代码
config
:配置目录 包括端口号等 初学可以使用默认的
node_modules
:npm
加载的项目依赖模块
src
:源码 包含几个目录及文件:
-
assets
:放置一些图片 logo -
components
:放置一个组件文件 可以不使用 -
App.vue
: 项目入口文件 可以直接把组件写在这里 取代components
目录 -
main.js
:项目的核心文件
.****
文件 配置文件 包括语法配置 git配置
static
:静态文件 资源目录 如图片 字体等
package.json
:npm
需要的一套配置文件
index.html
: 首页文件入口 可以添加一些meta
信息或者统计代码
npm run build
:此指令用于生成部署用的文件 文件会存在dist
中
创建项目
步骤:
vue init webpack Vue-Project
- 根据提示配置项目信息
- cd 到项目下 执行
npm install
:安装相关依赖 此处需要翻墙 -
npm run dev
:运行项目
有时候浏览器打不开页面可能是端口被占用
更换端口:
更换端口.png
mac下查询端口占用情况 例如查看8081端口:
lsof -i tcp:8081
细节杂记
字符串反转:
message.split('').reverse().join('')
"-" 命名的属性引用时必须使用单引号
vue中可以绑定对象 也可以绑定对象的计算属性
例子:
<div id="app">
<div v-bind:class="classObject"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal',
}
}
}
})
</script>
内联样式的两种写法:
- 在
html
中直接{}
- 在
css
中定义class
然后html
中引用
关于导出组件的data中采用函数return data
的方式 形成自己的实例 防止复用冲突
vue2.0
如果需要js的完全编程能力 必须使用render
渲染外部引入的app组件
区别与template
更接近与编译器
template
写 html,script
写 js,style
写样式,一个template
只能有一个div
除了数据属性,Vue
实例还提供了一些有用的实例属性与方法。它们都有前缀 $
,以便与用户定义的属性区分开来,例如:
<div id="vue_det">
<h1>site : {{site}}</h1>
<h1>url : {{url}}</h1>
<h1>Alexa : {{alexa}}</h1>
</div>
<script type="text/javascript">
// 我们的数据对象
var data = {
site: "菜鸟教程",
url:
alexa: 10000
}
var vm = new Vue({
el: '#vue_det',
data: data
})
document.write(vm.$data === data) // true 使用的时候需要前缀$
document.write("<br>") // true
document.write(vm.$el === document.getElementById('vue_det')) // true
</script>