1:vue基本语法
1.1:基本数据类型和字符串
取值:
{{code}}
{{str}}
data:({
code:100
str:"test"
})
1.2: 对象数据类型
支持ognl语法取值:
{{stu.name}}
{{stu.age}}
data:({
stu{
name:"zhangsan"
age:12
}
})
1.3:if判断语句
<div id="container">
<label class="c" v-if="stu.gender=='M'">男</label>
<label class="c" v-if="stu.gender=='S'">女</label>
</div>
var vm = new Vue({
el:"#container",
data:{
stu:{
name:"zhangsan",
age:"16",
gender:"S"
}
}
});
1.4: for循环语句
<div id="contriner">
<table>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
<tr v-for="s,index in stus">
<td>{{index+1}}</td>
<td>{{s.name}}</td>
<td>{{s.age}}</td>
<td>
<label v-if="s.gender=='M'">男</label>
<label v-if="s.gender=='S'">女</label>
</td>
</tr>
</table>
</div>
var vm = new Vue({
el:"#container",
data:{
stus:[
{
name:"zhangdasan",
age:"16",
gender:"S"
},
{
name:"zhangersan",
age:"19",
gender:"M"
},
{
name:"zhangsansan",
age:"21",
gender:"S"
}
]
}
})
1.5: v-bind: 绑定标签属性
<div id="contriner">
<input type="text" v-bind:value="str">
<img :src="img">
</div>
var vm = new Vue({
el:"#container",
data:{
str:"biaoqianshuxing"
img:"url"
}
})
1.6:表单标签的双向绑定
如果改变input标签中value的值 则lable中的文本也会被改变
<input type="text" v-model:value="str">
<lable>
{{str}}
</lable>
2.Vue生命周期
2.1:vue实例生命周期–vue实例从创建到销毁的过程
- 创建vue实例(初始化data、加载el)
- 数据挂载(将vue实例中的数据渲染到网页HTML标签)
- 重新渲染(当vue的data数据发生变化,会重新渲染到HTML标签中)
- 销毁实例(当页面关闭时)
创建对象—属性初始化—获取属性值—GC回收
2.2:生命周期函数
2.2.1 beforeCreate
beforeCreate:function({}) :data初始化之前
2.2.2 created
created:function({}):data初始化之后
2.2.3 beforeMount
beforeMount:function({}):data初始化之后。模版加载之前,数据初始渲染(挂载)之前,可以修改/获取data中的值,会影响v-once标签数据
2.2.4 mounted
Mounted:function({}):数据初始渲染之后,可以对数据data进行修改,但是不会改变v-once标签中的数据
2.2.5 beforeUpdate
beforeUpdate:function({}):默认不执行,数据渲染之后,当data中数据发生改变时触发重新渲染,渲染之前触发此函数
data数据修改之后,页面重新渲染之前执行
2.2.6 updated
updated:function({}):data数据修改之后,页面重新渲染之后执行
2.2.7 beforeDestroy
beforeDestroy:function({}):vue实例销毁之前
2.2.8 destroyed
Destroyed:function({}):vue实例销毁之后
3.vue的计算属性监听器
data中的属性可以通过声名获取,也可以通过computed通过计算获取
特性:计算属性所依赖的属性发生改变会影响计算属性的值同时发生变化
监听器:data属性中的监听器,当data中值发生改变,就会触发监听器函数的执行
4.vue中class、style绑定
我们可以使用mustache语法将vue中的数据绑定到html标签及标签的属性中,如何将data中的值绑定到标签的class及style属性中
4.1:class绑定方法一
<div :class="{'class1':boolean,'class-2':boolean}"></div>
<!-- class1是css中定义的class名、boolean是vue实例data中的值,当boolean为true则为该标签绑定此类,如果为false不绑定 -->
4.2:class绑定方法二
<div :class="[class1,class2]"></div>
<!--class1和class2是data中的值 -->
4.3:class绑定方法三
<div :class="[boolean2 ? 'class3':'class1']"></div>> <!-- 三元运算 -->
4.4:style绑定方法一
<div v-bind:style="{color: colorname , fontSize: fonsize+'px'}"></div>
<!-- 使用{}定义style样式才能获取data中的值,{}要遵循json格式
{}中不要使用style样式的属性名“font-size”,要用对呀的js属性名:border-style-width = borderStyleWidth
-->
4.5:style绑定方法二
<div v-bind:style="mystyle"></div>
<!-- 可以使用data中属性,定义一个style属性字符串 -->
4.6:style绑定方法三
<div v-bind:style="mystyle2"></div>
<!-- 通过data中的对象赋值 -->
data:{
mystyle2:{
color:"red",
fontSize:"30px"
}
}
4.7:style绑定方法四
<div v-bind:style="[mystyle , mystyle3]">77777</div>
<!-- 数组绑定法,可以将data中多个对象绑定到style中 -->
data:{
mystyle2:{
color:"red",
fontSize:"30px"
},
mystyle3:{
textShadow:"red 3px 3px 3px"
}
}
5.条件与列表渲染
5.1:v-if 和 v-sele
在html标签中可以添加v-if指令指定一个条件,如果条件成立则显示此html标签,如果不成立则不显示此标签
条件可以是一个表达式也可以是一个boolean类型值
包含v-if与v-else的标签只能挨在一起
5.2:v-else-if多分支判断
<div v-if="code>=90">优秀</div>
<div v-else-if="code>=60">良好</div>
<div v-else-if="code<60">不及格</div>
<div v-else>666</div>
<!-- 多分支语句标签不能分开 -->
5.3:v-show
从功能上讲v-show与v-if的作用是相同的,渲染过程有区别
v-show 是通过style属性渲染
v-if是真正的渲染,但是也是懒惰的渲染
v-if
是“真正”的条件渲染,因为它会确保在切换过程中,条件块内的事件监听器和子组件适当地被销毁和重建。
v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。相比之下,
v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。一般来说,v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show
较好;如果在运行时条件很少改变,则使用v-if
较好。
v-show:<div v-show="genderS=='S'">女</div>
v-if:<div v-if="genderM=='M'">男</div>
<input type="text" v-model:value="genderS">
6.列表渲染
将集合数据以表格或列表的格式展现到页面上
6.1:v-for
<tr v-for="s in stus">
<td>{{s.stuId}}</td>
<td>{{s.stuName}}</td>
<td>{{s.stuGender=='M'?'男':'女'}}</td>
<td>{{s.stuAge}}</td>
</tr>
7.事件处理: 处理用户操作事件
在使用vue进行数据渲染时如果使用原生的js事件绑定(例如onclick),如果需要获取vue实例中的数据并传参则需要通过拼接来完成
vue提供了v-on指令用于绑定各种事件(v-on:click),简化了从vue取值的过程,但触发的方法需要写在实例vue代码块中的methods代码中
7.1:v-on
<button type="button" v-on:click="deDelete(s.stuAge)">删除</button>
deDelete:function (age){
console.log("delete"+age)
}
v-on:click --> @click
<button type="button" @click="Update">修改</button>
7.2:使用js函数传值
<button type="button" v-on:click="deDelete(s.stuAge,s.stuName)">删除</button>
deDelete:function (age,name){
console.log("delete"+age+name)
}
7.3:使用dataset对象传值
<button type="button" @click="Update()":data-stuName="s.stuName":data-stuAge="s.stuAge">修改</button>
Update:function (){
//如果v-on绑定的js函数没有参数,调用的时候可以省略();同时可以给js函数一个event参数(事件对象 //1.event 表示触发当前函数的事件
//2.event.srcElement 表示发生事件的元素(修改按钮)
//3.event.srcElement.dataset 表示按钮上的数据集(data开头的属性)
var stu = event.srcElement.dataset;
console.log("update"+stu.stuName+stu.stuAge);
}
7.4:混合使用
<button type="button" v-on:click="事件函数(普通参数,$event)":data-参数name="参数value">删除</button>
<!-- 混合使用注意event传值需要加$event -->
deDelete:function (普通参数,$event){
//获取event对象dataset中值
var stu = event.srcElement.dataset;
console.log("delete"+age+name+stu.stuimg);
console.log(event.srcElement.dataset);
}
8.修饰符
当使用v-on进行事件绑定的时候,可以添加特点的后缀,设置事件触发的特性
8.1:事件修饰符使用示例
<form action="www.baidu.com">
<button type="button" @click.prevent="事件函数"></button><!-- 添加修饰符回消除按钮默认的操作 -->
</form>
8.2:事件修饰符:
prevent:提交事件不再重载页面,消除元素的默认事件
shop:阻止事件冒泡(阻止子标签向上冒泡触发父标签的事件)
self:阻止子组件触发父组件点击事件(设置只能自己触发事件)
<div style="height: 200px; width: 200px; background-color: aqua;" @click.self="method1"> <div style="height: 100px; width: 100px; background-color: fuchsia;" @click.self="method2"> <button @click.shop="method3">测试</button> </div> </div>
once:限定事件只触发一次
8.3:按键修饰符
按键修饰符就是针对键盘事件的修饰符
<input type="text" @keyup.enter="事件函数">
<!-- 将事件修改为按下enter触发,并不是松开按键触发 -->
- 限定哪个按键触发
- .enter
- .tab
- .delete
- .esc
- .up
- .space
- .down
- .left
- .right
- 键盘码
8.4:系统修饰符
组合键
.ctrl+键盘码触发事件
.alt+键盘码触发事件
.shift+键盘码触发事件
.meta+键盘码触发事件
9.表单输入绑定
表单输入绑定,即双向绑定,就是能够将vue示例的data数据渲染到表单输入视图(input\textarea\select),也能将输入视图的数据同步更新到vue实例的data中
9.1:输入框双向绑定
<input type="text" v-model="绑定元素">
data:{
绑定元素:"aaa"
}
9.2:单选选择按钮双向绑定
<!-- 单选按钮双向绑定 -->
<input type="radio" v-model="t1" value="A">A 3
<input type="radio" v-model="t1" value="B">B 4
<input type="radio" v-model="t1" value="C">C 5
<input type="radio" v-model="t1" value="D">D 6
data:{
t1:"C"//默认选择选项C
}
9.3:复选按钮双向绑定
<!-- 复选框双向绑定 -->
<input type="checkbox" v-model="t2" value="篮球">篮球<br/>
<input type="checkbox" v-model="t2" value="足球">足球<br/>
<input type="checkbox" v-model="t2" value="乒乓球">乒乓球<br/>
<input type="checkbox" v-model="t2" value="羽毛球">羽毛球<br/>
data:{
t2:[
"足球","乒乓球"//默认选择这两项
]
}
9.4:下拉菜单双向绑定
<!-- 下拉菜单 -->
<select v-model="t3">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
<option value="深圳">深圳</option>
</select>
data:{
t3:"上海" //默认选择上海选项
}
10.vue使用案例
10.1:接口说明
接口名称 | |
---|---|
请求URL | |
请求方式 | GET | POST |
请求参数 | s string [必须] limit int [可选] 返回搜索结果的条数,默认为10 type int[可选] 搜索类型(1单曲 10歌曲),默认1 offset int[可选] 搜索结果的偏移 |
11.vue-组件
组件就是将通用的HTML模块进行封装–可复用
11.1:组件注册
示例:
//定义一个名为 button-counter 的新组件
Vue.component('button-counter',{
data:funtion(){
return:{
count : 0
},
template:{
//Html元素
},
methods:{
//事件函数
}
}
})
//定义共享代码块
Vue.component("header-bar",{
//组件中的data是通过函数返回的对象
data:function (){
return{
title:"vue组件中data"
}
},
template:`
<table border="1px" style="width:80px;" cellspacing="0">
{{title}}
<tr>
<th>ID</th>
<th>姓名</th>
<th>密码(加密)</th>
<th>昵称</th>
<th>名称</th>
<button type="button" @click="test">测试</button>
</tr>
</table>`,
methods:{
test:function (){
alert("组件中定义的函数")
}
}
});
//template组件的HTML模块(HTML标签、CSS样式)、methods方法块、data代码块
//可以在多html文件中使用header-bar标签引用template中内容
//必须添加到因用el对应的标签中
11.2:组件引用
- 定义组件需要依赖vue.js,在引用自定义组件的js文件之前需要先引用vu e.js
- 组件的引用必须在vue实例的el指定容器中
<div id="vm">
<header-bar></header-bar>
</div>
<script type="text/javascript">
var vm = new Vue({
el:"#vm"
})
</script>
11.3:组件通信-父传子
vue实例本身就是一个组件(模版就是el容器,data容器就是组件数据,methods就是组件事件函数)是父组件
在vue实例中指定的el容器中引用的组件是子组件
父传子:父组件调用子组件时 向子组件传递信息
-
<!-- 父组件引用 --> <header-bar title="aaa"></header-bar> <header-bar :title="str"></header-bar> <script type="text/javascript"> var vm = new Vue({ el:"#vm", data:{ str:"传给子组件title值" } }) </script> Vue.component("header-bar",{ //组件中的data是通过函数返回的对象 // data:function (){ // return{ // title:"vue组件中data" // } // }, template:` <div> {{title}} </div> `, props:['title'] <!-- 使用props调用父组件传过来name对应的value --> });
父传子 | |
---|---|
父组件: data:{ str:“传给子组件title值” } | 子组件:template:<div>{{title}}</div> props:[‘title’] //接收父组件传来值的name |
11.4:子传父
通过子组件的按钮‘调用’父组件的函数,通过函数传值
子传父 | |
---|---|
子组件: data:function (){ return{ str:“子组件中data” } } <button type=“button” @click=“chickMethod”>子组件的按钮 子组件调取函数按钮 methods:{ chickMethod:function (){ this.$emit(“my-event”,this.str) 调用父组件函数,并且传参 } } | 父组件:<header-bar :title=“str” @my-event=“parentMethod”> methods:{ parentMethod:function (t){ vm.t=t; 将子组件的参数赋值到data数据中 } } |
11.5:组件插槽
当我们自定义vue组件时,允许组件中的部分内容在调用组件时进行定义–插槽
11.5.1:插槽的使用
- 在自定义组件时通过slot标签在组件的模版中定义插槽
<header-bar :title="str" @my-event="parentMethod">
<input type="text"> <!-- 自定义的内容自动加载到子组件的插槽中 -->
<button>搜索</button>
</header-bar>
template:`
<div>
<slot></slot> <!--自定义插槽标签-->
</div>`
11.5.2:具名插槽
如果在子组件中有俩个插槽时,需要在slot标签中定义name
具名插槽调用 | |
---|---|
子组件: | 父组件: 搜索 |
11.5.3:插槽的作用域
如果父组件定义slot时,要用到子组件data中的值,需要在子组件中插槽标签中传给父组件
插槽作用域 | |
---|---|
子组件 data:function(){ return:{ str:“子组件的数据”. s:“传给父组件” } } | 父组件: 搜索 {{sc.str}} |
12.axios
vue可以实现数据的渲染,但是如何获取数据呢?
vue 本身不具备通信能力,通常结合axios-一个专注于异步通信的js框架来使用
- asios 数据通信
- vue 数据渲染
12.1:axios入门使用
- 原生ajax–实现步骤复杂
- jquery 笨重
- axios 简洁、高效、对Result支持良好
12.1.1:axios的自定义请求实例
axios({
methods: "post",//请求方式
url:"请求路径",
params:{
//设置请求行
},
header:{
//设置请求头
},
data:{
//设置请求体(post,put)
}
}).then(function (rep){
console.log(rep)
});
12.1.2:axios的异步请求实例
axios.get("请求路径").then(function (rep) {
console.log(rep)
});
12.1.3:axios的并发请求实例
var vm = new Vue({
el:"#container",
data:{
},
methods:{
},
beforeMount:function (){
//3.data初始化之后。模版加载之前,数据初始渲染(挂载)之前,可以修改/获取data中的值
axios.all([queryUser(),queryUserLike()]).then(axios.spread(function (res1,res2){
console.log(res1)
console.log(res2)
}));
}
})
function queryUser(){
return axios.get('http://localhost:8080/FM/user/queryUsers')
}
function queryUserLike(){
return axios.get('http://localhost:8080/FM/user/queryUserLike/a')
}
12.1.4:axios的箭头函数实例
axios请求的回调函数并不是接口返回的data 可以用this直接调用data中的变量
axios.get("http://localhost:8080/FM/user/queryUsers").then((rep)=>{
console.log(rep)
this.stu=rep.data.data;
});
13:vue的路由:router
Router是由vue官方提供的实现组件跳转的插件
13.1:路由插件的引用
<script type="text/javascript" src="js/vue-router.js"></script>
13.2:路由的使用
<div id="container">
<ul>
<li><router-link to="/a">首页</router-link></li><!--路由跳转-->
<li><router-link to="/b">HTML</router-link></li>
<li><router-link to="/c">JAVA</router-link></li>
<li><router-link to="/d">PYTHON</router-link></li>
</ul>
<div style="width: 100%;height: 200px; background-color: paleturquoise;">
<router-view></router-view><!--路由模版显示-->
</div>
</div>
<script type="text/javascript">
//创建模版
const t1 = {template: `<p>模版1(首页)</p>`};
const t2 = {template: `<p>模版2(HTML)</p>`};
const t3 = {template: `<p>模版3(JAVA)</p>`};
const t4 = {template: `<p>模版4(PYTHON)</p>`};
var router = new VueRouter({
routes:[{path:"/a",component:t1},
{path:"/b",component:t2},
{path:"/c",component:t3},
{path:"/d",component:t4},]
});
var vm = new Vue({
el:"#container",
router:router//引用路由
})
</script>
13.3:动态路由匹配
*
可以匹配任意路由例如:
{path:"/*"}
{path:"/模版路径-*"}
<li><router-link to="/">404</router-link></li> <li><router-link to="/user123123123">user-*</router-link></li> <script type="text/javascript"> const t5= {template: `<p>404</p>`}; routes:[{path:"/*",component:t5}, {path:"/user-*",component:t5}]//匹配以user-开头的路径 </script>
注意
:如果使用通配符定义路径,需要注意路由声明的顺序
优先级:如果一个路径定义了多个路由,则按照路由的匹配顺序:路由定义的越早优先级就越高。
13.4:路由参数
<div id="container">
<router-link to="/a/101">首页</router-link>
<router-view></router-view>
</div>
<script type="text/javascript">
const t1 = {template: `<p>模版1(首页){{$route.params.id}}</p>`};
var router = new VueRouter({
routes:[ {path:"/a/:id",component:t1}]
});
var vm = new Vue({
el:"#container",
router:router
})
</script>
13.5:嵌套路由
一个路由里有一个或多个router-link路由时,使用children为其配置路由,和模版
实例:
<div id="container">
<router-link to="/a">模版1</router-link>
<router-view ></router-view>
</div>
<script type="text/javascript">
const t1 = {
template: `<p>
<router-link to="/b">模版1中的b子模版</router-link>
<router-link to="/c">模版1中的c子模版</router-link>
<router-view></router-view>
</p>
`
}
const t2 = {template: `<p>模版1中的b内嵌模版
<router-link to="/d">b子模版中的d子模版</router-link>
<router-link to="/e">b子模版中的e子模版</router-link>
<router-view></router-view>
</p>`}
const t3 = {template: `<p>模版1中的c内嵌模版</p>`}
const t4 = {template: `<p>模版b中的d内嵌模版</p>`}
const t5 = {template: `<p>模版b中的e内嵌模版</p>`}
const myrouter = new VueRouter({
routes: [{
path: "/a",
component: t1,
children:[{
path:"/b",
component:t2,
children:[{
path:"/d",
component:t4
},
{
path:"/e",
component:t5
}]
},{
path:"/c",
component:t3
}]
}]
})
var vm = new Vue({
el:"#container",
router:myrouter
})
</script>
13.6:编程示导航:
<div id="container">
<router-link to="/a">router-link测试</router-link>
<button type="button" @click="test">编程式导航测试</button>
<button type="button" @click="back">后退</button>
<button type="button" @click="forward">前进</button>
<router-view></router-view>
</div>
<script type="text/javascript">
const t = {template: `<p>编程式导航</p>`};
const myrouter = new VueRouter({
routes:[{
path:"/a",
component:t
}]
})
var vm = new Vue({
el:"#container",
router:myrouter,
methods:{
test(){
myrouter.push("/a")
},
back:function (){
myrouter.go(-1)
},
forward:function (){
myrouter.go(1)
}
}
})
参数传递
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
//实例
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
路由的进退步操作
go() 参数为一个整数,表示在浏览器历史记录中的前进/后退多少步,相当于
window.history.go(-1)
的作用
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)
13.7:路由的命名
命名路由:在定义路由时可以给路由指定name,我们在进行路由导航时可以通过路由的name导航
实例:
<input type="text" v-model="name"> //双向绑定
<router-link :to="{name:name}">router-link测试</router-link>
<button type="button" @click="test">编程式导航测试</button>
const myrouter = new VueRouter({
routes:[{
path:"/a",
name:"/name",//设置路由的名称
component:t,
}]
})
//编程式调用路由name
var vm = new Vue({
data:{
name:"/name"
},
router:myrouter,
methods:{
test:function (){
myrouter.push({name : vm.name})
},
}
})
13.8:视图的命名
当有多个 时需要用name给视图命名,用:components: { } 配置路由
实例:
<router-view name="v1"></router-view>
<router-view name="v2"></router-view>
<script type="text/javascript">
const t1 = {template: `<p>t1</p>`};
const t2 = {template: `<p>t2</p>`};
const t21 = {template: `<p>t21</p>`};
const t22 = {template: `<p>t22</p>`};
const myrouter = new VueRouter({
routes:[{
path:"/a",
name:"/aName",
components: {
v1:t1, //给router-view配置对应的视图
v2:t21,
}
},{
path:"/b",
name:"/bName",
components: {
v1:t2,
v2:t22
}
}]
})
13.9:重定向和别名
- 当用户访问
/a
时,URL 将会被替换成/b
,然后匹配路由为/b
- 重定向也是通过
routes
配置来完成,下面例子是从/a
重定向到/b
重定向实例:
routes:[{
path:"/a",
redirect:"/b", //也可以通过name配置
name:"/aName",
components: {
v1:t1,
v2:t21,
}
},{
path:"/b",
name:"/bName",
components: {
v1:t2,
v2:t22
}
}]
})
别名实例:
<button type="button" @click="test">别名测试</button>
routes:[{
path:"/a",
name:"/aName",
alias:"/cName",//为该路由取别名
component:t1
}]
methods:{
test:function (){
myrouter.push('/cName') //访问该路由会自动跳转到"/a"路径
}}