一周精通Vue(一)
new Vue(el, data, methods, computed, filters, components, 生命周期函数) el: 挂载页面元素 data: 数据 methods: 定义函数 computed: 计算属性 这里面定义的是方法 但是调用时一般是以变量的形式去调用的 这个要比 methods的方法效率更高 方法循环时会每次调用 而这个会有一个缓存 只会调用一次 filters: 定义过滤器函数 components: 局部组件注册 vue的生命周期(创建->消亡) beforeCreate created: 一般情况下会在这里面做网络请求 beforeMount mounted beforeUpdate updated beforeDestroy destroyed 模板语法 插值语法: {{ massage }} {{}}内不仅可以写变量 也可以写表达式 vue指令 插值指令 v-once: 只是一个指令 没有="" 内容只能被赋值一次 当数据改变时并不会改变 v-html: 按照html语法加载数据 v-text: 将数据加载到标签 并且覆盖标签内的所有内容 v-pre: 将所有的内容原封不动的展示出来 可以使模板插值语法失效 类似python的原始字符串 v-cloak: 这个属性类似于display:none vue不解析就不显示模板 在vue解析之前有这个属性,解析之后将这个属性删除 动态绑定指令 v-bind:动态绑定属性 (v-bind:src)可以缩写为(:src) 可以使用任何属性 :src='' 内容支持变量、数组、对象、方法、以及表达式 v-on:绑定事件 (v-on:click)可以缩写为(@click) 支持所有事件 $event: @click(prm, $event) $event默认写法 接收浏览器产生的event对象 stop修饰符: @click.stop 可以阻止事件冒泡 prevent修饰符: @click.prevent 阻止submit提交 键盘修饰符: @keyup.enter 监听回车建做事件操作 enter表示回车 这里可以更改为其他键 once修饰符: @click.once 事件只能被触发一次 这里防止重复提交很有效 v-for:循环操作 在遍历对象时 如果只接受一个值 默认为value 组件的key属性 在循环是可以选择绑定一个key 但是尽量不要绑定index 因为index 是每次变化的 如果往list里插入一个值 那么所有的 index会重新排序做改变 而绑定item内的数据 则不受排序影响 所以性能更好 一般而言key会绑定一个唯一值 v-if:条件成立时渲染代码快 v-else:else代码块 v-else-if:条件成立时渲染代码快 v-show:条件成立时显示代码块 否则隐藏代码块 和display:none相同 而v-if是直接不创建DOM 这里会始终有DOM只是不显示 Vue.set(要修改的对象, 索引值, 要修改的值) v-model:双向绑定 用来同步更新 默认为value属性 lazy修饰符: 懒加载 不会实时的去双向绑定更新 只有用户回车或取消焦点的时候进行更新 number修饰符: 默认情况下双向绑定的数据全部都是string类型 这里可以指定绑定的类型 trim修饰符: 自动去除字符串两边的空格 <h2>{{message}}</h2> <!--v-model 的双向绑定--> <input type="text" v-model="message"> <!--双向绑定也可以用另一种方式来实现--> <input type="text" :value="message" :input="valueChange"> <script > function valueChange(event){ console.log("当输入框内容被改变 input时间触发, 通过浏览器产生的 event来获取input内容"); this.message = event.target.value; } </script> <!--简写--> <input type="text" :value="message" @input="message=$event.target.value"> 虚拟DOM 渲染 key渲染 通过标签的key属性 决定vue在更新DOM的时候是否重新加载DOM 如果是相同的key则可以服用 不用重新加载DOM 但是DOM的属性数据会变化 如果是不相同则直接重新加载一个新的DOM vue的响应式 并不是所有的修改都是响应式的 例如List的操作 如果使用 list.push("hello") 页面是响应式的 若使用list[0] = 'hello' 此时数据已经改变但是 页面不会进行响应式的修改 ES6 数组的方法 push方法向list最后插入一个值 pop方法从list最后取出一个值并删除 shift方法从list取出第一个元素并删除 unshift方法在list最前插入一个值 splice方法 删除元素 如果是要删除元素 第一个参数为从第几个开始 第二个参数传入你要删除几个元素 如果只传第一个元素 则第一个参数下标的元素 后面的全部删除 插入元素 第一个表示开始元素 第二个参数默认为0 第三个以后的参数为要插入的参数 替换元素 第一个表示参数开始,第二个参数表示截止,第3个以后的参数表示插入的参数 sort方法将list进行排序 reverse方法将list进行反转 高级字符串`` 可以识别换行符 function function缩写 add: function() {} // 可以改写为 add(){} function不定长参数 add(...param){} // ...表示可接受不定长的参数 此时param为list类型 // 类似于python的 def add(*param) for循环 // 普通for循环 for (let i = 0; i < 10; i++){ console.log(list[i]); } // 索引for循环 for (let i in [1, 2, 3]){ console.log(list[i]) } // 增强for循环 for (let item of [1, 2, 3]){ console.log(item) } 高阶函数 // filter函数 const numList = [10, 20, 100, 21, 50, 20, 332, 213, 2123]; let newList = numList.filter(function(n){ return n >= 50 }); // map函数 let new2List = newList.map(function(n) { return n * 2 }); // reduce函数 对数组中所有内容进行汇总 第一个参数为回调函数 第二个参数为初始化的值 let totalCount = new2List.reduce(function(preValue, n){ // 初始化preValue是高阶函数初始化的值 n是list中的元素 // 每一次回调都会将 return的结果赋值给preValue return preValue + n }, 0); 箭头函数 const numList = [10, 20, 100, 21, 50, 20, 332, 213, 2123]; let total = numList.filter(n => n <= 50).map(n => n * 2).reduce((pre, n) => pre + n, 0); console.log(total); 组件化 基本使用 全局组件 全局组件表示注册的组件可以在任何地方使用 局部组件 创建的局部组件只能在挂载元素的内部使用 // 创建组件构造器(子组件) const cpn1 = Vue.extend({ template: ` <div> <h2>cpn1标题</h2> <p>cpn1内容</p> </div> ` }); // 创建组件构造器(父组件) const cpn = Vue.extend({ // ``是高级字符串 可以换行 template: ` <div> <h2>cpn标题</h2> <p>cpn内容</p> <cpn1></cpn1> </div> `, // 这里可以在组件构造器内注册其他组件 这注册的这个组件可以用在模板内 components: { cpn1: cpn1 } }); // 注册全局组件 Vue.component('my-dev', cpn); // 注册局部组件 vm可以看做是root组件 const vm = new Vue({ el: '#app', data: {}, methods:{}, // 注册局部组件 component:{ cpn: cpn } }); // 使用组件 // <my-dev></my-dev> 组件注册语法糖 注册 可以直接省略 extend 直接用对象进行替代 Vue.component('cpn1', { template: ` <div> <h2>cpn1标题</h2> <p>cpn1内容</p> </div> ` }); 模板分离写法 <!--通过id 进行选择器给template属性赋值 替代template中看起来很难受的字符串--> <script type="text/x-template" id="cpn"> <h3>标题</h3> <p>内容。。。</p> </script> <template id="cpn2"> <h1>标题</h1> </template> <script> Vue.component('my-cpn', { template: "#cpn" }); </script> 组件内容访问Vue实例数据默认组件内部是不能直接访问Vue实例内的数据内容的在组件的内部会有一个data属性 而这个data属性必须是一个函数 返回一个对象,对象内部保存着数据 为什么组件内的data必须是一个函数? 因为组件在复用时 应用的data如果是一个对象的话 ,那么每次引用都是同一个对象,当对这个 对象作出更改的时候,所有用到该数据的地方都会被联动修改,所以需要用函数返回一个对象 这代表这每一次 复用组件都会去调用一次data函数 获取一个新的data对象,这样就能相互隔离,其实这里是类似于深拷贝和浅拷贝的关系 组件之间的通信 props的用法(父组件向子组件传递) props支持的数据类型 String Number Boolean Array Object Date Function Symbol 注意: 当定义分离模板时需要一个根组件 如果没有根组件则不能正常解析 <!--子组件模板--> <template id="cpn"> <div> <p>{{c_movies}}</p> <h2>{{c_message}}</h2> <ul> <li v-for="item in c_movies"> {{item}}</li> </ul> </div> </template> <!--父组件模板--> <div id="app"> <!-- props数据来双向绑定父组件中的数据--> <cpn :c_movies="movies" :c_message="message"></cpn> </div> <script> // 子组件 const cpn = { template: "#cpn", // 父亲组件向子组件传递数据 // 第一种 数组方式 // props: ['c_movies', 'c_message'], // 第二种 对象方式 props: { // 1.类型限制 // c_movies: Array, // c_message: String, // 2.提供一些默认值 c_message: { // 数据类型 type: String, // 默认值 default: '这个是消息数据', // 是否必选参数 required: true, }, c_movies: { type: Array, default: [] } }, data() { return {} } }; // 父组件 const vm = new Vue({ el: "#app", data: { message: '信息', movies: ['海王', '海贼王', '庆余年', '神话'] }, components: { cpn: cpn } }); </script> this.$emit的用法(子组件向父组件传递事件) <!--子组件模板--> <template id="cpn"> <div> <button v-for="item in categories" @click="bthClick(item)"> {{item.name}} </button> </div> </template> <!--父组件模板--> <div id="app"> <!--监听子组件事件--> <!--监听到子组件事件后 如果绑定父组件的method若不传item 则默认就是item 不是event--> <cpn @item_click="cpn_click"></cpn> </div> <script> // 子组件 const cpn = { template: "#cpn", data() { return { categories: [ {id: '1', name: '热门推荐'}, {id: '2', name: '手机数码'}, {id: '3', name: '家用家电'}, {id: '4', name: '电脑办公'}, {id: '5', name: '生活日用'}, ] } }, methods: { bthClick(item) { console.log(item); // 发射子组件的自定义事件到父组件 传递item参数 this.$emit("item_click", item) } } }; // 父组件 const vm = new Vue({ el: "#app", data: [], components: { cpn }, methods: { // 接受item参数 cpn_click(item) { console.log('监听到了来自子组件的事件!'); console.log(item); } } }); </script>