1.Es6语法普及
- let和var的区别:
-
var:定义变量时,在全局范围内都有效;所以在变量没有声明之前就能使用,值为undefined, 称为变量提升; let:声明的变量一定要在声明后使用,而且在for循环时,变量都会被重新定义
-
let不允许在相同的作用域内,重复声明一个变量; // 报错 function func() { let a = 10; var a = 1; } // 报错 function func() { let a = 10; let a = 1; } 所以,在函数内部重新声明参数也报错 function func(arg) { let arg; // 报错 } function func(arg) { { let arg; // 不报错 } }
- const命令
- const声明一个只读的常量,一旦声明,常量的值不能修改;
- 所以const一旦声明,就必须立即初始化,不能留着以后赋值,只声明不赋值也报错;
2.模板字符串
-
- ``:在输出模板是,可以在里面输出标签叠加
- ${变量名}:在字符串中嵌入变量时,跟反引号配合着使用,在script中使用,在页面没办法渲染,而{{}}是vue插入值的语法,可以在模板上渲染;
-
// 普通字符串 `In JavaScript ' ' is a line-feed.` // 多行字符串 `In JavaScript this is not legal.` console.log(`string text line 1 string text line 2`); // 字符串中嵌入变量 let name = "Bob", time = "today"; `Hello ${name}, how are you ${time}?`
3.箭头函数
-
-
let f = a => a //等价于 let f = function(a){ return a} let f = () => 5 //等价于 let f=function()=>{return 5} let sum = (sum1, sum2) => sum1+sum2; // 等同于 var sum = function(num1, num2) { return num1 + num2; };
- 注意事项:函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
-
- import和export
-
//导出多个声明 export let name = 'gx' export function aa(){} export {age,name,aa} //批量导出 import {age,name,aa} from './main' console.log(name) console.log(age) console.log(aa()) // 整个模块导入 把模块当做一个对象 // 该模块下所有的导出都会作为对象的属性存在 import * as obj from "./main" / 一个模块只能有一个默认导出 // 对于默认导出 导入的时候名字可以不一样 // main.js var app = new Vue({ }); export default app // test.js // import app from "./main" import my_app from "./main"
2.Vue的基础语法及命令
<template> <div> <h2>head</h2> <p v-text="msg"></p> <p v-html="html"></p> </div> </template> <script> export default { name: "head", data(){ return { msg: "消息", html: `<h2>插入h2标题</h2>` } } } </script>
//双向监听事件(model)页面上修改,会自动触发后端修改,后端修改,会被一直尝试连接的客户端重新渲染;
<div id="app"> <label> 男 <input type="checkbox" v-model="sex" value="male"> // <input type="radio" v-model="sex" value="male"> </label> <label> 女 <input type="checkbox" v-model="sex" value="female"> </label> {{sex}} </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="../js/main.js"></script> // main.js 页面 var app = new Vue({ el: '#app', data: { // sex: "male", sex: [], } });
// HTML 页面 <div id="app"> <div> <texteare v-model="article"> </texteare> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="../js/main.js"></script> // main.js 页面 var app = new Vue({ el: '#app', data: { // sex: "male", sex: [], article: "这是一段文本。。这是一段文本。。这是一段文本。。这是一段文本。。这是一段文本。。" } });
// HTML页面 <div id="app"> <!--<select v-model="from">--> <!--<option value="1">单选1</option>--> <!--<option value="2">单选2</option>--> <!--</select>--> <!--{{from}}--> <select v-model="where" multiple=""> <option value="1">多选1</option> <option value="2">多选2</option> <option value="3">多选3</option> </select> {{where}} </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="../js/main.js"></script> // main.js 页面 var app = new Vue({ el: '#app', data: { from: null, where: [], } }); v-model select
//其他命令
//v-bind:动态绑定属性 <style> .active { background: red; } </style> <div id="app"> <div> <!--<a v-bind:href="my_link">点我</a>--> <a v-bind:href="my_link" :class="{active: isActive}">点我 </a> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="../js/main.js"></script> // main.js var app = new Vue({ el: '#app', data: { my_link: "http://baidu.com", isActive: true, } }); //v-show:动态管理是否显示标签:本质是给标签添加了display属性 <div id="app"> <button @click="on_click()"> 点我 </button> <p v-show="show">提示文本</p> </div> // main.js 页面 var app = new Vue({ el: '#app', data: { show: false, }, methods: { on_click: function () { this.show = !this.show } } }); //v-if:跟v-show的结果一样,但是v-if是通过append child DOM树和删除DOM树实现 <div> <div v-if="role == 'admin' || 'super_admin'">管理员你好</div> <div v-else-if="role == 'hr'">待查看简历列表</div> <div v-else> 没有权限</div> </div> // main.js 页面 var app = new Vue({ el: '#app', data: { role: 'admin', // role: 'hr', }, }); //v-on:绑定事件只能绑定DOM中存在的事件,简写为: @click='Myclick' <div> <span>事件</span> <button v-on="{mouseenter: onMouseenter, mouseleave: onMouseleave}" v-on:click="onClick(1)">点我</button> </div> <div> <input type="text" v-on="{keyup: onKeyup}"> </div> // main.js var app = new Vue({ el: '#app', data: { my_link: "http://baidu.com", isActive: true, }, methods: { onClick: function (a) { alert(a) }, onMouseenter: function () { console.log("mouse enter") }, onMouseleave: function () { console.log("mouse leave") }, onKeyup: function () { console.log("key up") } }, });
//指令修饰符
// 我们现在要获取用户的注册信息 // 用户名以及手机号 用指令修饰符能够让我们更加便捷 // HTML 页面 <div> 用户名: <input type="text" v-model.lazy.trim="username"><br> {{username}} 手机号: <input type="text" v-model.number="phone"><br> {{phone}} </div> // main.js 页面 var app = new Vue({ el: '#app', data: { username: "", phone: "", }, }); 指令修饰符 lazy:model是双端数据显示,你只要修改,对应值就跟着改变,lazy是把失焦之后触发model number:前端在 传输数据时一直是字符串,而有些地方需要用数字
//vue的计算属性
// 现在我们有一个成绩的表格 来计算总分和平均分 // HTML页面 <div id="app"> <table border="1"> <thead> <th>学科</th> <th>分数</th> </thead> <tbody> <tr> <td>数学</td> <td><input type="text" v-model.number="math"></td> </tr> <tr> <td>物理</td> <td><input type="text" v-model.number="physics"></td> </tr> <tr> <td>英语</td> <td><input type="text" v-model.number="english"></td> </tr> <tr> <td>总分</td> <!--<td>{{math+physics+english}}</td>--> <td>{{sum}}</td> </tr> <tr> <td>平均分</td> <!--<td>{{Math.round((math+physics+english)/3)}}</td>--> <td>{{average}}</td> </tr> </tbody> </table> </div> // js 页面 var app = new Vue({ el: '#app', data: { math: 90, physics:88, english: 78, }, computed: { sum: function () { var total = this.math + this.physics + this.english return total }, average: function () { var average_num = Math.round(this.sum/3) return average_num } } }); 计算属性 computed
//vue的过滤器
// 我们两个需求 一个是价格展示后面自动加“元” // 单位 毫米和米的转换 // HTML页面 <div> <p>价格展示</p> <input type="text" v-model="price"> {{price | currency('USD')}} </div> <div> <p>换算</p> <input type="text" v-model="meters"> {{meters | meter}} </div> // js 代码 Vue.filter('currency', function (val, unit) { val = val || 0; var ret = val+ unit return ret }); Vue.filter('meter', function (val) { val = val || 0; return (val/1000).toFixed(2) + "米" }); new Vue({ el: '#app', data: { price: 10, meters: 10, } }); 过滤器 filter
3.获取DOM元素
:vue对象中是一个一个键值对,有一个$refs属性,这里面有你给标签自定义的属性ref <style> .box { width: 200px; height: 200px; border: solid 1px red; } </style> </head> <body> <div id="app"> <div class="box" ref="my_box"> 这是一个盒子 </div> </div> <script> const app = new Vue({ el: "#app", mounted(){ this.$refs.my_box.style.color = "red"; } }) </script> </body>
4.事件监听
数据被渲染时,字符串会被立即渲染,
但是对象和数组只能监测到长度是否改变,而改变了特定的值时,监听不到
所以有一个app.$set(this.数组, 索引, '值')
5.每个组件的template:只能包括一个作用域块;
6.vue的组件
- 组件的注册:
- 全局的注册--Vue.component('组件的名称',{})
- 局部的注册--在根实例中new Vue({compents:{组件名称})
- 组件的通信:
- 父子的通信:在父组件中给子组件绑定属性,子组件通过props=['属性名称']
-
let Header = { template: ` <div> {{fD}} </div> `, props:['fD'] }; let App = { template: ` <div> <Header :fD="r"></Header> </div> `, data(){ return{ 'r':10, } }, components:{ Header, } };
- 子父间的通信:子组件先提交事件--this.$emit('事件名称',参数),在父组件给子组件绑定事件
-
let Header = { template: ` <div> <button v-on:click="myClick">点我变大</button> </div> `, methods: { myClick: function () { console.log(this); // 触发父级组件事件this.$emit this.$emit('font-click', 0.1); } } }; let App = { <!--在父组件监听事件,等待子组件触发--> // 为什么用fontSize,而不用font-size,js中规定在js代码中调用css属性的时候,把中间-去掉,后面单词第一个字母大写 template: ` <div> <Header v-on:font-click="fontClick"></Header> <span v-bind:style="{fontSize:postFontSize + 'em'} ">Hello Vue</span> </div> `, data() { return { postFontSize: 1, } }, methods: { fontClick: function (value) { this.postFontSize += value; console.log(this) } }, components: { Header }, };
- 非父子间的通信:
-
1. 声明中间调度器 2. 其中一个组件向中间调度器提交事件 3. 另一个组件监听中间调度器的事件 4. 注意this的问题
//1. 定义一个中间调度器,就是一个vue对象 let middle = new Vue(); //2.在组件中定义一个事件,触发与老二的交流 let Header = { template:` <div> <h1>这是老大</h1> <button @click="myClick">点我向老二说话</button> </div> `, methods:{ myClick:function () { //3.向中间调度器中发送数据 middle.$emit('oldSay','我说老二') } } }; let Footer = { template:` <div> <h1>这是老二</h1> <h2>老大:{{say}}</h2> </div> `, data(){ return{ say:'' } }, //4.在老二的组件中监听老大里面的触发事件$emit,用$on监听 mounted(){ let that = this; middle.$on('oldSay',function (data) { that.say = data; }) } }; let App = { template:` <div> <Header></Header> <Footer></Footer> </div> `, components: { Header, Footer, }, };
- 组件的插槽和混入
-
--<slot></slot>-- 命名的插槽 --混入 --代码的复用性 --Mixins = [base]
7.Vue的路由
- 路由的注册:
-
1.定义一个对应关系: let url = [ { path: "/", name: "home", component: {template: ``} } ] 2.定义一个router对象 let router = new VueRouter({ routes:url }) 3.在根实例中注册router对象 let new Vue({ router:router, })
- 子路由:在父路由中加一个children属性
- 注意要在父路由对应的组件中添加对应的router-view出口
-
<script> let Home = { template:` <div> <router-link :to="{name:'l'}">第一子</router-link> <router-link :to="{name:'y'}">第二子</router-link> <router-view></router-view> </div> ` }; //component:对应一个组件,字典,而也直接写template属性时,得用对象 let url = [ { path: '/a', name: 'home', component: Home, children: [ { path: 'lll', name: 'l', component: { template: ` <div> <h1>第一子</h1> </div> `, } }, { path: 'yyy', name: 'y', component: { template: ` <div> <h1>第二子</h1> </div> `, } } ] }, ]; let router = new VueRouter({ routes:url, }); let App = { template:` <div> <router-link :to="{name:'home'}">老子</router-link> <router-view></router-view> </div> `, //router-link里面自动注册组件,所以这里面不用注册属性 // components:{ // Home, // } };
- 路由的参数:params和query
- params:在path中用:变量名,来接收url的参数,所有参数都接收到params中, 取值:this.$route.params.id
- query:是?后面的参数, 取值:this.$route.query.属性名
- 还可以在路由匹配的地方加配置文件meta,用来作组件是否需要认证系统
-
path: 'lll', name: 'l', meta:{ is_login:true, }, if (this.$route.meta.is_login){ this.$router.push({name:'index'}) }
- beforeach和aftereach路由的钩子函数