VUE快速入门笔记
开发之路,羊肠九曲,荆棘密布,幸得高人指点,前辈填坑,一路谨小慎微,终得工程圆满;其间填坑之经验,开路之历程,皆为精华,不可弃之;记录于此,以便事后回顾,亦想于有相关开发疑惑之同学做参考之用,文中如若有错,恳请雅正,不胜感激。
VUE快速入门笔记
- 概述
- 学习笔记
- 安装
- 声明式渲染
- 绑定属性
- 条件
- 循环
- 点击事件
- 组件化
- 数据与方法
- 实例属性与方法。它们都有前缀 $
- 生命周期函数(钩子)
- 文本
- 富文本
- 对于布尔特性 (它们只要存在就意味着值为 true)
- 缩写
- 计算属性(基于它们的响应式依赖进行缓存的,不会多次执行,)
- 侦听属性
- 侦听器(异步/开销大)
- 对象语法
- 数组语法
- 条件
- 用 key 管理可复用的元素
- 变异方法 (mutation method)
- 替换数组
- 不检测改动
- 已有对象赋值新属性
- 父子组件传值
- 监听事件
- 访问原始dom
- 事件修饰符 (可以串联)
- 按键修饰符
- 系统修饰键
- 双向数据绑定
- 修饰符
- 组件注册
- 组件data 必须是函数
- 实例创建之前验证
- 动态组件持久化
- 异步组件
- 边界情况
- 自定义指令
- 插件
- 类型推断
- 生产环境
- vue-router路由
- Ajax axios
- vue-resource
概述
vue 是一套渐进式Javascript框架,它的设计采用的是自底向上增量开发设计,因为其核心库只关注视图层,所以学习起来很方便,并且易于其他库及现有项目结合。
学习笔记
现就学习vue整个过程做一简单记录,方便后期回顾,亦方便有需要是查阅。
Vue官方文档
安装
npm install vue
声明式渲染
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
绑定属性
v-bind:title=""
:title=""
条件
v-if=“”
循环
v-for=“todo in todos”
点击事件
v-on:click=""
@click=""
methods:{
function(){}
}
组件化
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
数据与方法
var data={a:1}
var vm = new Vue({
data:data
})
Object.freeze(),这会阻止修改现有的属性
实例属性与方法。它们都有前缀 $
vm.$data = data
vm.$el = document.getElementById()
vm.$watch('a',function(newvalue,oldvalue){
//vm.a改变之后调用
})
生命周期函数(钩子)
beforeCreate created beforeMount mounted
beforeUpdate updated beforeDestroy destroyed
文本
{{msg}}
v-once 一次性插值
富文本
v-html=“html”
对于布尔特性 (它们只要存在就意味着值为 true)
js表达式
{{ ok ? 'YES' : 'NO' }}
指令 v-if 参数 v-bind:href=“url” v-on:click=“fun”
动态参数 null移除 转小写
v-bind:[attr]=“url”
修饰符(modifier)
<form v-on:submit.prevent="onSubmit">...</form>
告诉 v-on 指令对于触发的事件调用 event.preventDefault()
缩写
v-bind == :
v-on == @
计算属性(基于它们的响应式依赖进行缓存的,不会多次执行,)
默认getter
computed: {
now: function(){
return this.msg
},
fullName:{
get:function(){
return this.firstName
},
set:function(newValue){
this.firstName = newValue
}
}
}
vm.fullName="newValue"
侦听属性
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
侦听器(异步/开销大)
_.debounce
是一个通过 Lodash 限制操作频率的函数。
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},
对象语法
v-bind:class="{acrive:isActive,'danger':hasErr}"
数组语法
v-bind:class="[isActive ? activeClass:'',errClass]"
v-bind:class="[{ active: isActive }, errorClass]"
条件
v-if="" v-else-if="" v-else
用 key 管理可复用的元素
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
- v-show 的元素始终会被渲染并保留在 DOM 中
- v-for 具有比 v-if 更高的优先级
- v-for="(item, index) in items"
- v-for="(value, name) in object"
- v-for=“item in items” v-bind:key=“item.id”
变异方法 (mutation method)
push() pop() shift() unshift() splice() sort() reverse()
替换数组
filter()、concat() 和 slice()
不检测改动
vm.items[indexOfItem] = newValue
Vue.set(vm.items, indexOfItem, newValue)
vm.items.splice(indexOfItem, 1, newValue)
vm.$set(vm.items, indexOfItem, newValue)
已有对象赋值新属性
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
v-for 的优先级比 v-if 更高
父子组件传值
props: [‘title’]
监听事件
v-on
访问原始dom
@click=“fun($event)”
事件修饰符 (可以串联)
.stop 阻止单击事件继续传播
.prevent 阻止默认行为的发生
.capture 元素自身触发的事件先处理,然后交内部处理
.self 事件不是从内部触发的
.once 事件将只会触发一次
.passive 不阻止事件的默认行为
按键修饰符
.enter .tab .delete .esc .space .up .down .left .right
// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
系统修饰键
.ctrl .alt .shift .meta
@click.ctrl="doSomething" ctrl+click
@keyup.alt.67="clear" Alt+C
.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
双向数据绑定
v-model=“”语法糖
复选框 true-value="yes" false-value="no"
修饰符
.lazy input事件与change同步
.number 输入值转为数值类型
.trim 去除首尾空格
组件注册
Vue.component('my-component-name', {
// ... options ...
})
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
组件data 必须是函数
data: function () {
return {
count: 0
}
}
每个组件必须只有一个根元素
模板字符串 ``
子组件可以通过调用内建的 emit('父级属性‘)
通过插槽分发内容 v-slot:==#
<slot name="default" v-bind:user="user">Default</slot>
<template v-slot:default="slotProps">default {{slotProps.user.name}}</template>
<current-user #default="{ user }">
{{ user.firstName }}
</current-user>
特殊的 is 特性 判断 并替换 <tr is="">
prop
props: {
title: String,
propA:{
type:Object,
required:true,
default:function(){
return {msg:"hello"}
},
validator:function(value){
return ['',''].indexOf(value) !== -1
}
}
}
实例创建之前验证
v-bind:is-published="post.isPublished"
v-bind="post" //传入对象的所有属性
单向流动 赋值初始值或者使用计算属性
非prop属性自动添加至跟元素 class style会合并,其他会替换
禁用特性继承 inheritAttrs: false
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件
model: {
prop: 'checked',
event: 'change'
},
<base-checkbox v-model="lovingVue"></base-checkbox>
<base-input v-on:focus.native="onFocus"></base-input> 原生事件
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
computed: {
inputListeners: function () {
var vm = this
// `Object.assign` 将所有的对象合并为一个新对象
return Object.assign({},
// 我们从父级添加所有的监听器
this.$listeners,
// 然后我们添加自定义监听器,
// 或覆写一些监听器的行为
{
// 这里确保组件配合 `v-model` 的工作
input: function (event) {
vm.$emit('input', event.target.value)
}
}
)
}
},
template: `
<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on="inputListeners"
>
</label>
`
})
<text-document v-bind:title.sync="doc.title"></text-document>
动态组件持久化
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
异步组件
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 `require` 语法将会告诉 webpack
// 自动将你的构建代码切割成多个包,这些包
// 会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})
const AsyncComponent = () => ({
// 需要加载的组件 (应该是一个 `Promise` 对象)
component: import('./MyComponent.vue'),
// 异步组件加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示加载时组件的延时时间。默认值是 200 (毫秒)
delay: 200,
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
})
边界情况
根实例 this.$root.
父组件 this.$parent.
自组件/子元素 this.$refs.usernameInput
依赖注入 provide inject
provide: function () {
return {
getMap: this.getMap
}
}
inject: ['getMap']
程式化侦听 $emit $on $once $off
组件的递归调用 避免
组件循环引用 全局注册 beforeCreate注册 webpack异步import
内联模板 inline-template <my-component inline-template>
<script type=“text/x-template” id=“hello-world-template”>
强制更新 $forceUpdate
静态组件 v-once缓存降低开销
第三方动画库 Animate.css Velocity.js
<transition name="fade">
<p v-if="show">hello</p>
</transition>
enter enter-active enter-to leave leave-active leave-to
自定义指令
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
<input v-focus>
插件
Vue.use(MyPlugin, { someOption: true })
过滤器 |
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
{{value|capitalize}}
类型推断
const Component = Vue.extend({
// 类型推断已启用
})
生产环境
webpack
module.exports={
mode:'production'
}
vue-router路由
<router-link :to="{ path: '/abc'}" replace></router-link>
<router-link :to="{ path: 'relative/path'}" append></router-link>
<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>
<router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
<router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>
<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>
Ajax axios
axios.get('url').then(response=>()).catch(function(){})
axios.post('url',{}).then(response=>()).catch(function(){})
axios.all([get(),get2()]).then(axios.spread(function(acct,perms){}))
vue-resource
this.$http.get(url,{params:jsonData}).then((success)=>{},(fail)=>{})
get(url, [options])
head(url, [options])
delete(url, [options])
jsonp(url, [options])
post(url, [body], [options])
put(url, [body], [options])
patch(url, [body], [options])
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);