vue.js 解耦视图与数据,可复用的组件,前端路由,状态管理,虚拟DOM。
MVVM模式:当View(视图层)变化时,会自动更新ViewModel(视图模型),View与ViewModel之间双向绑定。【Vue.js使用第一个程序】{
{ message }}
- { {book.name}}
v-for的表达式支持一个可选参数作为当前项的索引:
- { {index}}-{ {book.name}}
5.3.1 与v-if一样,v-for也可以用在内置标签<template>上,将多个元素进行渲染。
遍历对象属性时,有两个可选参数,分别是键名和索引。5.3.2 数组更新:当我们修改数组时,视图也会立即更。Vue包含了一组观察数组非变异的方法:push()、pop()、shift()、unshift()、splice()、sort()、reverse()、filter()、concat()、slice()它们返回的是一个新数组,在使用这些非变异的方法时,可以用新数组来替换原数组,相同的元素不会重新渲染。app.books = app.books.filter(function(item){ return item.name.match(/JavaScript/);});
关于通过索引修改更新数据,app.books[3]={...} 视图不会被更新,可以使用vue内置的set方法。
Vue.set(app.books,3,{name:'abc',author:'jack'});
如果是在组件化的方式,默认是没有导入Vue的,这是可以使用$set。
关于修改数组长度,app.books.length=1,视图也不会更新,可以使用splice来解决。app.books.splice(1);5.3.3 过滤与排序。当你不想改变原数组,想通过一个数组的副本来做过滤或排序显示时,可以使用计算属性来返回过滤或排序后的数组。5.4 方法与事件@click调用的方法名后面可以不写(),vue提供了一个特殊变量$event,用于访问原生DOM事件。5.4.2 修饰符。Vue支持以下修饰符:.stop、.prevent、.capture、.self、once。修饰符可以串联使用。【第6章,表单与v-model】6.1 v-model:完成表单类控件的数据双向绑定,如input、select等。<input type="text" v-model="message" placeholder="输入...">备注:v-model也是一个特殊的语法糖,使用@input来替代v-model,可以实时更新。单选按钮radio:分单独使用和组合使用,单独使用时,不需要绑定v-model,使用v-bind绑定一个布尔类型,组合使用时需要v-model和value来配合使用,v-model绑定数据为选中的value值,字符串类型。{data:{picked:true}}{data:{picked:'html'}}
复选框checked:复选框也分单选使用和组合使用,v-model都绑定到同一个数据,单选时值为布尔值,
组合使用时,需要value值,自动push到绑定的数组中,数据类型为字符串数组。{data:{checked:false}}{data:{checked:['html','css']}}
选择列表select:下拉选择也分单选和多选两种方式,单选时绑定数据为字符串,多选时为字符串数组形式,
<option>是备选项,如果包含value属性,v-model会优先取value值,没有则取text值,multiple属性支持多选。在业务中<option>经常用v-for动态输出,value和text也是用v-bind来动态输出的。
6.2 绑定值:单选按钮、复选框和选择列表在单独使用或单选的模式下,v-model绑定的值是一个静态字符串或布尔值,
但在业务中,有时需要绑定一个动态的数据,这时可以用v-bind来实现。{data:{picked:false,value:123}} //选中后,picked值为123{data:{toggle:false,value1:'a',value2:'b'}} //选中时toggle为a,未选中时toggle为b
6.3 修饰符:与事件的修饰符类似,v-model也有修饰符,用于控制数据同步的时机。
v-model.lazy:在输入框中,v-model默认是在input事件中同步输入框的数据,使用.lazy会转变为change事件中同步。v-model.number:可以将输入转换为Number类型,v-model默认输入的数字其实也是字符串类型。v-model.trim:可以自动过滤输入的首位空格。【第7章,组件详解】7.1.2 组件用法,组件需要注册后才能使用,分全局注册和局部注册,全局注册后,任何Vue实例都可以使用。Vue.component("my-component"),{ template: '这里是组件内容'})
使用组件:<my-component></my-component> //my-component就是注册的组件自定义标签名称。
在Vue实例中,使用components选项可以局部注册组件,组件也可以嵌套组件。<table>内无法直接使用组件,可以使用is特殊指令挂载组件,除了table还有ul、ol、select。注册组件,除了template选项外,还可以有data、computed、methods等选项。
Vue.component('my-component',{ template:'{ {message}}', data: function(){ return { message: '组件内容' }; //这里data必须是函数用return返回 }});
备注:如果data中引用了外部对象,那么这个对象就是共享的,所有修改同步,如果想复用组件,必须在内部返回一个新的对象。
7.2.1 使用props传递数据,组件间进行通信,父组件的模板中包含子组件,父组件要正向的向子组件传递数据或参数,子组件根据接收不同数据渲染不同的内容或执行操作,这种正向传递数据的过程就是通过props来实现的。Vue.component('my-component',{ props:['message'], //props的值分两种,字符串数组或对象。 template:' { {message}}'});
备注:props中声明的数据来自父级,组件data函数return的数据是组件自己的数据。
驼峰命名:当使用DOM模板时,props名称要转为短横分割命名。例如:{props:['warningText'],template:' { {warningText}}'}
直接传递数字、布尔值、数组、对象和通过v-bind绑定传递值区别?
//长度为7 //长度为3Vue.component('my-component',{ props:['message'], template:' { {message.length}}'});
7.2.2 单项数据流,业务中经常遇到两种需要改变prop的情况,一种是父组件传递初始值进来,
子组件将它作为初始值保存起来,在自己的作用域下可以随意使用和修改。Vue.component('my-component',{ props: ['initCount'], template:' { { count }}', data: function(){ return { count: this.initCount } }}
另一种情况是prop作为需要被转变的原始值传入,这种情况用计算属性就可以了。
Vue.component('my-component',{ props:['width'], template:' 组件内容', computed:{ style:function(){ return { width: this.width + 'px' } } }});
备注:在JavaScript中对象和数组是引用类型,指向同一个内存空间,所以props是对象和数组时,
在子组件内改变时会影响父组件的。7.2.3 数据验证,props选项的值需要用对象,验证数据非法,会在控制台弹出警告。验证的type类型包括:String、Number、Boolean、Object、Array、Functiontype也可以是一个自定义构造器,使用instanceof检测。Vue.component('my-component',{ props:{ //必须是数字类型 propA: Number, //必须是字符串或数字类型 propB: [String, Number], //布尔类型,默认值为true propC: { type: Boolean, default: true }, //数字类型,必传参数 propD: { type: Number, required: ture }, //数组或对象类型,默认值必须是一个函数来返回 propE: { type: Array, default: function(){ return []; } }, //自定义一个验证函数 propF: { validator: function(value){ return value > 10; } } }});
7.3.1 组件通信自定义事件,当子组件需要向父组件传递数据时,就要用到自定义事件。
子组件用$emit()来触发事件,父组件用$on()来绑定监听子组件的事件。父组件也可以直接在子组件的自定义标签上使用v-on来监听子组件触发的自定义事件。Vue.component('my-component',{ template: '\总数:{
{ total }} \ \ \', data: function(){ return { counter: 0 } }, methods:{ handleIncrease: function(){ counter++; this.$emit('increase',this.counter); }, handleReduce: function(){ counter--; this.$emit('reduce',this.counter); } }});var app = new Vue({ el: '#app', data: { total: 0 }, methods: { handleGetTotal: function(total){ this.total = total; } }});
解析:increase和reduce是自定义事件标签,由子组件$emit来触发这个事件。
备注:v-on在组件上监听事件,可以使用.native修饰符表示监听的是一个原生事件。7.3.2 使用v-model,在自定义组件上使用v-model指令。v-model是语法糖,$emit()事件名是特殊的input。v-model还可以用来创建自定义的表单输入组件,进行数据双向绑定。双向绑定要满足两个要求:接收一个value属性,在有新的value时触发input事件。Vue.component('my-component',{ props: ['value'], template: '', methods: { updateValue: function(event){ this.$emit('input',event.target.value); } }});var app = new Vue({ el: '#app', data: { total: 0 }, methods: { handleReduce: function(){ this.total--; } }});总数:{
{ total }}
7.3.3 非父子组件通信,非父子组件一般有两种,兄弟组件和跨多级组件。
使用一个空的Vue实例作为中央事件总线(bus),也就是一个中介,在实例初始化时让bus获取一次,任何时间,任何组件就可以从中直接使用了。{ { message }}var bus = new Vue();Vue.component('component-a',{ template: '', methods: { handleEvent: function(){ bus.$emit('on-message','来自组件component-a的内容'); } }});var app = new Vue({ el: '#app', data: { message: '' }, mounted: function(){ var _this = this; //在实例初始化时,监听来自bus实例的事件 bus.$on('on-message',function(msg){ _this.message = msg; }); }});
父链:在子组件中,使用this.$parent可以直接访问该组件的父实例或组件,
this.$parent.message = '来自组件component-a的内容';子组件索引:父组件也可以通过this.$children访问它所有的子组件。在父组件模板中,子组件标签上使用ref指定一个名称,并在父组件内通过this.$refs来访问指定名称的子组件。this.$refs.comA.message;
备注:除了中央事件总线bus,父链和子组件索引也可以实现组件间通信,但业务中子组件尽可能避免依赖父组件。
$refs是非响应式的,直接访问子组件,避免在模板或计算属性中使用。7.4.1 使用slot分发内容,什么是slot?当需要让组件组合使用,混合父组件的内容与子组件的模板时,就会用到slot,这个过程叫做内容分发。以<app>为例,它有两个特点:<app>组件不知道它的挂载点会有什么内容,挂载点的内容是有<app>的父组件决定的。<app>组件很可能有它自己的模板。备注:props传递数据、events触发事件和slot内容分发就构成了Vue组件的3个API来源,在复杂的组件也是由这3部分构成的。7.4.2 作用域,父组件模板的内容是在父组件作用域内编译,子组件模板的内容是在子组件作用域内编译。7.4.3 slot用法单个Slot,在子组件内使用特殊的<slot>元素就可以为这个子组件开启一个slot插槽,在父组件模板里插入在子组件标签内的所有内容将替代子组件的<slot>标签及它的内容。渲染结果为:分发的内容
更多分发的内容
分发的内容
更多分发的内容
注意:子组件<slot>内的备用内容,它的作用域是子组件本身。
具名Slot:给<slot>元素指定一个name后可以分发多个内容,具名Slot可以与单个Slot共存。标题
正文内容
更多的正文内容
底部信息
备注:slot没有使用name特性,所有内容将作为默认slot出现,有name特性的指定位置出现。
7.4.4 作用域插槽,是一种特殊的slot,使用一个可以复用的模板替换已渲染元素。来自父组件的内容
{
{ props.msg }}
备注:子组件<slot>中有类似props传递数据方式,声明参数msg数据传递给插槽,
父组件中使用了<template>元素,而且拥有一个scope特性来接收子组件插槽的数据。例:作用域插槽更具代表性的用例是列表组件,允许组件自定义应该如何渲染列表每一项。{ { props.bookname }}
备注:作用域插槽也可以是具名的Slot。
7.4.5 访问slot,用来访问被slot分发的内容的方法$slots。mounted: function(){ var header = this.$slots.header; var main = this.$slots.default; var footer = this.$slots.footer; console.log(footer); console.log(footer[0].elm.innerHTML);}
备注:通过$slots可以访问某个具名slot,this.$slots.default包括了所有没有被包含在具名slot中的节点。
在用render函数创建组件时比较有用。7.5.1 递归组件,组件在它的模板内可以递归地调用自己,只有给组件设置name的选项就可以了,必须给一个条件来限制递归数量,否则会抛出异常。7.5.2 内联模板,给组件标签使用inline-template特性,组件就会把它的内容当作模板,而不是把它内容分发。备注:在父组件和子组件中声明的数据,都可以直接渲染,如果同名优先使用子组件数据,不建议使用内联模板。7.5.3 动态组件,Vue.js提供了一个特殊的元素<component>用来动态挂载不同的组件,使用is特性来选择要挂载的组件。动态的改变currentView的值就可以动态挂载组件了,也可以直接绑定在组件对象上。
7.5.4 异步组件,Vue.js允许将组件定义为一个工厂函数,动态地解析组件,
Vue.js只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。7.6.1 $nextTick,当v-if="true"时div不会被立即创建出来,这时操作dom会报错,$nextTick(function(){}),就是用来知道什么时候DOM更新完成的。7.6.2 X-Templates,Vue提供了另外一种定义模板的方式,在<script>标签中使用text/x-template类型,并且指定一个id,将这个id赋给template。7.6.3 手动挂载实例,通常我们都是通过new Vue()形式创建的实例,在一些非常特殊的情况下,我们需要动态地去创建Vue实例,Vue提供了Vue.extend和$mount两个方法来手动挂载一个实例。8 自定义指令,Vue有许多内置指令,比如v-if、v-show等,这些丰富的内置指令能满足我们的绝大部分业务需求,
不过在需要一些特殊功能时,我们仍然希望对DOM进行底层操作,这是就要弄到自定义指令了。8.1 基本用法,自定义指令的注册方法和组件很像,也分全局注册和局部注册。比如注册一个v-focus的指令,用于在<input>、<textarea>元素初始化时自动获得焦点。//全局注册:Vue.directive('focus',{ //指令选项});
//局部注册:
var app = new Vue({ el: '#app', directives: { focus: { //指令选项 } }});
*bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
*inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。*update:被绑定元素所在的模板更新时调用,而不论绑定值是否变化,通过比较更新前后的绑定值,可以忽略不必要的模板更新。*componentUpdated:被绑定元素所在模板完成一次更新周期时调用。*unbind:只调用一次,指令与元素解绑时调用。示例:=======================================================================================
JavaScript(ES6) snippets:ES6的语法支持。JavaScript Snippet Pack:JavaScript代码片段集合。ESLint:最流行的代码检测插件。Beatufy:最流行的格式化工具。Live Server:开启本地开发时服务器。Vetur:实现支持vue文件的代码高亮。Beautify:自动格式化插件,F1,输入beaBeautify配置:在工作目录下建立.jsbeautifyrc文件{ "brace_style": "none,preserve-inline", "indent_size": 2, "indent_char": " ", "jslint_happy": true, "unformatted": [""], "css": { "indent_size": 2 } }在VSCode的配置文件里添加 "editor.formatOnSave":true 即可实现保存时自动格式化{ "emmet.syntaxProfiles": { "vue-html": "html", "vue": "html" }, "eslint.validate": ["javascript", "javascriptreact", "html", "vue"], "eslint.options": { "plugins": ["html"] }, "editor.formatOnSave": true}================================================================================================