Vue
与jQuery 区别
数据与视图的分离,解耦以数据驱动视图,只关心数据变化
vue 三要素
响应式:vue 如何监听到data 的每个属性的变化模板引擎:vue 的模板如何被解析,指令如何处理?渲染:vue 的模板如何被渲染成 html? 以及渲染过程
响应式
修改data属性之后,vue 立刻监听到(使用Object.defineProperty)data属性被代理到vm 上var mv = {}var data = {price: 100,name: 'zhangsan'}var key, valuefor (key in data){(function (key) {Object.defineProperty(mv, key, {get: function () {console.log('get')return data[key]}set: function (newVal) {console.log('set')data[key] = newVal}})})(key)}
vue 的整个实现流程
第一步:解析模板成 render 函数第二步:响应式开始监听第三步:首次渲染,显示页面,且绑定依赖第四步:data属性变化,触发 rerender
Example
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="public/static/js/vue.js" type="text/javascript"></script></head><body><!-- 挂载点,模板,实例 --><div id="root"><div><input type="text" v-model="inputValue" /><button @click="handleSubmit">Submit</button></div><ul><todo-itemv-for="(item, index) of list":key="index":content="item":index="index"@delete="handleDelete"></todo-item></ul></div><script>Vue.component('todo-item',{props: ['content','index'],template: '<li @click="handleClick">{{content}}</li>',methods:{handleClick: function () {this.$emit('delete',this.index)}}})new Vue({el:"#root",data:{inputValue: '',list:[]},methods:{handleSubmit: function () {this.list.push(this.inputValue);this.inputValue = '';},handleDelete: function (index) {this.list.splice(index,1)}}})</script></body></html>
template syntax
Attributes
v-bindv-bind Shorthand(用冒号: 替代 v-bind: )<!-- shorthand --><a :href="url"> ... </a><!-- full syntax --><a v-bind:href="url"> ... </a><!-- shorthand with dynamic argument --><a :[key]="url"> ... </a>eg:<div v-bind:id="dynamicId"></div><button v-bind:disabled="isButtonDisabled">Button</button>//属性值有变量<div v-bind:id="'list-' + id"></div>
Class and Style Bindings
//class 里面直接是一个对象<div :class="{ active: isActive }"></div>//You can have multiple classes toggled by having more fields in the object.<divclass="static":class="{ active: isActive, 'text-danger': hasError }"></div>//We can pass an array to :class to apply a list of classes<div :class="[activeClass, errorClass]"></div>data() {return {activeClass: 'active',errorClass: 'text-danger'}}
Directives
v-if 渲染或者不渲染某个元素
<p v-if="seen">Now you see me</p>
v-on
v-on Shorthand (用 @ 代替 v-on:)<!-- shorthand --><a @click="doSomething"> ... </a><!-- full syntax --><a v-on:click="doSomething"> ... </a><!-- shorthand with dynamic argument -->// event 是一个变量,它的值可能是click、hover 等<a @[event]="doSomething"> ... </a><h1 v-show="ok">Hello!</h1>v-show 使用css 的显示与隐藏v-if 是条件渲染Prefer v-show if you need to toggle something very often, and prefer v-if if the condition is unlikely to change at runtimeWhen v-if and v-for are both used on the same element, v-if will be evaluated first. See the list rendering guide for details.
Modifiers
// the .prevent modifier tells the v-on directive to call event.preventDefault() on the triggered event<form v-on:submit.prevent="onSubmit">...</form>
List Rendering
<ul id="array-rendering"><li v-for="item in items">{{ item.message }}</li></ul>// get optional second argument for the index of the current item<ul id="array-with-index"><li v-for="(item, index) in items">{{ parentMessage }} - {{ index }} - {{ item.message }}</li></ul>//v-for with an Object<ul id="v-for-object" class="demo"><li v-for="value in myObject">{{ value }}</li></ul>//use a second argument for the property's name<li v-for="(value, name) in myObject">{{ name }}: {{ value }}</li>//And another for the index<li v-for="(value, name, index) in myObject">{{ index }}. {{ name }}: {{ value }}</li>Note that it's not recommended to use v-if and v-for together.<!-- This will throw an error because property "todo" is not defined on instance. --><li v-for="todo in todos" v-if="!todo.isComplete">{{ todo.name }}</li>// This can be fixed by moving v-for to a wrapping <template> tag<template v-for="todo in todos" :key="todo.name"><li v-if="!todo.isComplete">{{ todo.name }}</li></template>
this.content 就是 this.$data.content 的简写
data(){return {content: 1}},mounted() {setInterval(() => {this.content+=1}, 1000)}
computed 和 methods的区别
computed: 当计算内容依赖的属性发生变更时,才会重新计算 methods: 只要页面重新渲染,就会重新计算
vue 生命周期函数
beforeCreate(){//在实例生成之前执行console.log("beforeCreate")},created(){//在实例生成之后执行console.log("created")},beforeMount(){//在模版已经被编译成函数之后执行/在组件内容被渲染到页面之前执行console.log("beforeMount")},mounted(){//在组件内容被渲染到页面之后执行console.log("mounted")},beforeUpdate(){//当数据发生变化时,在组件内容更新完成之前执行console.log("beforeUpdate")},updated(){//当数据发生变化时,在组件内容更新完成之后执行console.log("updated")},beforeUnmount(){//组件销毁前console.log("beforeUnmount")},unmounted(){//组件销毁后console.log("unmounted")}