文章目录
路由实现组件的嵌套
举例:登录组件是账户组件的子组件
1.创建链接、路由容器
<div id="app">
<router-link to="/account">这是账户</router-link>
<router-link to="/newlist">这是新闻列表</router-link>
<router-view></router-view>
</div>
2.创建组件
const account = {
template:`<div>
<h3 class="account">
账户组件
</h3>
</div>`
}
const newlist = {
template: `<h3 class="newlist">
新闻列表组件
</h3>`
}
const login = {
template:`<h3>登录组件</h3>`
}
3.创建路由对象,写入路由规则
const router = new VueRouter({
routes:[
{path:"/account",component:account},
{path:"/newlist",component:newlist}
]
})
4.子路由链接、子路由容器加入account的组件
const account = {
template:`<div>
<h3 class="account">
账户组件
</h3>
<router-link to="/account/login">登录</router-link>
<router-view></router-view>
</div>`
}
5.把登录路由匹配规则加入account
的子规则children
const router = new VueRouter({
routes:[
{path:"/account",component:account,children:[
{path:"login",component:login}
]},
{path:"/newlist",component:newlist}
]
})
注: 子路由规则path前面不带/
命名视图
之前的路由规则, 当匹配到一个路由时,只能再页面的容器中,放置唯一一个组件
可以通过命名视图实现当前页面容器router-view
中放置多个组件
经典视图
标签代码结构
<div id="app">
<router-view name="top"></router-view>
<router-view name="left"></router-view>
<router-view name="right"></router-view>
<router-view name="bottom"></router-view>
</div>
js代码
const header = {
template:`<h1>头部</h1>`
}
const sidebar = {
template:`<h1>左侧</h1>`
}
const content={
template:`<h1>主体区域</h1>`
}
const footer={
template:`<h1>尾部</h1>`
}
const router = new VueRouter({
routes:[
{path:"/",components:{
//组件名称:组件对象
'top':header,
'left':sidebar,
'right':content,
'bottom':footer
}}
]
})
var vm = new Vue({
el:"#app",
data:{},
methods:{},
router:router
})
watch监听
1.使用watch监听数据的变化
名称案例
1)经典做法:v-model
实现双向绑定
<!DOCTYPE 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>Document</title>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
</head>
<body>
<div id="app">
firstname:
<input type="text" v-model="firstname" @change="txtchanged"> + lastname:
<input type="text" v-model="lastname" @change="txtchanged"> = fullname:
<input type="text" v-model="fullname">
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
firstname:"",
lastname:"",
fullname:""
},
methods:{
txtchanged(){
this.fullname = this.firstname+"-"+this.lastname
}
}
})
</script>
</body>
</html>
2)使用watch监听数据的变化
JS代码
var vm = new Vue({
el:"#app",
data:{
firstname:"",
lastname:"",
fullname:""
}.
watch:{
"firstname":{
//deep:true, //深度监测,多级属性
//immediate:true, //初始化时就调用handler
handler(newvalue,oldvalue){
this.fullname = newvalue + "-" + this.lastname
}
},
"lastname":{
//deep:true, //深度监测,多级属性
//immediate:true, //初始化时就调用handler
handler(newvalue,oldvalue){
this.fullname = this.firstname + "-" + newvalue
}
},
}
})
注: 当不使用deep
和immediate
时,可以使用如下简写方式
var vm = new Vue({
el:"#app",
data:{
firstname:"",
lastname:"",
fullname:""
},
watch:{//表示监听指定数据的改变
//"键是要监听的数据":数据变化时的处理函数
"firstname":function(newval,oldval){//新值,旧值
this.fullname = newval + "-" + this.lastname
},
"lastname":function(newval,oldval){
this.fullname = this.firstname + "-" + newval
}
}
})
2.使用watch监听url地址的改变
注: 可以监听当前vm实例上的所有属性变化
要求:登录注册组件,当组件切换时出现一句话 欢迎进入登录/注册页面
<!DOCTYPE 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>Document</title>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
</head>
<body>
<div id="app">
<router-link to="/login">登录</router-link>
<router-link to="/reg">注册</router-link>
{{msg}}
<router-view></router-view>
</div>
<script>
const login = {
template:"<h3>登录组件</h3>"
}
const reg = {
template:"<h3>注册组件</h3>"
}
const router = new VueRouter({
routes:[
{path:"/login",component:login},
{path:"/reg",component:reg}
]
})
var vm = new Vue({
el:"#app",
data:{
msg:"欢迎"
},
methods:{},
router:router,
created(){//在页面刚被打开时会执行,页面刷新时执行
if(this.$route.path === "/login"){
this.msg = "欢迎进入登录页面"
}else if(this.$route.path === "/reg"){
this.msg = "欢迎进入注册页面"
}
},
watch:{
"$route.path":function(newval){//newval 是当前页面的地址/login /reg
if(newval === "/login"){
this.msg = "欢迎进入登录页面"
}
if(newval === "/reg"){
this.msg = "欢迎进入注册页面"
}
}
}
})
</script>
</body>
</html>
watch适合监听单个的、虚拟的数据,做对应操作
computed计算属性
名称案例
<!DOCTYPE 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>Document</title>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
</head>
<body>
<div id="app">
firstname:
<input type="text" v-model="firstname"> + lastname:
<input type="text" v-model="lastname"> = fullname:
<input type="text" v-model="fullname">
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
firstname:"",
lastname:"",
},
methods:{},
computed:{
"fullname":function(){ //fullname就是计算属性,在使用时当作普通属性
//只要计算属性的function中所依赖的任何数据发生变化,则会触发计算属性的重新求值
return this.firstname+"-"+this.lastname
}
}
})
</script>
</body>
</html>
注: 计算属性的值,如果被第一次计算后,没有发生过变化,则会把第一次的值缓存起来,供后续使用,能够提高性能
上述方法为简写(前提为不改变值即不调用set
函数时可使用),相当于下述中get
方法
下述为完整写法
计算属性的get和set
computed:{
"fullname":{
get(){ //上例相当于get
return this.firstname + "-" +this.lastname
},
set(val){
const parts = val.split("-")
this.firstname = parts[0] || ""
this.lastname = parts[1] || ""
}
}
}
get表示外界要引用fullname
的值
set表示外界重新为fullname
赋值,val
为fullname
内的值
watch、computed和methods之间的对比
computed
属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算,主要当作属性来使用;methods
方法表示一个具体的操作,主要书写业务逻辑;watch
一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computed
和methods的结合体;computed
能完成的功能,watch
也能完成
watch
能完成的功能,computed
不一定能完成,watch可以进行异步操作
小原则:1.所被vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象
2.所有不被vue管理的函数(定时器的回调函数,ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象