Vue教程
Vue安装与使用Vue起步Vue基本结构Vue基本指令Vue绑定样式Vue循环指令Vue条件语句Vue过滤器Vue按键修饰符Vue自定义指令Vue监听属性Vue计算属性Vue生命周期Vue ajax安装方法get方法post方法axios APIconfig配置Vue动画语法格式过渡的类名自定义过渡类名JavaScript 钩子列表过渡过渡模式组件过渡Vue组件全局组件注册局部组件注册外部定义组件
Vue安装与使用
1.使用cdn
<script src="https://unpkg.com/vue/dist/vue.js"></script>
or
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
2.官网下载
进入英文官网
- 第一个为开发版本,包含完整的警告和调试模式
- 第二个为生产版本,压缩了代码,删除了警告
根据自己的需求下载合适的版本,需要注意的是中文的官网点击下载出现的是源码
在html文件中用script标签直接引入Vue就可使用
Vue起步
Vue基本结构
每个 Vue 应用都需要通过实例化 Vue 来实现
var vm = new Vue()
Vue构造器基本的参数
参数 | 含义 |
---|---|
el | 表示当前new的这个vue的实例,即要控制哪个区域 |
data | 用于定义属性,当属性改变时,html的内容也发生改变,不需要手动操作DOM元素 |
methods | 用于定义函数 |
html代码
<div id="app">
<p>{{msg}}</p>
<p>{{show()}}</p>
</div>
js代码
var vm=new Vue({
el:"#app",
data:{
msg:'Hello'
},
methods:{
show:function(){
return 'World'
}
}
})
输出结果:
Vue基本指令
{{ }}和v-cloak
{{ }}插值表达式的作用:用于输出对象属性和函数返回值
v-cloak作用:解决插值表达式闪烁的问题,即在为了防止出现Vue的变量名,在DOM染完成后才显示
用法:
html:
html <p v-cloak>{{msg}}</p>
css
css [v-cloak]{ display: none; }
v-text 和 v-html
默认的v-text是没有闪烁的,和插值表达式的不同是v-text会覆盖元素中原本的内容,但是插值表达式只会替换自己的占位符,而不会把整个元素的内容清空
<p v-text="msg">haha</p>
输出结果:Hello
使用 v-html 指令用于输出 html 代码
v-bind 和 v-on
v-bind用于绑定属性,简写 :
v-on用于绑定方法,简写 @
代码示例
<div id="app">
<input type="text" v-bind:value="val"/>
<br/>
<span v-on:mouseover="show()">鼠标移到这</span>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
val:"这里绑定了输入框的值"
},
methods: {
show: function() {
alert("移到这了!")
}
}
})
</script>
输出结果:
v-model
v-model 指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。
<div id="app">
<p>{{msg}}</p>
<input v-model="msg">
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
msg: "绑定"
}
})
</script>
Vue绑定样式
例:
.color{
color: #ffffff;
}
.bkcolor{
background-color: #ff0000;
.size{
font-size: 20px;
}
:class为v-bind:class的简写
1.使用数组绑定
<div id="app">
<h1 :class="['color','bkcolor','size']">这是一个用Vue绑定样式的标题</h1>
</div>
<script>
var vm = new Vue({
el: "#app",
//也可将数组的内容写在data域里
})
</script>
结果:
2.数组中使用三元表达式或者镶嵌对象
<div id="app">
<h1 :class="[flag?'color':'','bkcolor','size']">这是一个用Vue绑定样式的标题1</h1>
<h1 :class="['color','bkcolor',{'size':flag}]">这是一个用Vue绑定样式的标题2</h1>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
flag:false
//也可将数组内容写在data区域
}
})
</script>
3.使用对象
<div id="app">
<h1 :class="h_class">这是一个用Vue绑定样式的标题</h1>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
h_class:{
color:true,
bkcolor:true,
size:false
}
}
})
</script>
4.使用:style(v-bind:style)内联样式
Vue循环指令
循环使用 v-for 指令
1.迭代数组
<div id="app">
<span v-for="item in arr">{{item}}</span>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
arr:[1,2,3,4,5]
}
})
</script>
结果:
<div id="app">
<span v-for="item,i in arr">{{i}}=>{{item}} </span>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
arr:[1,2,3,4,5]
}
})
</script>
结果:
2.迭代对象中的属性
<div id="app">
<span v-for="item in arr">{{item.id}}=>{{item.name}} </span>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
arr:[
{id:1,name:'ls1'},
{id:2,name:'ls2'},
{id:2,name:'ls3'}
]
}
})
</script>
<div id="app">
<span v-for="item,i in arr">{{i}}=>{{item.id}}=>{{item.name}} </span>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
arr:[
{id:1,name:'ls1'},
{id:2,name:'ls2'},
{id:2,name:'ls3'}
]
}
})
</script>
<div id="app">
<span v-for="val,key in obj">{{key}}=>{{val}} </span>
<!--可以有第三个值,索引-->
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
obj:{
id:123456,
name:"zs",
sex:"M"
}
}
})
</script>
3.迭代数字
迭代数字从1开始
<div id="app">
<span v-for="count in 5">{{count}}</span>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{}
})
</script>
Vue条件语句
v-if:每次都会重新创建或者删除元素
v-show:不会重新进行对DOM删除或者创建,只是切换了元素的display:none的属性
v-if有更高的切换消耗v-show有更高的初始渲染消耗,因此如果需要频繁切换v-show较好,如果运行条件不大可能改变v-if更好
<div id="app">
<span v-if="hasinfor">您已登陆</span>
<!--v-else-if用于多重判断-->
<span v-else="hasinfor">请登录登陆</span>
<span v-show="hasinfor">您已登陆</span>
<span v-show="!hasinfor">请登录登陆</span>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
hasinfor:false
}
})
</script>
Vue过滤器
可被用作一些常见文本格式化,可在mustachc插值和v-bind表达式
过滤器调用格式
{{name|过滤器名称}}
全局过滤器的使用
Vue.filter('过滤器名称',function(){})
私有过滤器的使用
filters:{
过滤器名称:function(){}
}
例子:
<div id="app">
<p>{{msg|msgFormat}}</p>
</div>
<script>
Vue.filter('msgFormat',function(msg){
return msg.replace('邪恶','单纯')
})
var vm = new Vue({
el: "#app",
data:{
msg:"他是一个邪恶的男孩"
}
})
</script>
/*****私有过滤器的使用方法
var vm = new Vue({
el: "#app",
data:{
msg:"他是一个邪恶的男孩"
},
filters:{
msgFormat:function(msg){
return msg.replace('邪恶','单纯')
}
}
})
*****/
输出:他是一个单纯的男孩
Vue按键修饰符
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符
<!--在输入框绑定回车事件submit-->
<input v-on:keyup.enter="submit">
Vue 提供了绝大多数常用的按键码的别名
- enter
- tab
- delete (捕获“删除”和“退格”键)
- esc
- space
- up
- down
- left
- right
可以通过全局 config.keyCodes 对象自定义按键修饰符别名
// 可以使用v-on:keyup.f1,112为f1的键码
Vue.config.keyCodes.f1 = 112
Vue自定义指令
对普通 DOM 元素进行底层操作,这时候就会用到自定义指令
自定义指令使用方法:
v-指令名称
全局自定义指令的注册
Vue.directive('指令名称',{
//第二个参数为一个对象,包括不同的钩子函数,常用bind,inserted,update
bind:function(){},
inserted:function(){},
update:function(){}
})
局部自定义指令的注册
directives:{
指令名称:{
bind:function(){},
inserted:function(){},
update:function(){}
}
}
例子:
<div id="app">
<p v-color>测试文字</p>
</div>
<script>
Vue.directive('color',{
bind:function(el){
el.style.color="red";//el是直接对dom元素进行操作
}
})
</script>
/*****私有指令的使用方法
var vm = new Vue({
el: "#app",
data:{},
directives:{
color:{
bind:function(el){
el.style.color="red";
}
}
}
})
*****/
钩子函数
函数名称 | 作用 |
---|---|
bind | 只调用一次,指令第一次绑定到元素时调用 |
inserted | 被绑定元素插入父节点时调用 |
update | 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前 |
componentUpdated | 指令所在组件的 VNode 及其子 VNode 全部更新后调用 |
unbind | 只调用一次,指令与元素解绑时调用 |
钩子函数参数- el:指令所绑定的元素,可以用来直接操作 DOM 。
- binding:一个对象,包含以下属性:
- name:指令名,不包括 v- 前缀。
- value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
- oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
- expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
- arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
- modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
- vnode:Vue 编译生成的虚拟节点。
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
<div id="app" v-demo:foo.a.b="message"></div>
<script>
Vue.directive('demo', {
bind: function(el, binding){
el.innerHTML =
'name: ' + binding.name + '<br>' +
'value: ' + binding.value + '<br>' +
'expression: ' + binding.expression + '<br>' +
'argument: ' + binding.arg + '<br>' +
'modifiers: ' + JSON.stringify(binding.modifiers) + '<br>'
}
})
var vm = new Vue({
el: "#app",
data: {
message:"hello"
},
})
</script>
输出结果:
Vue监听属性
可以通过 watch 来响应数据的变化
格式:
watch:{
监听的属性:function (newvalue,oldvalue) {}
}
例子:
<div id="app">
请输入姓:<input type="text" v-model="fistname" /><br />
请输入名:<input type="text" v-model="lastname" /><br />
姓名:<span>{{fullname}}</span>
<p>{{log}}</p>
</div>
<script>
var vue = new Vue({
el: '#app',
data:{
fistname:'',
lastname:'',
fullname:'',
log:''
},
watch:{
'fistname':function () {
this.fullname=this.fistname+this.lastname;
},
'lastname':function () {
this.fullname=this.fistname+this.lastname;
},
'fullname':function (newname,oldname) {
this.log='您的姓名由'+oldname+'改成'+newname;
},
}
})
</script>
Vue计算属性
计算属性关键词: computed
计算属性的本质就是一个方法,只不过,在使用这些计算属性的时候,是把他们的名称直接当作属性使用,并不会当作方法
可以使用 methods 来替代 computed,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。使用 computed 性能会更好,但不希望缓存,可以使用 methods 属性
var vue = new Vue({
el: '#app',
computed:{
}
})
Vue生命周期
生命周期钩子=生命周期函数=生命周期事件
图示:
钩子函数
生命周期钩子 | 详情 | 应用 |
---|---|---|
beforeCreate | 在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用,不能访问到data以及methods等 | 初始化非响应式变量 |
created | 实例已经创建完成之后被调用。可访问data以及methods等,未挂载DOM,不能访问$el | 简单的ajax请求以及页面的初始化 |
beforeMount | 在挂载开始之前被调用,可访问到$el | |
mounted | 挂载到实例上去之后调用该钩子 | 常用于获取VNode信息和操作,ajax请求 |
beforeUpdate | 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前 | 更新之前访问现有的DOM,手动移除已添加的事件监听器 |
updated | 虚拟 DOM 重新渲染和打补丁之后调用 | 避免在这个钩子函数中操作数据,可能陷入死循环 |
beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用。 | 常用于销毁定时器、解绑全局事件、销毁插件对象等操作 |
destroyed | Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 |
Vue ajax
Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求
Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中
安装方法
1.使用cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
2.使用npm
$ npm install axios
get方法
示例:
<div id="app"></div>
<script>
var vue = new Vue({
el: '#app',
mounted() {
axios
.get(url)//url地址
.then(function(response){
console.log(response.data);
})//.then为请求数据成功后的函数
.catch(function(error) {
console.log(error);
});//.catch为请求数据失败后的函数
}
})
</script>
get传参
1.在url上拼接参数
axios
.get(url+'?key1=value1&key2=value2')
2.使用params传参
axios
.get(url,{
params:{
key1:value1,
key2:value2
}
})
post方法
<div id="app"></div>
<script>
var vue = new Vue({
el: '#app',
mounted() {
axios
.post(url)//url地址
.then(function(response){
console.log(response.data);
})//.then为请求数据成功后的函数
.catch(function(error) {
console.log(error);
});//.catch为请求数据失败后的函数
}
})
</script>
post传参
axios
.post(url,{
key1:value1,//第一个参数
key2:value2//第二个参数
})
axios API
可以通过向 axios 传递相关配置来创建请求
<script>
var vue = new Vue({
el: '#app',
mounted() {
axios({
method: 'get',
url:url,
params:{
key:value
}
})//config配置,具体见下文
.then(function(response){
console.log(response.data);
})//.then为请求数据成功后的函数
.catch(function(error) {
console.log(error);
});//.catch为请求数据失败后的函数
}
})
</script>
请求方法别名
在使用别名方法时, url、method、data 这些属性都不必在配置中指定。
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
例如:
<div id="app"></div>
<script>
var vue = new Vue({
el: '#app',
mounted() {
axios
.get(url,{
//此处对config里的参数进行配置
//与请求一起发送的 URL 参数
params:{
key=value
},
//指定请求超时的毫秒数
timeout:1000,
})//url地址
.then(function(response){
console.log(response.data);
})//.then为请求数据成功后的函数
.catch(function(error) {
console.log(error);
});//.catch为请求数据失败后的函数
}
})
</script>
axios响应结构
{
// `data` 由服务器提供的响应
data: {},
// `status` HTTP 状态码
status: 200,
// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: "OK",
// `headers` 服务器响应的头
headers: {},
// `config` 是为请求提供的配置信息
config: {}
}
默认配置
1.默认全局配置
axios.defaults.baseURL = 主目录url;
2.自定义的实例默认设置
var instance = axios.create({
baseURL: 主目录url,
timeout:1000
});
instance
.get('/下一级目录')
//修改
instance.defaults.baseURL = url;
config配置
Vue动画
语法格式
<transtion>
<!--变化的DOM-->
</transtion>
过渡的类名
即用相应类名的css控制变化前后以及变化的时长
类名 | 作用 |
---|---|
v-enter | 定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除 |
v-enter-active | 定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数 |
v-enter-to | 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除 |
v-leave | 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除 |
v-leave-active | 定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。 |
v-leave-to | 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除 |
***如果transition没有指定name属性的值,默认类名为上表的类名,即v-(如v-enter),如果指定了name的值,则类名为:name的值-(如name=“fade”,类名为fade-enter)
例子:
css
/*默认的transition*/
.v-enter,.v-leave-to{
opacity: 0;
transform: translateX(100px);
}
.v-enter-active,.v-leave-active{
transition: all 0.8s linear;
}
/*指定name属性的transition*/
.fade-enter,.fade-leave-to{
opacity: 0;
transform: translateY(100px);
}
.fade-enter-active,.fade-leave-active{
transition: all 1s linear;
}
html
<div id="app">
<div>
<input type="button" value="h1变化" @click="flag1=!flag1"/>
<transition>
<h1 v-if="flag1">这是一个可以变化的h1</h1>
</transtion>
</div>
<div>
<input type="button" value="h2变化" @click="flag2=!flag2"/>
<transition name="fade">
<h2 v-if="flag2">这是一个可以变化的h2</h2>
</transition>
</div>
</div>
<script>
var vue = new Vue({
el: '#app',
data:{
flag1:false,
flag2:false
}
})
</script>
自定义过渡类名
自定义过渡的类名优先级高于普通的类名,这样就能很好的与第三方(如:animate.css)的动画库结合使用
- enter-class
- enter-active-class
- enter-to-class (2.1.8+)
- leave-class
- leave-active-class
- leave-to-class (2.1.8+)
:duration用于设置过渡动画时间
<transition :duration="800">...</transition>
<transition :duration="{ enter: 600, leave: 1000 }">...</transition>
例如:
<!--前面引入Animate.css动画库-->
<div id="app">
<input type="button" value="h1变化" @click="show=!show"/>
<transition
enter-active-class="bounceIn"
leave-active-class="bounceOut"
:duration="1000"
>
<h1 v-if="show">这是一个使用自定义动画的h1</h1>
</transtion>
</div>
<script>
var vue = new Vue({
el: '#app',
data:{
show:false,
}
})
</script>
JavaScript 钩子
html
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
</transition>
函数 | 作用 |
---|---|
beforeEnter(el) | el,表示要执行动画的DOM元素,是个原生的js对象,动画入场之前 |
function(el, done) | 动画开始之后的样子,在这可以设置结束状态,done的起始就是afterEnter,done为afterEnter的引用 |
afterEnter(el) | 动画完成之后调用 |
**leave函数类似
***在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
***推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css=“false”,Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响
小球移动例子:
<div id="app">
<input type="button" value="jump" @click="show=!show"/>
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
>
<div v-if="show" style="width: 20px;height: 20px;border-radius: 50%;background: red;"></div>
</transtion>
</div>
<script>
var vue = new Vue({
el: '#app',
data:{
show:false,
},
methods:{
beforeEnter:function(el){
el.style.transform="translate(0,0)";
},
enter:function(el,done){
el.offsetWidth;
//可以认为el.offsetWidth会强制动画刷新,不加没动画
el.style.transform="translate(150px,450px)";
el.style.transition="all 1s ease";
done();
},
afterEnter:function(el){
this.show=!this.show;
}
}
})
</script>
列表过渡
1.在实现列表过渡的时候,如果需要过渡的元素是通过v-for循环渲染出来的,则使用transition-group包裹
2.不同于 transition,transition-group会以一个真实元素呈现,默认为span,可以通过 tag 特性更换为其他元素
3.内部元素总是需要提供唯一的 key 属性值
例子:随机在数组位置中插入一个数字以及随机减少一个数字
css
.num{
margin-right: 10px;
display: inline-block;
}
.num-enter, .num-leave-to{
opacity: 0;
transform: translateY(20px);
}
.num-enter-active, .num-leave-active {
transition: all 1s linear;
}
html
<div id="app">
<input type="button" value="Add" @click="add"/>
<input type="button" value="remove" @click="remove"/>
<transition-group name="num" tag="div">
<span class="num" v-for="item in arr" v-bind:key="item">{{item}}</span>
</transition-group>
</div>
<script>
var vue = new Vue({
el: '#app',
data:{
arr:[1,2,3,4,5,6,7,8,9],
nextnum:10//为了使key唯一,让增加的数字每次都不同,在9之后
},
methods:{
add:function(){
var index=Math.floor(Math.random() * this.arr.length);
return this.arr.splice(index,0,this.nextnum++);
},
remove:function(){
var index=Math.floor(Math.random() * this.arr.length);
return this.arr.splice(index,1);
}
}
})
</script>
上述例子中,添加和移除元素的时候,周围的元素会瞬间移动到他们的新布局的位置,而不是平滑的过渡,为了解决这个问题,则添加下面代码
/*这两个类需要配合使用,才能让其他元素有动画*/
.num-move{
transition: all 1s linear;
}
.num-leave-active{
position: absolute;
}
过渡模式
transition的默认行为是进入和离开同时发生,可以通过vue提供的过渡模式让进入和离开分别进行
格式:
<transitio mode="out-in">
</transition>
模式 | 方式 |
---|---|
in-out | 新元素先进行过渡,完成之后当前元素过渡离开 |
out-in | 当前元素先进行过渡,完成之后新元素过渡进入 |
组件过渡
Vue组件
组件可以扩展 HTML 元素,封装可重用的代码。组件化是从UI的角度进行划分,前端的组件化,方便UI组件的重用
全局组件注册
格式:
Vue.component(tagName, options)
调用组件的方式
<tagName></tagName>
如果为驼峰命名,则采用将大写改小写,两个单词用-分离
例:
<div id="app">
<com></com>
<my-com></my-com>
</div>
<script>
Vue.component('com',{
template:"<h1>这是由vue创建的第一个全局组件</h1>",
//通过template属性指定要展示的HTML结构
})
Vue.component('myCom',{
template:"<h1>这是由vue创建的第二个全局组件</h1>",
//调用采用my-com的标签
})
var vue = new Vue({
el: '#app',
data:{}
})
</script>
**需要注意的是,template属性指向的模板内容必须有且只有唯一的根元素
局部组件注册
格式:
components:{
tagName: options
}
例子
<div id="app">
<my-com2></my-com2>
</div>
<script>
var vue = new Vue({
el: '#app',
data:{},
components:{
myCom2:{
template:"<h1>这是由vue创建的私有组件</h1>"
}
}
})
</script>
外部定义
通过template标签可在外面定义的组件结构后调用
<template id="t_com">
<h1>这是通过template元素在外面定义的组件结构</h1>
</template>
<div id="app">
<t-com></t-com>
</div>
<script>
Vue.component('tCom',{
template:'#t_com'
})
var vue = new Vue({
el: '#app',
data:{}
})
</script>
组件的数据和方法
1.组件可以有自己的数据,但是组件中的数据必须为一个方法
2.在方法的内部,必须返回一个对象
3.调用方式和实例中的data一样
例子:计数器
<template id="counter">
<div>
<input type="button" value="+" @click="add"/>
<p>{{count}}</p>
</div>
</template>
<div id="app">
<counter></counter>
</div>
<script>
Vue.component('counter',{
template:'#counter',
data:function(){
return {
count:0
}
},
methods:{
add:function(){
this.count++
}
}
})
var vue = new Vue({
el: '#app',
data:{},
})
</script>
父组件向子组件传值
使用v-bind 动态绑定 props的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件,props值为只读
<div id="app">
<com v-bind:parentmsg="msg"></com>
<!--parentmsg通过props传递到父组件中被调用,传递的值为msg-->
</div>
<script>
Vue.component('com',{
template:"<h1>这是子组件and{{parentmsg}}</h1>",
props:['parentmsg'],
//只有通过props数组,子组件才可以调用传递过来的值
})
var vue = new Vue({
el: '#app',
data:{
msg:"这是父组件的数据"
}
})
</script>
子组件向父组件传值
使用 v-on 绑定自定义事件,使用 $emit(eventName) 触发事件
<template id="com">
<input type="button" value="点击子组件向父组件传值" @click="myclick"/>
</template>
<div id="app">
<!--通过v-on绑定子组件中触发的函数func,交给父组件中的show方法来处理,参数为子组件传递的参数-->
<com v-on:func="show"></com>
</div>
<script>
//添加子组件的点击事件为myclick,通过myclick触发函数,后面跟要传递的值
Vue.component('com',{
template:"#com",
data(){
return{
childmsg:"这是子组件的值"
}
},
methods:{
myclick:function(){
this.$emit('func',this.childmsg)
}
}
})
var vue = new Vue({
el: '#app',
methods:{
show:function(data){
console.log(data)
}
}
})
</script>
组件切换
1.使用v-if/v-else进行显示和隐藏
<div id="app">
<a href="" @click.prevent="flag=true">登陆</a>
<a href="" @click.prevent="flag=false">注册</a>
<!--click.prevent阻止默认事件-->
<login v-if="flag"></login>
<register v-else></register>
</div>
<script>
Vue.component('login',{
template:"<h3>登陆组件</h3>"
})
Vue.component('register',{
template:"<h3>注册组件</h3>"
})
var vue = new Vue({
el: '#app',
data:{
flag:true
},
})
</script>
2.使用component来展示对应名称的组件,:is属性可以用来指定展示的组件名称,类型为字符串,所以用’ ’
<div id="app">
<a href="" @click.prevent="cname='login'">登陆</a>
<a href="" @click.prevent="cname='register'">注册</a>
<!--click.prevent阻止默认事件-->
<component :is="cname"></component>
</div>
<script>
Vue.component('login',{
template:"<h3>登陆组件</h3>"
})
Vue.component('register',{
template:"<h3>注册组件</h3>"
})
var vue = new Vue({
el: '#app',
data:{
cname:'login'
},
})
</script>
组件过渡
多个组件过渡不需要使用key属性
例子:
css
.v-enter,.v-leave-to{
transform: translateY(20px);
opacity: 0;
}
.v-enter-active,.v-leave-active{
transition: all 0.5s linear;
}
html
<div id="app">
<a href="" @click.prevent="cname='login'">登陆</a>
<a href="" @click.prevent="cname='register'">注册</a>
<!--click.prevent阻止默认事件-->
<transition mode="out-in">
<component :is="cname"></component>
</transition>
</div>
<script>
Vue.component('login',{
template:"<h3>登陆组件</h3>"
})
Vue.component('register',{
template:"<h3>注册组件</h3>"
})
var vue = new Vue({
el: '#app',
data:{
cname:'login'
},
})
</script>
Vue路由
前端路由:主要通过URL中的hash(#号)来实现不同页面之间的切换,同时hash有个特点,http请求不包含hash相关的内容。这种通过hash改变来切换页面的方式称为前端路由
安装方法
1.使用cdn
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
2.使用npm
npm install vue-router
基本使用
1.创建一个路由对象,VueRouter
var routerobj=new VueRouter()
2.在路由对象里配置路由规则,routes,每个规则都是一个对象。里面包含两个必须属性
1)path,表示监听哪个路由地址。
2)component,表示路由是前面所匹配到的path,则component对应哪个组件,component必须是一个模板对象,不能是组件引用的名称。
var routerobj=new VueRouter({
routes:[
{path:路由地址,component:组件模板对象}
]
})
3.将路由规则对象注册到vm实例上,用来监听URL地址的变化,然后展示对应组件的变化
var vue = new Vue({
el: '#app',
router:routerobj
})
4.router-view将路由规则匹配到的组件展示到页面
<router-view></router-view>
5.切换方式
1)a标签
<a href="#/路由地址"></a>
注意有#进行hash
2)router-link
<router-link to="/路由地址"></router-link>
例子
<div id="app">
<router-link to="/login">登陆</router-link>
<router-link to="/register">注册</router-link>
<router-view></router-view>
</div>
<script>
var login={
template:'<h1>登陆组件</h1>'
}
var register={
template:'<h1>注册组件</h1>'
}
//创建一个路由对象
var routerobj=new VueRouter({
//配置路由规则
routes:[
//component必须是一个模板对象
{path:'/',redirect:'/login'},//重定向,默认path为/login
{path:'/login',component:login},
{path:'/register',component:register}
]
})
var vue = new Vue({
el: '#app',
router:routerobj
})
</script>
点击默认URL和点击登陆时
点击注册时
注:可用redirect进行重定向,使默认的URL展示的指定路由地址
router-link设置
1.router-link默认渲染成a标签,如需要渲染成其他标签,则在标签内添加tag属性,指向设置的标签
<router-link to="/路由地址" tag="li"></router-link>
2.设置选中样式
1)默认选中路由标签的类名为router-link-active,只需修改这个类的样式,即可设置选中样式
2)在路由对象中添加linkActiveClass属性,设置对应的类
var routerobj=new VueRouter({
routes:[],
linkActiveClass:'myClass'
})
路由传参
1.query方式
不需要修改path属性,传参的格式为在连接地址后加?key=value,调用$router.query.key
2.params方式
在path属性后添加/:key,传参的格式为在连接地址后加/value,调用$router.params.key
<div id="app">
<router-link to="/login?id=11&name=hhh">登陆</router-link>
<router-link to="/register/11/hh">注册</router-link>
<router-view></router-view>
</div>
<script>
var login={
template:'<h1>登陆组件<br/>id:{{$route.query.id}}<br/>name:{{$route.query.name}}</h1>'
}
var register={
template:'<h1>注册组件<br/>id:{{$route.params.id}}<br/>name:{{$route.params.name}}</h1>'
}
var routerobj=new VueRouter({
routes:[
{path:'/login',component:login},
{path:'/register/:id/:name',component:register}
]
})
var vue = new Vue({
el: '#app',
router:routerobj
})
</script>
路由的嵌套
在路由匹配规则中用children属性即可实现组件的嵌套
<!-- 用户组件acc里面包含登陆注册组件以及相应的显示 -->
<template id="acc">
<div>
<h1>这里是用户界面</h1>
<!-- 包含父组件路径 -->
<router-link to="/acc/login">登陆</router-link>
<router-link to="/acc/register">注册</router-link>
<router-view></router-view>
</div>
</template>
<div id="app">
<router-link to="/acc">用户界面</router-link>
<router-view></router-view>
</div>
<script>
var login={
template:'<h1>登陆组件</h1>'
}
var register={
template:'<h1>注册组件</h1>'
}
var acc={
template:'#acc'
}
var routerobj=new VueRouter({
routes:[
{
path:'/acc',
component:acc,
//不需要/,否则将以根目录开头
children:[
{path:'login',component:login},
{path:'register',component:register}
]
}
]
})
var vue = new Vue({
el: '#app',
router:routerobj
})
</script>
命名视图
为了同级展示多个视图,则使用命名视图,在路由配置中,使用components配置多个路由视图,name属性对应 router-view的name属性对应components配置对象的名字,如果 router-view 没有设置名字,那么默认为 default
<div id="app">
<router-view></router-view>
<router-view name='a'></router-view>
<router-view name='b'></router-view>
</div>
<script>
var com1={
template:'<h1>组件1</h1>'
}
var com2={
template:'<h1>组件2</h1>'
}
var com3={
template:'<h1>组件3</h1>'
}
var routerobj=new VueRouter({
routes:[
{
path:'/',
components:{
default:com1,
a:com2,
b:com3
}
}
]
})
var vue = new Vue({
el: '#app',
router:routerobj
})
</script>
更多推荐
所有评论(0)