<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<p>{{msg}}p>
div>
<script>
// 创建一个Vue的实例
// 当我们导入包之后,在浏览器的内存中就多了一个Vue的构造函数
// 注意:我们new出来的这个vm对象就是我们 MVVM中的VM调度者
var vm = new Vue({
el: '#app', //表示,当前我们new的这个Vue实例要控制特面上的哪个区域
// 这里的data就是 MVVM中的M 专门用来保存每个页面的数据
data: { //data 属性中存放的是el中要用到的数据
msg:'欢迎学习Vue' //通过Vue提供的指令很方便的就能把数据渲染到页面上,程序员不在手动操作DOM元素了
//前端的Vue之类的框架不提倡我们去手动操作DOM元素
}
})
script>
body>
html>
v-cloak :使用 v-cloak 能够解决插值表达式闪烁的问题
v-text : 默认 v-text 是没有闪烁问题的,可以用来渲染页面
v-html :会覆盖元素中原本内容并且会让文本用html形式输出(可以识别html标签)
区别:
v-text 会覆盖元素中原本的内容
差值表达式 只会替换自己的这个占位符不会把整个元素的内容清空
v-html 会覆盖元素中原本内容并且会让文本用html形式输出(可以识别html标签)
v-bind: 是Vue中提供的用于绑定属性的指令, v-bind可以简写为 :要绑定的属性,只要是属性就可以用这个绑定
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<style>
[v-cloak] {
display: none;
}
style>
<div id="app">
<p v-cloak>+++{{msg}}+++p>
<h4 v-text='msg'>++++++h4>
<div v-html="msg2">+++div>
<input type="button" value="按钮按钮" v-bind:title="mytitle">
div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '123',
msg2: 'haha
',
mytitle: '这是自己定义的title'
}
})
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<input type="button" value="按钮" v-on:click="show">
div>
<script>
var vm = new Vue({
el: '#app',
methods:{ //这个methods属性中定义了当前Vue实例所有可用的方法
show: function(){
alert('Hello')
}
}
})
script>
body>
html>
1、导入Vue包
2、创建一个要控制的区域
用箭头函数解决this指向问题
添加id标记定时器
v-bind 只能实现数据的单向绑定,从M自动绑定到V 无法实现数据双向绑定(从客户端表单元素到代码中的数据与从代码中的数据到客户端元素
使用v-model指令,可以实现表单元素和Model中数据的双向数据绑定
注意:v-model 只能运用在表单元素中: input(radio,text,address,email…) select , checkbox textarea
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<input type="text" v-model="msg" style="width:100%">
div>
<script>
//创建Vue实例,得到ViewModel
var vm = new Vue({
el: '#app',
data: {
msg: 'v-model学习'
},
methods: {
}
})
script>
body>
html>
在组件中或者一些特殊情况中必须使用v-for的同时指定唯一的字符串/数字类型:key值
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
{{ item }}p>
{{ user.id }} --- {{ user.name }} --- {{ i }}p>
值:{{ val }} --- 键:{{ key }} --- {{i}} p>
第{{count}}次p>
div>
<script>
//创建Vue实例,得到ViewModel
var vm = new Vue({
el: '#app',
data: {
list: [1, 2, 3, 4, 5, 6],
list1: [
{id:1,name:'zs1'},
{id:1,name:'zs2'},
{id:1,name:'zs3'}
],
list2: {
id:1,
name: '托尼',
gender: '男'
}
},
methods: {
}
})
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<input type="button" value="按钮" @click="toggle">
<h3 v-if="flag">v-if控制h3>
<h3 v-show="flag">v-show控制h3>
div>
<script>
//创建Vue实例,得到ViewModel
var vm = new Vue({
el: '#app',
data: {
flag: true
},
methods: {
toggle(){
this.flag = !this.flag
}
}
})
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
<style>
.red {
color: red;
}
.thin {
font-weight: 200;
}
.italic {
font-style: italic;
}
.active {
letter-spacing: 0.5em;
}
style>
head>
<body>
<div id="app">
<h1 class="red thin">大的h1h1>
<h1 :class="['thin','italic']">大的h1h1>
<h1 :class="['thin','italic',flag?'active':'']">大的h1h1>
<h1 :class="['thin','italic',{'active':flag}]">大的h1h1>
<h1 :class="{red: true, thin:false}">大的h1h1>
<h1 :class="obj">大的h1h1>
div>
<script>
//创建Vue实例,得到ViewModel
var vm = new Vue({
el: '#app',
data: {
flag: true,
obj: {red: true, thin:true},
},
methods: {
}
})
script>
body>
html>
全局过滤器:
其中:调用的时候,前面的msg会先执行 | 后面的过滤器,然后再将返回的值作为真正的msg渲染
定义过滤器的时候第一个参数是要过滤的数据,后面的参数是传参
过滤器可以调用多次:
私有过滤器:
字符串填充:一个是头部填充一个是尾部填充
遍历方法:
查找索引的两个方法:
这两个方法如果返回true都会终止循环
some不仅仅可以用来找索引,还可以进行别的操作。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
<link rel="stylesheet" href="./lib/bootstrap-3.3.7.css">
head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">添加品牌h3>
div>
<div class="panel-body from-inline">
<label>
Id:
<input type="text" class="from-control" v-model="id">
label>
<label>
Name:
<input type="text" class="from-control" v-model="name">
label>
<input type="button" value="添加" class="btn btn-primary" @click="add">
<label>
搜索:
<input type="text" class="from-control" v-model="keyword">
label>
div>
div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>Idth>
<th>Nameth>
<th>Ctimeth>
<th>Operationth>
tr>
thead>
<tbody>
<tr v-for="(item,i) in search(keyword)" :key="item.id">
<td>{{ item.id }}td>
<td>{{ item.name }}td>
<td>{{ item.ctime }}td>
<td>
<a href="" @click.prevent="del(i)">删除a>
td>
tr>
tbody>
table>
div>
<script>
//创建Vue实例,得到ViewModel
var vm = new Vue({
el: '#app',
data: {
id:'',
name:'',
keyword: '',
list: [
{id: 1,name: '奔驰',citme: new Date()},
{id: 2,name: '宝马',citme: new Date()}
]
},
methods: {
add(){
//获取到id和name,直接从data上面获取
//组织出一个对象
//把这个对象调用数组的相关方法添加到当前data上的list中
//注意:Vue中已经实现了数据的双向绑定,每当我们修改了data中的数组Vue会默认监听到数据的改动,自动把最新的数据应用到页面上
var car = {id: this.id, name:this.name, ctime: new Date()}
this.list.push(car)
this.id = ''
this.name= ''
},
del(i){
this.list.splice(i,1);
},
search(keyword){
var newList = []
//循环遍历数组中每个元素,使用indexOf判断前字符串是否包含后面的,-1不包含,不输入(空)的时候是0
this.list.forEach(element => {
if (element.name.indexOf(keyword) != -1){
newList.push(element)
}
});
return newList
}
}
})
script>
body>
html>
除了 vue-resource 之外,还可以使用 axios 的第三方包实现实现数据的请求
由于浏览器的安全性限制,不允许AJAX访问 协议不同、域名不同、端口号不同的 数据接口,浏览器认为这种访问不安全;
可以通过动态创建script标签的形式,把script标签的src属性,指向数据接口的地址,因为script标签不存在跨域限制,这种数据获取方式,称作JSONP(注意:根据JSONP的实现原理,知晓,JSONP只支持Get请求);
具体实现过程:
先在客户端定义一个回调方法,预定义对数据的操作;
再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口;
服务器数据接口组织好要发送给客户端的数据,再拿着客户端传递过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行;
客户端拿到服务器返回的字符串之后,当作Script脚本去解析执行,这样就能够拿到JSONP的数据了;
发送get请求:
getInfo() { // get 方式获取数据
this.$http.get(‘http://127.0.0.1:8899/api/getlunbo’).then(res => {
console.log(res.body);
})
}
发送post请求:
postInfo() {
var url = ‘http://127.0.0.1:8899/api/post’;
// post 方法接收三个参数:
// 参数1: 要请求的URL地址
// 参数2: 要发送的数据对象
// 参数3: 指定post提交的编码类型为 application/x-www-form-urlencoded
this.$http.post(url, { name: ‘zs’ }, { emulateJSON: true }).then(res => {
console.log(res.body);
});
}
发送JSONP请求获取数据:
jsonpInfo() { // JSONP形式从服务器获取数据
var url = ‘http://127.0.0.1:8899/api/jsonp’;
this.$http.jsonp(url).then(res => {
console.log(res.body);
});
}
使用过渡类名实现动画
1、使用transition元素,把需要被动画控制的元素包裹起来 ,transition元素是vue官方提供的
2、自定义两组样式来控制transition内部的元素实现动画
注意:自定义的时候要用
.v-enter,
.v-leave-to,
.v-enter-active,
.v-leave-active,
这四个,这样是所有transition包裹的都共有的
要是想自己定义前缀不用v-开头,给某个transition定义单独的动画:就要定义transition name属性然后用自己定义的name的值作为开头
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
<script src="./lib/vue-resource-1.3.4.js">script>
<style>
/* v-enter 是一个时间点 是进入之前,元素的起始状态,此时还没有开始进入 */
/* v-leave-to 是一个时间点 是动画离开之后,离开的终止状态,此时元素动画已经结束 */
.v-enter,
.v-leave-to {
/* 透明度 从 0.0 (完全透明)到 1.0(完全不透明)*/
opacity: 0;
transform: translateX(100px);
}
/* .v-enter-active 入场动画的时间段
.v-leave-active 离场动画的时间段 */
.v-enter-active,
.v-leave-active {
transition: all 0.4s ease;
}
.my-enter,
.my-leave-to {
/* 透明度 从 0.0 (完全透明)到 1.0(完全不透明)*/
opacity: 0;
transform: translateY(100px);
}
.my-enter-active,
.my-leave-active {
transition: all 0.4s ease;
}
style>
head>
<body>
<div id="app">
<input type="button" value="按钮" @click="flag=!flag">
<transition>
<h3 v-if="flag">这是一个h3h3>
transition>
<input type="button" value="按钮" @click="flag1=!flag1">
<transition name="my">
<h3 v-if="flag1">这是一个h3h3>
transition>
div>
<script>
// 创建 Vue 实例,得到 ViewMode
var vm = new Vue({
el: '#app',
data: {
flag: false,
flag1: false
},
methods: {}
});
script>
body>
html>
beforeEnter 表示动画入场之前,此时,动画尚未开始,可以在beforeEnter中设置元素开始动画之前的起始样式
enter 表示动画开始之后的样式,这里可以设置小球完成动画之后的结束状态,done需要写
动画完成之后 会调用afterEnter
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
<script src="./lib/vue-resource-1.3.4.js">script>
<style>
.ball {
width: 15px;
height: 15px;
border-radius: 50%;
background-color: red;
}
style>
head>
<body>
<div id="app">
<input type="button" value="按钮" @click="flag=!flag">
div>
transition>
div>
<script>
// 创建 Vue 实例,得到 ViewMode
var vm = new Vue({
el: '#app',
data: {
flag: false,
},
methods: {
//注意:动画钩子函数的第一个参数:el,表示要执行动画的那个DOM元素,是个原生的JS DOM对象
//可以认为el是 :通过document.getElementById('')方式获取到的原生JS DOM对象
beforeEnter(el){
//beforeEnter 表示动画入场之前,此时,动画尚未开始,可以在beforeEnter中设置元素开始动画之前的起始样式
//设置小球动画之前的起始位置
el.style.transform = "translate(0,0)"
},
enter(el,done){
//这句话没有实际作用但是如果不写出不来动画效果
//可以认为el.offsetWidth会强制动画刷新
el.offsetWidth
//enter 表示动画开始之后的样式,这里可以设置小球完成动画之后的结束状态
el.style.transform = "translate(150px,450px)"
el.style.transition = 'all 1s ease'
//这里的done 其实就是afterEnter这个函数,也就是说:done 是afterEnter函数的引用
done()
},
afterEnter(el){
//动画完成之后 会调用afterEnter
this.flag = !this.flag
}
}
});
script>
body>
html>
列表动画 transitionGroup
- 在实现列表过渡的时候,如果需要过渡的元素,是通过 v-for 循环渲染出来的,不能使用 transition 包裹,需要使用
- transitionGroup 如果要为 v-for 循环创建的元素设置动画,必须为每一个 元素 设置 :key 属性
- 给 ransition-group 添加 appear 属性,实现页面刚展示出来时候,入场时候的效果
- 通过 为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为 span 标签
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
<style>
li {
border: 1px dashed #999;
margin: 5px;
line-height: 35px;
padding-left: 5px;
font-size: 12px;
width: 100%;
}
li:hover {
background-color: hotpink;
transition: all 0.8s ease;
}
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateY(80px);
}
.v-enter-active,
.v-leave-active {
transition: all 0.6s ease;
}
/* 下面的 .v-move 和 .v-leave-active 配合使用,能够实现列表后续的元素,渐渐地漂上来的效果 */
.v-move {
transition: all 0.6s ease;
}
.v-leave-active{
position: absolute;
}
style>
head>
<body>
<div id="app">
<div>
<label>
Id:
<input type="text" v-model="id">
label>
<label>
Name:
<input type="text" v-model="name">
label>
<input type="button" value="添加" @click="add">
div>
<transition-group appear tag="ul">
<li v-for="(item, i) in list" :key="item.id" @click="del(i)">
{{item.id}} --- {{item.name}}
li>
transition-group>
div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
list: [
{ id: 1, name: '赵高' },
{ id: 2, name: '秦桧' },
{ id: 3, name: '严嵩' },
{ id: 4, name: '魏忠贤' }
]
},
methods: {
add() {
this.list.push({ id: this.id, name: this.name })
this.id = this.name = ''
},
del(i) {
this.list.splice(i, 1)
}
}
});
script>
body>
html>
8、组件
创建全局组件的方式
建议:最好使用一个div包裹起来
方式一:Vue.extend配合Vue.component
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<my-com1>my-com1>
div>
<script>
//1.1 使用 Vue.extend 来创建全局的组件
var com1 = Vue.extend({
//通过template属性 制定了组件要展示的HTML结构
template: '这是使用 Vue.extend 创建的组件
'
})
//1.2 使用Vue.component('组件的名称',创建出来的组件模板对象)
Vue.component('myCom1',com1)
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
},
methods: {
}
});
script>
body>
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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<mycom2>mycom2>
div>
<script>
Vue.component('mycom2',{
template:'这是使用 Vue.component 创建的组件
'
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
},
methods: {
}
});
script>
body>
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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<mycom3>mycom3>
div>
<template id="tmp1">
<div>
<h1>这是通过template元素在外部定义的组件结构,这个方式有代码的只能提示和高亮显示h1>
div>
template>
<script>
Vue.component('mycom3',{
template:'#tmp1'
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
},
methods: {
}
});
script>
body>
html>
创建私有组件的方式components
组件中的data和methods
- 1、组件可以有自己的data数据
- 2、组件的data和实例的data有点不一样,实例中的data可以为一个对象,但是组件中的data必须是一个方法
- 3、组件中的data除了必须是一个方法外这个方法内部还必须返回一个对象才行
- 4、组建中的data数据使用方式和实例中的完全一样
- 5、methods完全一样
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<mycom2>mycom2>
div>
<script>
// 1、组件可以有自己的data数据
// 2、组件的data和实例的data有点不一样,实例中的data可以为一个对象,但是组件中的data必须是一个方法
// 3、组件中的data除了必须是一个方法外这个方法内部还必须返回一个对象才行
// 4、组建中的data数据使用方式和实例中的完全一样
Vue.component('mycom2',{
template:'这是全局组件 --- {{msg}}
',
data: function () {
return {
msg: '组件中的data定义的数据'
}
},
methods: {
}
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
},
methods: {
}
});
script>
body>
html>
组件切换
使用 v-if v-else
注意:使用 v-if v-else 只能切换两个组件
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<a href="" @click.prevent="chan">登录a>
<a href="" @click.prevent="chan">注册a>
<com1 v-if="flag">com1>
<com2 v-else="flag">com2>
div>
<template id="tmp1">
<h3>loginh3>
template>
<template id="tmp2">
<h3>registerh3>
template>
<script>
Vue.component('com1',{
template: '#tmp1',
data: function () {
return {
}
},
methods: {
}
})
Vue.component('com2',{
template: '#tmp2',
data: function () {
return {
}
},
methods: {
}
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
flag: true
},
methods: {
chan(){
this.flag = !this.flag
}
}
});
script>
body>
html>
使用component
- Vue提供了 component 来展示对应名称的组件
- component 是一个占位符 :is 属性,可以用来指定要展示的组件的名称
- 因为:is是绑定了属性,这样如果只是输入com1会被当做需要查找的数据去data里面找,因此需要加上单引号表示他是字符串
- 如果只是 is 没有绑定的话,那么 is=“com1” 这个com1就是一个字符串
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
head>
<body>
<div id="app">
<a href="" @click.prevent="comName='com1'">登录a>
<a href="" @click.prevent="comName='com2'"> 注册a>
<component :is="comName">component>
div>
<template id="tmp1">
<h3>loginh3>
template>
<template id="tmp2">
<h3>registerh3>
template>
<script>
Vue.component('com1',{
template: '#tmp1',
data: function () {
return {
}
},
methods: {
}
})
Vue.component('com2',{
template: '#tmp2',
data: function () {
return {
}
},
methods: {
}
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
comName: 'com1'
},
methods: {
}
});
script>
body>
html>
切换动画
直接用transition包裹,对动画的操作就是按之前那样
父子组件传值
默认情况下,子组件是无法访问到父组件上的data和methods
传值方法:通过在调用的时候绑定自定义属性,把父组件上的值传给他,然后在子组件的props:[ ]属性中定义一个和绑定的自定义属性名称一样的属性,然后就可以在子组件中使用了
传方法的方法:
调用父组件方法并向父组件传参的话:从第二个参数开始都是传参,下图的123,456,传递给了data,data2
子组件向父组件传值的话:通过方法传参,然后在方法中传值
案例:评论列表
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
<link rel="stylesheet" href="./lib/bootstrap-3.3.7.css">
head>
<body>
<div id="app">
<cmt @fun="addComment">cmt>
<ul class="list-group">
<li class="list-group-item" v-for="item in list" :key="item.id">
<span class="badge">评论人:{{item.user}}span>
{{item.content}}
li>
ul>
div>
<template id="tmp1">
<div>
<div class="form-group">
<label >评论人:label>
<input type="text" class="form-control" v-model="user">
div>
<div class="form-group" >
<label >评论内容:label>
<textarea class="form-control" v-model="content">textarea>
div>
div>
template>
<script>
var commentBox = {
template: '#tmp1',
data() {
return {
user: '',
content:''
}
},
methods: {
add() {
var comment = {id: Date.now() ,user: this.user,content:this.content}
this.$emit('fun',comment)
}
}
}
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
list: [
{id: Date.now(), user: '李白', content: '天生我才必有用'},
{id: Date.now(), user: '江小白', content: '西出阳关无故人'},
{id: Date.now(), user: '小马', content: '我叫小马'}
],
},
methods: {
addComment(data){
this.list.push(data)
}
},
components:{
'cmt': commentBox
}
});
script>
body>
html>
9、ref获取元素和组件
通过vm实例中自带的$refs属性可以获取到
可以获取组件中的数据、方法,直接点就可以
10、Vue路由
什么是路由
后端路由就是URL地址和服务器资源的对应关系
前端路由就是相当于点击a链接然后换切换不同的组件,这些组件不涉及到页面的刷新,都是在同一个页面进行的
URL中的hash(# - 井号)
安装路由
两个方式:第一个直接官网下载,然后导入包,第二个使用npm进行安装(基于模块开发的时候使用)
路由的基本使用
首先:安装路由模块
然后:创建一个路由对象,当导入vue-router包之后,在window全局对象中就有了一个路由的构造函数,叫做VueRouter
最后和vm实例进行关联,注意使用路有的时候就可以不用在vm的components属性中定义对应的私有组件,直接声明出来一个组件模板对象就可以,不需要使用components了
(注意:这里没有components属性)
router-link
redirect重定向
可以默认让他监听到URL是前面path路径时就变为后面redirect的路径(这里的路径是#之后的)
设置选中路由高亮
router-link 中默认有类,当选中时(激活链接时)才会有
所以可以直接设置这个类的样式
也可以修改默认的这个类名,然后设置对应类样式
路由切换动画
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
<script src="./lib/vue-router-3.0.1.js">script>
<style>
.myactive {
background-color: red;
}
style>
head>
<body>
<div id="app">
<router-link to="/login" tag="span">登录router-link>
<router-link to="/register">注册router-link>
<router-view>router-view>
div>
<script>
//组件的模板对象
var login = {
template: '登录组件
'
}
var register = {
template: '注册组件
'
}
//2、创建一个路由对象,当导入vue-router包之后,在window全局对象中就有了一个路由的构造函数,叫做VueRouter
//在 new 路由对象的时候可以为构造函数传递一个配置对象
var routerObj = new VueRouter({
// route 这个配置对象中的route表示 路由匹配规则 的意思
routes: [ //路由匹配规则
//每个路由规则都是一个对象,这个规则对象身上有两个必须的属性:
//属性1 :是path,表示监听哪个路由连接地址
//属性2 :是component ,表示,如果路由是前面匹配到的path,则展示 component 属性对应的那个组件
//这里必须要填组件模板对象的名称,而不是组件引用名称(就是可以通过尖括号在html里面引用的名称)
{path: '/' , redirect: '/login'},
{path: '/login' , component: login},
{path: '/register' , component: register}
],
linkActiveClass:'myactive'
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
},
methods: {
},
router: routerObj ,// 3、将路由规则对象注册到vm实例上,用来监听URL地址的变化,然后展示对应的组件
});
script>
body>
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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
<script src="./lib/vue-router-3.0.1.js">script>
head>
<body>
<div id="app">
<router-link to="/login?id=10&name=zs">登录router-link>
<router-link to="/register">注册router-link>
<router-view>router-view>
div>
<script>
var login = {
//传参的this可以省略
template: '登录 --- {{this.$route.query.id}} --- {{$route.query.name}}
',
created(){//组件的生命周期钩子函数
console.log(this.$route.query.id)
}
}
var register = {
template: '注册
'
}
var router = new VueRouter({
routes: [
{ path: '/login', component: login },
{ path: '/register', component: register }
]
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
},
methods: {
},
//属性名和属性值一样的话只写一个就可以他会自动解析成 xxx:xxx 的形式
// router: router
router
});
script>
body>
html>
使用children属性实现路由(路由嵌套)
这里的router-view是用来放登录注册所要显示的东西的(登录注册组件的内容)
11、路由-使用命名视图实现经典布局
<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>Documenttitle>
<script src="./lib/vue-2.4.0.js">script>
<script src="./lib/vue-router-3.0.1.js">script>
<style>
body {
margin: 0;
padding: 0;
}
.header {
background-color: orange;
height: 80px;
}
h1 {
margin: 0;
padding: 0;
}
.container {
display: flex;
height: 600px;
}
.left {
background-color: orchid;
flex: 1;
}
.right {
background-color: pink;
flex: 3;
}
style>
head>
<body>
<div id="app">
<router-view>router-view>
<div class="container">
<router-view name="left">router-view>
<router-view name="right">router-view>
div>
div>
<script>
var header = {
template: '头部
'
}
var leftBox = {
template: '左部
'
}
var rightBox = {
template: '右部
'
}
//创建路由对象
var router = new VueRouter({
routes: [
//components后面跟对象,表示这一个路径下可以匹配多个组件 , 加上单引号是为了在router-view中引用
{ path: '/', components: {
'default': header,
'left': leftBox,
'right': rightBox
} }
]
});
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
},
methods: {
},
router
});
script>
body>
html>
12、Watch、computed
使用keyup事件监听
使用watch监听文本框
watch 监听路由地址变化
computed