vue初识-基础篇
世事忙忙如水流,休将名利挂心头。粗茶淡饭随缘过,富贵荣华莫强求
1.介绍
是什么?
- 构建用户界面,只需关心view层
- 简单易学,轻量快速
- 渐进式框架
核心?
- 响应式的数据绑定:当数据发生改变,视图可以自动更新,可以不用关心dom操作,而专心做数据操作
- 可组合的视图组件:把视图按照功能切分成若干基本单元,组件可以一级一级再组合成整个应用形成倒置组件树,可维护,可重用,可测试
2.基本使用
安装
<script>
标签引入<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
npm安装
# 最新稳定版 $ npm install vue
第一个程序
html
<div id="app"> {{ message }} </div> <script type="text/javascript"> var app = new Vue({ el: '#app', //绑定上面标签的id data: { message: 'Hello Vue!' //绑定标签里的message } }) </script>
运行后,修改
message
的值,页面也会跟着变
3.vue实例
对象Vue()
每个 Vue 应用都是通过用 Vue
函数创建一个新的 Vue 实例开始的
var vm = new Vue({
// 选项
})
数据与方法
var app = new Vue({
el: '#app', //绑定主标签id
data: { //添加多个数据
message: 'Hello Vue!',
word:'athink'
},
methods:{ //添加多个方法
change:function(){
this.message="", //通过this.数据名 来获取数据
this.word="",
this.change() //通过this.方法() 来获取方法
}
}
})
console.log(app) //查看所有数据
计算属性
<div id="app">
{{ reversedMessage }} //reversedMessage 属性可以直接使用
</div>
var app = new Vue({
el: '#app', //绑定主标签id
data: { //添加多个数据
message: 'Hello Vue!',
word:'athink'
},
computed: { // 计算属性 相当于重新进行逻辑运算后的data
reversedMessage: function () {
return this.message.split('').reverse().join('') // `this` 指向 vm 实例
}
},
methods:{ //添加多个方法
change:function(){
this.message="", //通过this.数据名 来获取数据
this.word="",
this.change() //通过this.方法() 来获取方法
}
}
})
侦听器
watch: { //侦听器方法watch
message: function (newVal, oldVal) { // 如果 message 发生改变,这个函数就会运行
console.log("这个值改变了.."+newVal)
}
}
生命周期
beforeCreate() //在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created() //在实例创建完成后被立即调用
beforeMount() //在挂载开始之前被调用:相关的 render 函数首次被调用
mounted() //实例被挂载后调用
beforeUpdate() //数据更新时调用
updated() //由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子
beforeDestroy() //实例销毁之前调用。在这一步,实例仍然完全可用
destroyed() //实例销毁后调用
生命周期图示
4.模板语法
插值
文本
{{ message }} //双括号括起来 输出为纯文本
原始 HTML
<span v-html="rawHtml"></span> //使用v-html输出带标签的值
属性
<div v-bind:id="dynamicId" id=""></div> //使用 v-bind:属性 输出变量属性的值 使用原始属性则为字符串
JavaScript 表达式
{{ number + 1 }} //支持直接写单行的JavaScript表达式代码
指令
v-bind (缩写 : )
用于绑定变量属性
<!-- 完整语法 --> <a v-bind:href="url">...</a> <!-- 缩写 --> <a :href="url">...</a> <!-- 动态参数的缩写 (2.6.0+) --> <a :[key]="url"> ... </a>
v-on(缩写 @ )
用于绑定事件
<!-- 完整语法 --> <a v-on:click="doSomething">...</a> <!-- 缩写 --> <a @click="doSomething">...</a> <!-- 动态参数的缩写 (2.6.0+) --> <a @[event]="doSomething"> ... </a>
条件渲染
v-if
v-if
指令用于条件性地渲染一块内容,注意是v-if
是“真正”的条件渲染<div v-if="type === 'A'"> A </div> <div v-else-if="type === 'B'"> B </div> <div v-else> Not A/B/C </div>
v-show
v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的display进行切换<h1 v-show="ok">Hello!</h1> //ok是变量,可能为true或false
循环渲染
v-for
v-for
指令基于一个数组来渲染一个列表。v-for
指令需要使用item,index in items
形式,其中items
是源数据数组,而item
则是被迭代的数组元素的别名,index
是当前索引值<ul id="v-for-object" class="demo"> <li v-for="item,index in object" :key='index'> //key为了标识每个标签是唯一的 {{ item }} </li> </ul> new Vue({ el: '#v-for-object', data: { object: ["1","2","3"] } })
事件处理
可以用
v-on或@
指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
基本
<div id="example-3"> <button v-on:click="say('hi',$event)">Say hi</button> //触发点击事件 第一个为传入的参数值,第二个为原始DOM事件 <button v-on:click="say('what',$event)">Say what</button> </div> new Vue({ el: '#example-3', methods: { say: function (message, event) { //第一个为传入的参数值,第二个为原始DOM事件 alert(message) } } })
事件修饰符
.stop
停止向上冒泡.prevent
阻止默认事件.capture
捕捉子元素事件.self
当前父元素事件才触发.once
事件只会触发一次.passive
移动滚动行为触发
<!-- 阻止单击事件继续传播 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 --> <form v-on:submit.prevent></form> <!-- 添加事件监听器时使用事件捕获模式 --> <!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 --> <div v-on:click.capture="doThis">...</div> <!-- 只当在 event.target 是当前元素自身时触发处理函数 --> <!-- 即事件不是从内部元素触发的 --> <div v-on:click.self="doThat">...</div> <!-- 点击事件将只会触发一次 --> <a v-on:click.once="doThis"></a> <!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 --> <!-- 而不会等待 `onScroll` 完成 --> <!-- 这其中包含 `event.preventDefault()` 的情况 --> <div v-on:scroll.passive="onScroll">...</div>
按键修饰符
监听键盘事件时,默认了很多按键属性
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
.exact
.left
.right
.middle
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` --> <input v-on:keyup.enter="submit"> <!-- Alt + C --> <input v-on:keyup.alt.67="clear"> <!-- Ctrl + Click --> <div v-on:click.ctrl="doSomething">Do something</div> <!-- 有且只有 Ctrl 被按下的时候才触发 --> <button v-on:click.ctrl.exact="onCtrlClick">A</button> <!-- 没有任何系统修饰符被按下的时候才触发 --> <button v-on:click.exact="onClick">A</button> // 可以使用 `v-on:keyup.f1` Vue.config.keyCodes.f1 = 112
表单绑定
v-model
v-model
指令在表单<input>
、<textarea>
及<select>
元素上创建双向数据绑定v-model
本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理v-model
在内部为不同的输入元素使用不同的 property 并抛出不同的事件:- text 和 textarea 元素使用
value
property 和input
事件; - checkbox 和 radio 使用
checked
property 和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
<!-- 输入框输入值时,message值也会改变,同理,反过来也是 --> <input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p> <!--多行文本 --> <textarea v-model="message" placeholder="add multiple lines"></textarea> <!--单个复选框,绑定到布尔值 --> <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label>
- text 和 textarea 元素使用
修饰符
.lazy 默认
input
事件触发后将输入框的值与数据进行同步 ,添加lazy
修饰符,从而转为在change
事件_之后_进行同步.number 自动将用户的输入值转为数值类型
.trim 自动过滤用户输入的首尾空白字符
<!-- 在“change”时而非“input”时更新 --> <input v-model.lazy="msg"> <!-- 转为数字 --> <input v-model.number="age" type="number"> <!-- 过滤首尾空白字符 --> <input v-model.trim="msg">
过渡动画
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件。
单元素过度
<transition name="fade"> <p v-if="show">hello</p> </transition>
.fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; }
过渡类名
v-enter
:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。v-enter-active
:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。v-enter-to
:定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时v-enter
被移除),在过渡/动画完成之后移除。v-leave
:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。v-leave-active
:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。v-leave-to
:定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时v-leave
被删除),在过渡/动画完成之后移除。
列表过度
<transition-group name="list" tag="p"> <span v-for="item in items" v-bind:key="item" class="list-item"> {{ item }} </span> </transition-group>
配置animate使用
<!-- 引用animate库--> <link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" rel="stylesheet" type="text/css"> <!-- enter-active-class进入动画,leave-active-class动画,:duration动画时间--> <transition-group name="todoTransition" enter-active-class=" animate__animated animate__bounceIn" leave-active-class="animate__animated animate__fadeOutRight" :duration="{ enter: 500, leave: 400 }"> <li v-for="item,index in todoList" :key="'todo'+index"> <input type="radio" @click.prevent.stop="checkDone(item)" :checked="item.isDone" /> <span>{{item.val}}</span> <a href="#1" @click="removeInfo(index.id)">-</a> </li> </transition-group>
5.复用性
混入
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
通过
mixins
// 定义一个混入对象 var myMixin = { created: function () { this.hello() }, methods: { hello: function () { console.log('hello from mixin!') } } } // 定义一个使用混入对象的组件 var Component = Vue.extend({ mixins: [myMixin] }) var component = new Component() // => "hello from mixin!"
自定义命令
全局添加
自定义命令在任何地方可使用
// 注册一个全局自定义指令 `v-focus` Vue.directive('focus', { // 当被绑定的元素插入到 DOM 中时…… inserted: function (el) { //inserted 为钩子函数,下面有介绍更多定义的 // 聚焦元素 el.focus() } }) <!-- 在标签上即可使用 --> <input v-focus>
局部添加
directives: { focus: { // 指令的定义 inserted: function (el) { el.focus() } } } <!-- 在标签上即可使用 --> <input v-focus>
钩子函数
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。componentUpdated
:指令所在组件的 VNode 及其子 VNode全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
钩子函数参数 -> (钩子函数会被传入以下参数)
el
:指令所绑定的元素,可以用来直接操作 DOM。binding
:一个对象,包含以下 property:name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如v-my-directive="1 + 1"
中,表达式为"1 + 1"
。arg
:传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
vnode
:Vue 编译生成的虚拟节点oldVnode
:上一个虚拟节点,仅在update
和componentUpdated
钩子中可用。
插件
插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:
- 添加全局方法或者属性
- 添加全局资源:指令/过滤器/过渡等.
- 通过全局混入来添加一些组件选项.
- 添加 Vue 实例方法,通过把它们添加到
Vue.prototype
上实现.- 一个库,提供自己的 API,同时提供上面提到的一个或多个功能.
使用组件
var Vue = require('vue') var VueRouter = require('vue-router') // 不要忘了调用此方法 Vue.use(VueRouter)
开发插件
暴露一个
install
方法。这个方法的第一个参数是Vue
构造器,第二个参数是一个可选的选项对象MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或 property Vue.myGlobalMethod = function () { // 逻辑... } // 2. 添加全局资源 Vue.directive('my-directive', { bind (el, binding, vnode, oldVnode) { // 逻辑... } ... }) // 3. 注入组件选项 Vue.mixin({ created: function () { // 逻辑... } ... }) // 4. 添加实例方法 Vue.prototype.$myMethod = function (methodOptions) { // 逻辑... } }
过滤器
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。
过滤器可以用在两个地方:
双花括号插值
和v-bind
表达式 。通过
变量 |过滤器
使用。
定义本地的过滤器
//在组件的选项中定义本地的过滤器 filters: { capitalize: function (value) { if (!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) } } //全局过滤器 Vue.filter('capitalize', function (value) { if (!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) })
使用过滤器
<!-- 在双花括号中 --> {{ message | capitalize }} <!-- 在 `v-bind` 中 --> <div v-bind:id="rawId | formatId"></div>
6.组件
定义组件
// 定义一个名为 button-counter 的新组件
Vue.component('com1', {
props: ['name'], //自定义由组件外传进来的值
data: function () { //组件内的data为方法并返回一个对象
return {
age: 18
}
},
methods: {
comEven: function() {
this.$emit("getage", this.age) //向外触发事件
}
}
template: '<div>组件1: <slot></slot></div>' //<slot></slot>为插槽,指组件外调用html标签
})
<div id="components-demo">
<!-- 在需要的地方直接使用组件名调用,name为传进组件内的值, @getage 为捕捉事件 里面可以写js语句或写方法名 -->
<com1 :name="Athink" @getage="age+$event">{{age}}</com1>
</div>
new Vue({ el: '#components-demo' },data:{age:0})
动态组件
在不同组件之间进行动态切换
<!-- 组件会在currentComponent改变时改变 ,例如currentComponent="com1" 即为显示com1组件 -->
<component v-bind:is="currentComponent"></component>
使用
keep-alive
标签,缓存组件,减少性能开销
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
全局组件
//这样即为全局组件,任何地方都可以直接使用
Vue.component('my-component-name', {
// ... 选项 ...
})
局部组件
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
new Vue({
el: '#app',
components: {
'component-a': ComponentA, //这样的组件只能再id为#app标签里使用
'component-b': ComponentB
}
})
模块系统
过
import
/require
使用一个模块系统,后续直接使用vue-cl
i脚手架会经常使用
import ComponentA from './ComponentA' //引入一个组件
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
异步组件
//全局组件
Vue.component(
'async-webpack-example',
() => import('./my-async-component') // 这个动态导入会返回一个 `Promise` 对象。
)
new Vue({
// 局部组件
components: {
'my-component': () => import('./my-async-component')
}
})
组件边界
$root 获取根组件
// 获取根组件的数据 this.$root.foo // 访问根组件的计算属性 this.$root.bar // 调用根组件的方法 this.$root.baz()
$parent 获取父组件
this.$parent.foo
$refs 为事先绑定的标签提供虚拟dom引用
<!-- ref为绑定名usernameInput的引用 ,:ref 为绑定变量为usernameInput的引用--> <base-input ref="usernameInput"></base-input> this.$refs.usernameInput //获取这个指定元素的访问
7.其他
目测一般vue使用好像都是通过
vue-cli
脚手架来创建单文件组件开发的。掌握基本语法和命令,使用起来还是挺简单的样子..
下篇将记录通过小案例去熟悉使用vue -> vue初始-基础应用
下下篇文章将记录如何使用
vue-cli
脚手架来创建单文件组件开发。