- 定义vue组件
什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可。
组件化和模块化的不同:
- 模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
- 组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用
-
1.1 全局组件定义的四种方式
1.使用 Vue.extend 配合 Vue.component 方法:
var login = Vue.extend({
template: '<h1>登录</h1>'
});
Vue.component('login', login);2.直接使用 Vue.component 方法:
Vue.component('register', {
template: '<h1>注册</h1>'
});3.将模板字符串,定义到script标签中:
<script id="tmpl" type="x-template">
<div><a href="#">登录</a> | <a href="#">注册</a></div>
</script>同时,需要使用 Vue.component 来定义组件:
Vue.component('account', {
template: '#tmpl'
});4.将模板字符串,定义到template标签中:
< template id="tmpl">
<div><a href="#">登录</a> | <a href="#">注册</a></div>
</ template >同时,需要使用 Vue.component 来定义组件:
Vue.component('account', {
template: '#tmpl'
});注意:组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!
1.2 组件中展示数据和响应事件
在组件中,data需要被定义为一个方法,例如:
Vue.component('account', {
template: '#tmpl',
data() {
return {
msg: '大家好!'
}
},
methods:{
login(){
alert('点击了登录按钮');
}
}
});
在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的data属性中的值,需要使用this来访问;
【重点】为什么组件中的data属性必须定义为一个方法并返回一个对象
示例:
<!DOCTYPE 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>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<counter></counter>
<hr>
<counter></counter>
<hr>
<counter></counter>
</div>
<template id="tmpl">
<div>
<input type="button" value="+1" @click="increment">
<h3>{{count}}</h3>
</div>
</template>
<script>
var dataObj = { count: 0 }
// 这是一个计数器的组件, 身上有个按钮,每当点击按钮,让 data 中的 count 值 +1
Vue.component('counter', {
template: '#tmpl',
data: function () {
// return dataObj
return { count: 0 }
},
methods: {
increment() {
this.count++
}
}
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
</body>
</html>
1.3 使用components属性定义局部子组件
组件实例定义方式:
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {},
components: { // 定义子组件
account: { // account 组件
template: '<div><h1>这是Account组件{{name}}</h1><login></login></div>', // 在这里使用定义的子组件
components: { // 定义子组件的子组件
login: { // login 组件
template: "<h3>这是登录组件</h3>"
}
}
}
}
});
</script>
引用组件:
<div id="app">
<account></account>
</div>
使用flag标识符结合v-if和v-else切换组件
页面结构:
<div id="app">
<input type="button" value="toggle" @click="flag=!flag">
<my-com1 v-if="flag"></my-com1>
<my-com2 v-else="flag"></my-com2>
</div>
Vue实例定义:
<script>
Vue.component('myCom1', {
template: '<h3>奔波霸</h3>'
})
Vue.component('myCom2', {
template: '<h3>霸波奔</h3>'
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
flag: true
},
methods: {}
});
</script>
1.4 使用:is属性来切换不同的子组件,并添加切换动画
组件实例定义方式:
// 登录组件
const login = Vue.extend({
template: `<div>
<h3>登录组件</h3>
</div>`
});
Vue.component('login', login);
// 注册组件
const register = Vue.extend({
template: `<div>
<h3>注册组件</h3>
</div>`
});
Vue.component('register', register);
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: { comName: 'login' },
methods: {}
});
使用component标签,来引用组件,并通过:is属性来指定要加载的组件:
<div id="app">
<a href="#" @click.prevent="comName='login'">登录</a>
<a href="#" @click.prevent="comName='register'">注册</a>
<hr>
<transition mode="out-in">
<component :is="comName"></component>
</transition>
</div>
添加切换样式:
<style>
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(30px);
}
.v-enter-active,
.v-leave-active {
position: absolute;
transition: all 0.3s ease;
}
h3{
margin: 0;
}
</style>
1.5 父组件传值子组件
- 接受父组件传值
设置props属性就可以接受父组件传值
示例:
// html部分
<son :parent-msg='msg' :list='list'></son>
<template id='myComTemp'>
<div>
<button @click='changeMsg'>修改parentMsg</button>
<h1>你好{{parentMsg}}</h1>
<ul>
<li v-for='item in list'>{{item.name}}</li>
</ul>
</div>
</template>
// 组件定义部分
var vm = new Vue({
el: '#app',
components: {
son: {
template: '#myComTemp',
// 定义父组件传过来的值
props: ['parentMsg', 'list']
}
}
})
- 设置传递类型
props: {
// 规定了父组件只能传对象类型
prop1:Object
// 可以设置多个类型,可以传Number也可以传String
parentMsg: [Number, String],
list: {
// 设置类型
type: Array,// [Array,String]
// 设置默认值的时候必须使用函数,原理和data必须使用函数是一样的
default: function () {
return [{
name: '这个一个默认的名字'
}]
}
},
}
- 属性的继承和传递
属性继承的特征:
父组件的属性会覆盖子组件的属性
class 和 style 会进行合并,不会覆盖
设置禁用继承
加在子组件上的属性,使用了这个属性之后会阻止组件继承父组件的属性,但是class和style除外
inheritAttrs: false
在组件内可以使用$attrs获取父组件传过来的属性
示例:
<!DOCTYPE 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>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.parent-class {
background-color: bisque;
color: red
}
.son-class {
color: aquamarine
}
</style>
</head>
<body>
<div id='app'>
<!-- 如果想传递一个非字符串类型,必须用数据绑定的方式 -->
<!--
属性继承的特征:
父组件的属性会覆盖子组件的属性
class 和 style 会进行合并,不会覆盖
-->
<!-- 通过这种方式就可以为子组件设置一些属性 -->
<son :parent-msg='msg' required class="parent-class" name='fuzujian'></son>
</div>
<template id='myComTemp'>
<div name='zizujian' class='son-class'>
<button @click='changeMsg'>修改parentMsg</button>
<input type="text" :name='$attrs.name' >
<h1>你好{{parentMsg}}</h1>
<ul>
<li v-for='item in list'>{{item.name}}</li>
</ul>
</div>
</template>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '这个父组件的数据',
list: [{
name: '张三'
},
{
name: '李四'
},
{
name: '王五'
},
]
},
components: {
son: {
template: '#myComTemp',
// 使用了这个属性之后会阻止组件继承父组件的属性,但是class和style除外
inheritAttrs: false,
data() {
return {
sonMsg: '你好'
}
},
methods: {
changeMsg() {
console.log(this.$attr)
console.log(this.parentMsg);
}
},
props: {
// 可以设置多个类型
parentMsg: [Number, String],
list: {
type: Array,
// 设置默认值的时候必须使用函数,原理和data必须使用函数是一样的
default: function () {
return [{
name: '这个一个默认的名字'
}]
}
},
}
}
}
})
</script>
</body>
</html>
- 注意事项
data和props的区别
data是组件私有的,props是父组件传过来的
data是可以修改的,props是只读的
1.6 子组件传值父组件
子组件调用父组件的方法
- 在父组件中给引用的子组件注册一个事件(这个事件的名字是自定义的)
- 子组件可以触发这个事件$emit('事件名字')
子组件给父组件传递数据
- $emit方法第二个参数可以定义子组件给父组件传递的内容
- 在父组件中怎么拿到这内容
2.1 父组件这个方法没有自定参数,在父组件的方法直接加这个参数就可以拿到
2.2 父组件有自定义参数,可以传入$event也可以拿到子组件传递的数据。通过$event只能传递第一个参数。
示例:
<!DOCTYPE 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>组件自定义事件</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<!-- 1.给组件添加事件 -->
<div id="app">
<son v-on:click-son='clickParent($event,"自定义参数")' v-on:click-son2='clickParent2'></son>
</div>
<template id='sonTemp'>
<div>
<button @click='clickSon'>点击事件</button>
<button @click='clickSon2'>点击事件2</button>
<h3>这是子组件的内容</h3>
</div>
</template>
<script>
var son = {
template: '#sonTemp',
methods: {
clickSon() {
console.log('子组件的方法');
// 2. 在子组件中触发这个事件
// 发射,触发
// 通过这种方式,子组件也可以给父组件传值
this.$emit('click-son', {
name: '张三'
})
},
clickSon2(){
console.log('子组件的方法2');
this.$emit('click-son2', 'nihao')
}
},
}
var vm = new Vue({
el: '#app',
data: {},
methods: {
// e是接受子组件传过来的参数,msg是这个方法自己参数
clickParent(e, msg) {
console.log(e);
console.log('父组件的方法,数据为:' + msg);
},
clickParent2(e) {
console.log(e);
}
},
components: {
son
}
})
</script>
</body>
</html>
1.8 ref的使用
- 获取dom节点
- 给dom节点记上ref属性,可以理解为给dom节点起了个名字。
- 加上ref之后,在$refs属性中多了这个元素的引用。
- 通过vue实例的$refs属性拿到这个dom元素。
- 获取组件
- 给组件记上ref属性,可以理解为给组件起了个名字。
- 加上ref之后,在$refs属性中多了这个组件的引用。
- 通过vue实例的$refs属性拿到这个组件的引用,之后可以通过这个引用调用子组件的方法,或者获取子组件的数据。
示例:
<!DOCTYPE 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>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<input type="button" value="获取元素" @click="getElement" ref="mybtn">
<h3 id="myh3" ref="myh3">哈哈哈, 今天天气太好了!!!</h3>
<hr>
<login ref="mylogin"></login>
</div>
<script>
var login = {
template: '<h1>登录组件</h1>',
data() {
return {
msg: 'son msg'
}
},
methods: {
show() {
console.log('调用了子组件的方法')
}
}
}
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {
getElement() {
// console.log(document.getElementById('myh3').innerText)
// console.log(this.$refs.myh3.innerText)
// console.log(this.$refs.mylogin.msg)
// this.$refs.mylogin.show()
}
},
components: {
login
}
});
</script>
</body>
</html>
2. Vue中路由的使用
2.1 什么是路由
- 后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源
- 前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;
- 在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由)
2.2 如何使用路由
- 路由的安装
直接引用官网提供的cdn
路由的基本使用
- 引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)
- 创建路由new VueRouter(),接受的参数是一个对象
- 在实例化的对象里配置属性routes:[],这个数组里的对象包含path属性和component属性
- path属性是url的地址,component属性就是显示的组件(传组件的对象)
- 创建的路由需要和vue实例关联一下
- 路由到的组件显示在哪个位置<router-view></router-view>
示例:
<body>
<div id="app">
<!-- 通过路由切换的组件会被放在这里 -->
<router-view></router-view>
</div>
<script>
const login = {
template: '<h2>登录</h2>'
}
// 这里实例化了一个路由
const router = new VueRouter({
routes: [{
path: '/login',
//这里需要注意的是我们直接组件的对象放在这里
component: login
}]
});
var vm = new Vue({
el: '#app',
// 把路由挂在到实例上
router: router
})
</script>
</body>
路由的跳转
- router-link标签可以设置to属性
- 默认是a标签,可以通过tag设置包裹标签
示例:
<router-link to='/login'>登录</router-link>
<router-link to='/registry'>注册</router-link>
路由重定向
redirect可以进行路由的重定向
选中路由高亮
- 使用默认的样式
直接设置router-link-active
- 自定义样式
配置 linkActiveClass:'自定义的类名'
定义参数
通过query的方式在url后加?参数名=参数的值
获取参数:$route.query.参数名
示例:
<!DOCTYPE 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>路由传递参数</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入这个路由组件之后提供了一个VueRouter的构造方法 -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<style>
.router-link-active {
background-color: aquamarine;
font-size: 20px;
}
.my-active {
background-color: aquamarine;
font-size: 20px;
}
</style>
</head>
<body>
<div id="app">
<!-- 通过路由切换的组件会被放在这里 -->
<!-- <a href="#/login">登录</a> -->
<!-- <a href="#/registry">注册</a> -->
<!-- 通过router-link 进行路由的跳转 -->
<!-- 通过tag可以指定router-link渲染的界面元素 -->
<!-- <router-link to='/login' tag='div'>登录</router-link> -->
<router-link to='/login?id=123&name=张三'>登录</router-link>
<router-link to='/registry'>注册</router-link>
<router-link to='/detail?id=999'>某一篇新闻</router-link>
<router-view></router-view>
</div>
<script>
// 实现简单路由功能的步骤
// 1. 引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)
// 2. 创建路由new VueRouter(),接受的参数是一个对象
// 3. 在实例化的对象里配置属性 routes :[],这个数组里的对象包含path属性和component属性
// 4. path属性是url的地址,component属性就是显示的组件(传组件的对象)
// 5. 创建的路由需要和vue实例关联一下
// 6. 路由到的组件显示在哪个位置<router-view></router-view>
const login = {
template: '<h2>登录,父组件传递过来的id{{$route.query.id}},name:{{$route.query.name}}</h2>'
}
const registry = {
template: '<h2>注册</h2>'
}
const newsDetail = {
template: '<h2>文章的详情</h2>',
created() {
console.log(this.$route.query.id);
// 根据这个id去请求后台数据,获取完整的新闻内容,之后进行展示
},
}
// 这里实例化了一个路由
const router = new VueRouter({
linkActiveClass: 'my-active',
routes: [{
path: '/',
// 通过这种方式,在访问/路径的时候会重定向到/login路径
redirect: '/login'
}, {
path: '/login',
//这里需要注意的是我们直接组件的对象放在这里
component: login
}, {
path: '/registry',
component: registry
}, {
path: '/detail',
component: newsDetail
}]
});
var vm = new Vue({
el: '#app',
// 把路由挂在到实例上
router: router
})
</script>
</body>
</html>
使用浏览器参数的方式传递参数
- 设置路由的时候/路由地址/:参数名
- 获取参数$route.params.参数名
示例:
<body>
<div id="app">
<!-- 通过路由切换的组件会被放在这里 -->
<!-- <a href="#/login">登录</a> -->
<!-- <a href="#/registry">注册</a> -->
<!-- 通过router-link 进行路由的跳转 -->
<!-- 通过tag可以指定router-link渲染的界面元素 -->
<!-- <router-link to='/login' tag='div'>登录</router-link> -->
<router-link to='/login?id=123&name=张三'>登录</router-link>
<router-link to='/registry'>注册</router-link>
<router-link to='/detail/1000'>某一篇新闻</router-link>
<router-view></router-view>
</div>
<script>
// 实现简单路由功能的步骤
// 1. 引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)
// 2. 创建路由new VueRouter(),接受的参数是一个对象
// 3. 在实例化的对象里配置属性 routes :[],这个数组里的对象包含path属性和component属性
// 4. path属性是url的地址,component属性就是显示的组件(传组件的对象)
// 5. 创建的路由需要和vue实例关联一下
// 6. 路由到的组件显示在哪个位置<router-view></router-view>
const login = {
template: '<h2>登录,父组件传递过来的id{{$route.query.id}},name:{{$route.query.name}}</h2>'
}
const registry = {
template: '<h2>注册</h2>'
}
const newsDetail = {
template: '<h2>文章的详情</h2>',
created() {
console.log(this.$route.params.id);
// 根据这个id去请求后台数据,获取完整的新闻内容,之后进行展示
},
}
// 这里实例化了一个路由
const router = new VueRouter({
linkActiveClass: 'my-active',
routes: [{
path: '/',
// 通过这种方式,在访问/路径的时候会重定向到/login路径
redirect: '/login'
}, {
path: '/login',
//这里需要注意的是我们直接组件的对象放在这里
component: login
}, {
path: '/registry',
component: registry
}, {
path: '/detail/:id/:name',
component: newsDetail
}]
});
var vm = new Vue({
el: '#app',
// 把路由挂在到实例上
router: router
})
</script>
</body>
组件的嵌套
- 声明路由的时候设置children,这是children是一个数组,数组里是路由对象
- 这个children的组件就会渲染在它父组件的<router-view>中
示例:
<body>
<!-- 通过这个路由的嵌套,我们可以实现一些布局 -->
<div id="app">
<router-view></router-view>
</div>
<template id="parentCompTemp">
<div>
<h1>登录注册页面</h1>
<router-link to='/parent/login'>登录</router-link>
<router-link to='/parent/registry'>注册</router-link>
<router-view></router-view>
</div>
</template>
<script>
const parentComp = {
template: '#parentCompTemp'
}
const login = {
template: '<h2>登录</h2>'
}
const registry = {
template: '<h2>注册</h2>'
}
const newsDetail = {
template: '<h2>文章的详情</h2>',
created() {
console.log(this.$route.query.id);
// 根据这个id去请求后台数据,获取完整的新闻内容,之后进行展示
},
}
// 这里实例化了一个路由
const router = new VueRouter({
linkActiveClass: 'my-active',
routes: [{
path: '/',
// 通过这种方式,在访问/路径的时候会重定向到/login路径
redirect: '/parent'
}, {
path: '/parent',
component: parentComp,
// 涉及到了子路由的内容
children: [{
// 这就是用相对路径,相对于父组件的,这个实际路径就是/parent/login
path: 'login',
component: login
}, {
// 这就是用相对路径,相对于父组件的,这个实际路径就是/parent/login
path: 'registry',
component: registry
},
]
}]
});
var vm = new Vue({
el: '#app',
// 把路由挂在到实例上
router: router
})
</script>
</body>
命名视图
- 我们之前只能一个地址对应一个组件,现在可以一个地址对应多个组件
- components属性设置的
- 给router-view设置名字,这个名字和components组件名字是对应的
- 设置默认值default对应组件可以设置名字也可以访问
示例:
<!DOCTYPE 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>命名视图</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入这个路由组件之后提供了一个VueRouter的构造方法 -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<style>
.router-link-active {
background-color: aquamarine;
font-size: 20px;
}
.my-active {
background-color: aquamarine;
font-size: 20px;
}
.header {
width: 100%;
height: 80px;
background-color: red;
}
.my-container {
height: calc(100vh - 80px);
}
.sidebar {
height: 100%;
float: left;
width: 200px;
background-color: gray;
}
.main {
height: 100%;
margin-left: 200px;
background-color: khaki;
}
body {
margin: 0
}
</style>
</head>
<body>
<!-- 通过这个路由的嵌套,我们可以实现一些布局 -->
<div id="app">
<!-- router-view可以设置名字,指定渲染的组件 -->
<router-view></router-view>
<div class='my-container'>
<router-view name='sidebar'></router-view>
<router-view name='main'></router-view>
</div>
</div>
<script>
// 头部
const header = {
template: '<div class="header">头部内容</div>'
}
// 侧边栏
const sidebar = {
template: '<div class="sidebar">侧边栏</div>'
}
// 主体
const main = {
template: '<div class="main"> <router-view></router-view>内容</div>'
}
const test={
template: '<div >测试</div>'
}
// 这里实例化了一个路由
const router = new VueRouter({
linkActiveClass: 'my-active',
routes: [{
path: '/',
// 使用compones可以定义多个组件
components: {
// 通过default属性可以设置默认的组件,默认组件只有一个,不写名字也可以渲染
default: header,
sidebar: sidebar,
main
},
children:[
{path:'/test',component:test}
]
}]
});
var vm = new Vue({
el: '#app',
// 把路由挂在到实例上
router: router
})
</script>
</body>
</html>
3. 计算属性和监听器
名称案例
- 获取完整的名字,需要把姓和名字拼接在一起
- 什么时候去拼接在一起(input值改变的时候)
- 监听keyup知道input什么时候改变了,在这里就可以获取完整的名字
3.1 Method实现
3.2 Watch用法
监听data中属性的改变:
<div id="app">
<input type="text" v-model="firstName"> +
<input type="text" v-model="lastName"> =
<span>{{fullName}}</span>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
firstName: 'jack',
lastName: 'chen',
fullName: 'jack - chen'
},
methods: {},
watch: {
'firstName': function (newVal, oldVal) { // 第一个参数是新数据,第二个参数是旧数据
this.fullName = newVal + ' - ' + this.lastName;
},
'lastName': function (newVal, oldVal) {
this.fullName = this.firstName + ' - ' + newVal;
}
}
});
</script>
监听路由对象的改变:
<div id="app">
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
<router-view></router-view>
</div>
<script>
var login = Vue.extend({
template: '<h1>登录组件</h1>'
});
var register = Vue.extend({
template: '<h1>注册组件</h1>'
});
var router = new VueRouter({
routes: [
{ path: "/login", component: login },
{ path: "/register", component: register }
]
});
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {},
router: router,
watch: {
'$route': function (newVal, oldVal) {
if (newVal.path === '/login') {
console.log('这是登录组件');
}
}
}
});
</script>
3.3 Computed用法
默认只有getter的计算属性:
<div id="app">
<input type="text" v-model="firstName"> +
<input type="text" v-model="lastName"> =
<span>{{fullName}}</span>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
firstName: 'jack',
lastName: 'chen'
},
methods: {},
computed: { // 计算属性; 特点:当计算属性中所以来的任何一个 data 属性改变之后,都会重新触发 本计算属性 的重新计算,从而更新 fullName 的值
fullName() {
return this.firstName + ' - ' + this.lastName;
}
}
});
</script>
定义有getter和setter的计算属性:
<div id="app">
<input type="text" v-model="firstName">
<input type="text" v-model="lastName">
<!-- 点击按钮重新为 计算属性 fullName 赋值 -->
<input type="button" value="修改fullName" @click="changeName">
<span>{{fullName}}</span>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
firstName: 'jack',
lastName: 'chen'
},
methods: {
changeName() {
this.fullName = 'TOM - chen2';
}
},
computed: {
fullName: {
get: function () {
return this.firstName + ' - ' + this.lastName;
},
set: function (newVal) {
var parts = newVal.split(' - ');
this.firstName = parts[0];
this.lastName = parts[1];
}
}
}
});
</script>
3.4 method、computed和watch的区别
- computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用,使用的时候不加();
- methods方法表示一个具体的操作,主要书写业务逻辑;
- watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computed和methods的结合体
拓展:nrm的安装使用
作用:提供了一些最常用的NPM包镜像地址,能够让我们快速的切换安装包时候的服务器地址; 什么是镜像:原来包刚一开始是只存在于国外的NPM服务器,但是由于网络原因,经常访问不到,这时候,我们可以在国内,创建一个和官网完全一样的NPM服务器,只不过,数据都是从人家那里拿过来的,除此之外,使用方式完全一样;
如何使用
- 运行npm i nrm -g全局安装nrm包;
- 使用nrm ls查看当前所有可用的镜像源地址以及当前所使用的镜像源地址;
- 使用nrm use npm或nrm use taobao切换不同的镜像源地址;