大家好,又见面了,我是全栈君。
一.使用vue文件
继续1的学习,我们知道使用:
可以把.vue文件的内容解析成组件对象的形式:
解析类似如下:
我们使用es6的语法,把render的回调处理参数使用这种处理:
import Vue from 'vue'
import App from './App.vue'
var app = new Vue({
render:h=>h(App)
}).$mount("#app")
显示正常:
二.组件使用
1.组件嵌套
我们已经学习了如何定义组件,组件同样提供了嵌套功能,也就是组件可以嵌套组件:
main.js定义一个组件,注册:
import Vue from 'vue'
import App from './App.vue'
// 注册
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
var app = new Vue({
render:h=>h(App)
}).$mount("#app")
App.vue在组件中嵌套使用:
<template>
<div id="app">
helloworld
<my-component></my-component>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
显示正常:
对于注册组件的第一个参数,是组件名字,第二个参数也就是组件类型对象,我们知道可以解析.vue文件为这样的对象,我们创建:
myComponent.vue:
<template>
<div>A custom component!</div>
</template>
<script>
export default {
name: 'myComponent'
}
</script>
main.js使用es6导入注册:
import Vue from 'vue'
import App from './App.vue'
import myComponent from './myComponent.vue'
Vue.component('my-component', myComponent)
var app = new Vue({
render:h=>h(App)
}).$mount("#app")
2.组件局部注册
除了使用Vue.component注册一个组件,还可以局部注册,注册在vue新建的实例中:
3.父组件给子组件传值
我们在注册一个组件,是my-component组件的子组件:
weComponent.vue:
<template>
<div>
我是myComponent的儿子
</div>
</template>
<script>
export default {
name: 'weComponent'
}
</script>
main.js注册:
import Vue from 'vue'
import App from './App.vue'
import myComponent from './myComponent.vue'
import weComponent from './weComponent.vue'
Vue.component('my-component', myComponent)
Vue.component('we-component', weComponent)
var app = new Vue({
render:h=>h(App)
}).$mount("#app")
myComponent.vue使用:
<template>
<div>
<div>我是myComponent组件</div>
<we-component></we-component>
</div>
</template>
<script>
export default {
name: 'myComponent'
}
</script>
vue组件的传值方式就是使用属性的方式,然后在子组件中用props属性接收,不过在组件中data数据的设置必须使用函数的形式,在调用位置使用v-bind:xx绑定属性即可:
myComponent.vue:
<template>
<div>
<div>我是myComponent组件</div>
<we-component v-bind:val1="val1"></we-component>
</div>
</template>
<script>
export default {
name: 'myComponent',
data:function(){
return {
val1:"我是小李子"
}
}
}
</script>
weComponent.vue子组件接收使用props:
<template>
<div>
我是myComponent的儿子
<h3>{
{val1}}</h3>
</div>
</template>
<script>
export default {
name: 'weComponent',
props:["val1"]
}
</script>
同样的子组件接收到父组件的值,父组件中这个值变化时,子组件会自动更新到,我们可以给父组件加一个方法,修改这个传入子组件的值,在vue中绑定事件使用的是v-on:xx(事件名字)=方法,方法要写在methods属性中,在组件内部,获取data的值只需要this.xx即可!
myComponent.vue:
<template>
<div>
<div>我是myComponent组件</div>
<we-component v-bind:val1="val1"></we-component>
<button v-on:click="clickVal">点击修改val1的值</button>
</div>
</template>
<script>
export default {
name: 'myComponent',
data:function(){
return {
val1:"我是小李子"
}
},
methods:{
clickVal:function(){
this.val1=this.val1+"1"
}
}
}
</script>
点击一次按钮:
4.子组件通信给父组件
是上一种操作的逆处理,vue为我们提供了这样的接口,在子组件的this会有一个$emit方法,他的参数就是绑定在调用这个组件位置上定义的事件:
weComponent.vue:
<template>
<div>
我是myComponent的儿子
<h3>{
{val1}}</h3>
<button v-on:click="clickPar">告诉父组件值+2</button>
</div>
</template>
<script>
export default {
name: 'weComponent',
props:["val1"],
methods:{
clickPar:function(){
this.$emit("parAdd2")
}
}
}
</script>
在父组件自定义这个事件,调用一个对应的方法+2:
myComponent.vue:
<template>
<div>
<div>我是myComponent组件</div>
<we-component v-bind:val1="val1" v-on:parAdd2="clickVal2"></we-component>
<button v-on:click="clickVal">点击修改val1的值</button>
</div>
</template>
<script>
export default {
name: 'myComponent',
data:function(){
return {
val1:"我是小李子"
}
},
methods:{
clickVal:function(){
this.val1=this.val1+"1"
},
clickVal2:function(){
this.val1=this.val1+"2"
}
}
}
</script>
三.tab切换效果
我们这时候会定义多个组件,分别是:
myComponent.vue
youComponent.vue
loveComponent.vue
myComponent.vue:
<template>
<div>
{
{info}}
</div>
</template>
<script>
export default {
name: 'myComponent',
data:function(){
return {
info:"myComponent"
}
}
}
</script>
youComponent.vue:
<template>
<div>
{
{info}}
</div>
</template>
<script>
export default {
name: 'youComponent',
data:function(){
return {
info:"youComponent"
}
}
}
</script>
loveComponent.vue:
<template>
<div>
{
{info}}
</div>
</template>
<script>
export default {
name: 'loveComponent',
data:function(){
return {
info:"loveComponent"
}
}
}
</script>
main.js注册:
import Vue from 'vue'
import App from './App.vue'
import myComponent from './myComponent.vue'
import youComponent from './youComponent.vue'
import loveComponent from './loveComponent.vue'
Vue.component('my-component', myComponent)
Vue.component('you-component', youComponent)
Vue.component('love-component', loveComponent)
var app = new Vue({
render:h=>h(App)
}).$mount("#app")
App.vue应用:
<template>
<div id="app">
<h3>tab切换显示:</h3>
<my-component></my-component>
<you-component></you-component>
<love-component></love-component>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
对于显示隐藏vue为我们提供了v-if和v-show指令,我们在data设置对应的值,控制即可:
<template>
<div id="app">
<h3>tab切换显示:</h3>
<my-component v-if="isshowmy"></my-component>
<you-component v-if="isshowyou"></you-component>
<love-component v-if="isshowlove"></love-component>
</div>
</template>
<script>
export default {
name: 'app',
data:function(){
return {
isshowmy:true,
isshowyou:false,
isshowlove:false
}
}
}
</script>
既然是tab切换,只有内容是不对的,还得有对应的三个菜单,我们写好他们:
<template>
<div id="app">
<h3>tab切换显示:</h3>
<ul>
<li>my-component</li>
<li>you-component</li>
<li>love-component</li>
</ul>
<div>
<my-component v-if="isshowmy"></my-component>
<you-component v-if="isshowyou"></you-component>
<love-component v-if="isshowlove"></love-component>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data:function(){
return {
isshowmy:true,
isshowyou:false,
isshowlove:false
}
}
}
</script>
我们要给li加入事件,控制对应显示,我们最简单就是把data的key做参数传递给定义的方法,修改为true,其他是false:
<template>
<div id="app">
<h3>tab切换显示:</h3>
<ul>
<li v-on:click="tab('isshowmy')">my-component</li>
<li v-on:click="tab('isshowyou')">you-component</li>
<li v-on:click="tab('isshowlove')">love-component</li>
</ul>
<div>
<my-component v-if="isshowmy"></my-component>
<you-component v-if="isshowyou"></you-component>
<love-component v-if="isshowlove"></love-component>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data:function(){
return {
isshowmy:true,
isshowyou:false,
isshowlove:false
}
},
methods:{
tab:function(key){
this.isshowmy=false;
this.isshowyou=false;
this.isshowlove=false;
this[key]=true;
}
}
}
</script>
其实我们还有一个小操作,就是希望地址也对应变化,我们获取key之后,操作window.location.href=#/xx即可!
看地址变化:
四.tab效果修改地址,在激发修改结构显示
我们还是基于上面的例子,我们这次点击li只是修改地址而已:
我们知道vue提供了一个watch属性,可以监听某个属性变化,然后做出处理,我们可以把地址放在data的一个属性中,监听他是否修改,然后在修改显示元素对应的布尔值:
<template>
<div id="app">
<h3>tab切换显示:</h3>
<ul>
<li v-on:click="tab('isshowmy')">my-component</li>
<li v-on:click="tab('isshowyou')">you-component</li>
<li v-on:click="tab('isshowlove')">love-component</li>
</ul>
<div>
<my-component v-if="isshowmy"></my-component>
<you-component v-if="isshowyou"></you-component>
<love-component v-if="isshowlove"></love-component>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data:function(){
return {
url:"",
isshowmy:true,
isshowyou:false,
isshowlove:false
}
},
watch:{
url:function(newurl){
this.isshowmy=false;
this.isshowyou=false;
this.isshowlove=false;
this[newurl]=true;
}
},
methods:{
tab:function(key){
window.location.href="#/"+key;
this.url=key;
}
}
}
</script>
这时候我们的流程就是点击修改了地址,然后根据地址在去控制对应结构的显示。
五.路由使用,vue-router
在我们单页开发中,路由是非常重要的,就像上面的例子,我们如果有很多控制显示隐藏的处理,是非常麻烦的,
修改地址,然后显示对应的结构,就变得清晰明了。
vue-router可以帮助我们非常出色的解决问题,还是如上例子的处理,我们使用vue-router完成我们的实现,
用vue-router就要有这个依赖,我们安装vue-router有两种方式:
package.json配置好,
{
"name": "stydy-vue",
"description": "study-vue",
"version": "1.0.0",
"author": "tbd",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": {
"vue": "^2.4.4"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1",
"vue-router": "^*"
}
}
然后执行:
npm install
npm手动安装
npm install vue-router
等待完成即可!
如何终止启动的项目:ctrl+c
1.引用路由
路由的引入非常简单:
2.配置路由
然后就是简单的配置:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import myComponent from './myComponent.vue'
import youComponent from './youComponent.vue'
import loveComponent from './loveComponent.vue'
//路由配置
Vue.use(VueRouter);
var routes = [
{ path: '/', component: myComponent},
{ path: '/youComponent', component: youComponent},
{ path: '/loveComponent', component: loveComponent}
]
var router = new VueRouter({
routes: routes // (缩写)相当于 routes: routes
})
var app = new Vue({
render:h=>h(App)
}).$mount("#app")
3.注册到vue中
这时候在对应的地址下,配置了使用的对应组件,然后使用VueRouter帮助生成这个实例,然后应用到vue实例中:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import myComponent from './myComponent.vue'
import youComponent from './youComponent.vue'
import loveComponent from './loveComponent.vue'
//路由配置
Vue.use(VueRouter);
var routes = [
{ path: '/', component: myComponent},
{ path: '/youComponent', component: youComponent},
{ path: '/loveComponent', component: loveComponent}
]
var router = new VueRouter({
routes: routes // (缩写)相当于 routes: routes
})
var app = new Vue({
router,
render:h=>h(App)
}).$mount("#app")
4.使用路由
路由为我们提供了它写好的组件,我们只要直接使用即可!
<router-link to=”/isshowmy”>my-component</router-link>
最终会被解析成a标签,href就是to的设置,地址点击之后就会变为#/isshowmy的形式
<router-view></router-view>
会根据的路由配置,匹配好,然后显示对应组件。
App.js:
<template>
<div id="app">
<h3>tab切换显示:</h3>
<ul>
<li><router-link to="/">my-component</router-link></li>
<li><router-link to="/youComponent">you-component</router-link></li>
<li><router-link to="/loveComponent">love-component</router-link></li>
</ul>
<div>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
六.路由参数获取
1.?形式传参
我们修改我们的myComponent.vue,加入一个列表,然后跳到详情页面,一会我们在创建详情页的组件和配置对应路由:
myComponent.vue我们使用vue提供的v-for指令做循环处理:
<template>
<div>
{
{info}}
<ul>
<li v-for="(item, index) in list"><a v-bind:href="'#/myDetail?id='+item.id">{
{item.title}}</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'myComponent',
data:function(){
return {
info:"myComponent",
list:[
{id:1,title:"c1111111"},
{id:2,title:"c2222222222"},
{id:3,title:"c33333333"},
{id:4,title:"c4444444"},
{id:5,title:"c55555555"}
]
}
}
}
</script>
创建myDetail.vue:
<template>
<div>
我是详情页面
</div>
</template>
<script>
export default {
name: 'myDetail'
}
</script>
main.js加入路由配置:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import myComponent from './myComponent.vue'
import youComponent from './youComponent.vue'
import loveComponent from './loveComponent.vue'
import myDetail from './myDetail.vue'
//路由配置
Vue.use(VueRouter);
var routes = [
{ path: '/', component: myComponent},
{ path: '/youComponent', component: youComponent},
{ path: '/loveComponent', component: loveComponent},
{ path: '/myDetail', component: myDetail}
]
var router = new VueRouter({
routes: routes // (缩写)相当于 routes: routes
})
var app = new Vue({
router,
render:h=>h(App)
}).$mount("#app")
我们看那一下效果:
点击列表进入详情页面:
我们在new vue实例的时候使用了路由对象,
那么在任何组件中我们的this都会有一个$route属性,里面会包含所有路由相关的信息和方法处理,
我们在详情组件的生命周期函数中打印出这个属性的内容:
myDetail.vue,对于生命周期函数,就是组件渲染的阶段:
<template>
<div>
我是详情页面
</div>
</template>
<script>
export default {
name: 'myDetail',
created: function () {
console.log(this.$route)
}
}
</script>
看到打印入下:
在如见中显示这个id非常简单,在组件内获取的话就是this.$route. query .id即可!
<template>
<div>
我是详情页面id{
{this.$route.query.id}}
</div>
</template>
<script>
export default {
name: 'myDetail',
created: function () {
console.log(this.$route)
}
}
</script>
2./url/:id形式传参
这种处理,我们要在路由配置进行处理:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import myComponent from './myComponent.vue'
import youComponent from './youComponent.vue'
import loveComponent from './loveComponent.vue'
import myDetail from './myDetail.vue'
//路由配置
Vue.use(VueRouter);
var routes = [
{ path: '/', component: myComponent},
{ path: '/youComponent', component: youComponent},
{ path: '/loveComponent', component: loveComponent},
{ path: '/myDetail/:id', component: myDetail}
]
var router = new VueRouter({
routes: routes // (缩写)相当于 routes: routes
})
var app = new Vue({
router,
render:h=>h(App)
}).$mount("#app")
在传递位置,我们就可以用地址的形式了:
myComponent.vue:
<template>
<div>
{
{info}}
<ul>
<li v-for="(item, index) in list"><a v-bind:href="'#/myDetail/'+item.id">{
{item.title}}</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'myComponent',
data:function(){
return {
info:"myComponent",
list:[
{id:1,title:"c1111111"},
{id:2,title:"c2222222222"},
{id:3,title:"c33333333"},
{id:4,title:"c4444444"},
{id:5,title:"c55555555"}
]
}
}
}
</script>
在接收端,我们看console的结果:
我们只需要把query改成params即可!
myDetail.vue:
<template>
<div>
我是详情页面id{
{this.$route.params.id}}
</div>
</template>
<script>
export default {
name: 'myDetail',
created: function () {
console.log(this.$route)
}
}
</script>
七.手动跳转
我们的
会被解析成a,不过有的时候我们需要在一个事件里面去跳转,比如登录操作:
youComponent.vue:
<template>
<div>
{
{info}}
<button v-on:click="skip">登录</button>
</div>
</template>
<script>
export default {
name: 'youComponent',
data:function(){
return {
info:"youComponent"
}
},
methods:{
skip:function(){
this.$router.push("loveComponent")
}
}
}
</script>
路由除了提供$route之外,还提供了$router,这里面有对应的跳转方法,我们调用即可!
八.嵌套路由
这个其实也是非常常用的,一个简单的例子,关于我们页面,这个关于我们地址是:
#/about
他的下面还有三个页面:
联系方式#/about/phone
信息#/about/info
地址#/about/address
这样就出现了嵌套关系,在关于我们有一部分内容是公用的,同样点击对于的a会显示不同的内容,当时你是用tab切换也可以。
嵌套路由的配置和路由配置一样,不过是多一级的设置:
main.js:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import myComponent from './myComponent.vue'
import youComponent from './youComponent.vue'
import loveComponent from './loveComponent.vue'
import myDetail from './myDetail.vue'
import lovePhone from './lovePhone.vue'
import loveInfo from './loveInfo.vue'
import loveAddress from './loveAddress.vue'
//路由配置
Vue.use(VueRouter);
var routes = [
{ path: '/', component: myComponent},
{ path: '/youComponent', component: youComponent},
{ path: '/loveComponent', component: loveComponent,
children: [
{
path: 'lovePhone',
component: lovePhone
},
{
path: 'loveInfo',
component: loveInfo
},
{
path: 'loveAddress',
component: loveAddress
}
]
},
{ path: '/myDetail/:id', component: myDetail}
]
var router = new VueRouter({
routes: routes // (缩写)相当于 routes: routes
})
var app = new Vue({
router,
render:h=>h(App)
}).$mount("#app")
loveComponent.vue使用嵌套处理,router-link不用多说,重要的是这里面的<router-view></router-view>,根据配置关系,看到这个二级地址之后会找到他一级的结构,然后找到router-view去渲染:
<template>
<div>
{
{info}}
<ul>
<li><router-link to="/loveComponent/lovePhone">lovePhone</router-link></li>
<li><router-link to="/loveComponent/loveInfo">loveInfo</router-link></li>
<li><router-link to="/loveComponent/loveAddress">loveAddress</router-link></li>
</ul>
<div>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'loveComponent',
data:function(){
return {
info:"loveComponent"
}
}
}
</script>
我们一次创建这三个组件,
lovePhone.vue:
<template>
<div>
{
{info}}
</div>
</template>
<script>
export default {
name: 'lovePhone',
data:function(){
return {
info:"lovePhone"
}
}
}
</script>
loveInfo:
<template>
<div>
{
{info}}
</div>
</template>
<script>
export default {
name: 'loveInfo',
data:function(){
return {
info:"loveInfo"
}
}
}
</script>
loveAddress:
<template>
<div>
{
{info}}
</div>
</template>
<script>
export default {
name: 'loveAddress',
data:function(){
return {
info:"loveAddress"
}
}
}
</script>
九.重定向
我们进入是没有内容的,其实我们打算显示出:
我们在路由配置可以加入重定向处理:
main.js:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import myComponent from './myComponent.vue'
import youComponent from './youComponent.vue'
import loveComponent from './loveComponent.vue'
import myDetail from './myDetail.vue'
import lovePhone from './lovePhone.vue'
import loveInfo from './loveInfo.vue'
import loveAddress from './loveAddress.vue'
//路由配置
Vue.use(VueRouter);
var routes = [
{ path: '/', component: myComponent},
{ path: '/youComponent', component: youComponent},
{ path: '/loveComponent', component: loveComponent, redirect: '/loveComponent/lovePhone',
children: [
{
path: 'lovePhone',
component: lovePhone
},
{
path: 'loveInfo',
component: loveInfo
},
{
path: 'loveAddress',
component: loveAddress
}
]
},
{ path: '/myDetail/:id', component: myDetail}
]
var router = new VueRouter({
routes: routes // (缩写)相当于 routes: routes
})
var app = new Vue({
router,
render:h=>h(App)
}).$mount("#app")
十.路由变化监听函数
我们也许有这样的需求,比如用户的账户长时间未操作过期了,我们在进入目的页面会给用户返回到登录页面,路由为我们提供了这样的全局的路由变化监听函数:
main.js:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import myComponent from './myComponent.vue'
import youComponent from './youComponent.vue'
import loveComponent from './loveComponent.vue'
import myDetail from './myDetail.vue'
import lovePhone from './lovePhone.vue'
import loveInfo from './loveInfo.vue'
import loveAddress from './loveAddress.vue'
//路由配置
Vue.use(VueRouter);
var routes = [
{ path: '/', component: myComponent},
{ path: '/youComponent', component: youComponent},
{ path: '/loveComponent', component: loveComponent, redirect: '/loveComponent/lovePhone',
children: [
{
path: 'lovePhone',
component: lovePhone
},
{
path: 'loveInfo',
component: loveInfo
},
{
path: 'loveAddress',
component: loveAddress
}
]
},
{ path: '/myDetail/:id', component: myDetail}
]
var router = new VueRouter({
routes: routes // (缩写)相当于 routes: routes
})
router.beforeEach(function (to, from, next){
console.log(to,"即将要进入的目标 路由对象");
console.log(from,"当前导航正要离开的路由");
next();
})
var app = new Vue({
router,
render:h=>h(App)
}).$mount("#app")
在这个函数里我们必须执行一次next函数,不设置参数就是成功跳转到目的页面,也可以设置参数,这个参数就是要跳转的新位置。
转载于:https://my.oschina.net/tbd/blog/1553267
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/108098.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...