目录
3.2、双向数据绑定、Vue事件介绍 以及Vue中的ref获取dom节点
3.3、定义方法 执行方法 获取数据 改变数据 执行方法传值 以及事件对象
1、安装
npm install --global vue-cli / cnpm install --global vue-cli
2、创建vue工程
- 完整:
vue init webpack vue-demo01
cd vue-demo01
cnpm install / npm install 如果创建项目的时候没有报错,这一步可以省略。如果报错了 cd到项目里面运行 cnpm install / npm install
npm run dev
- 简化:
vue init webpack-simple vuedemo02
cd vuedemo02
cnpm install / npm install
npm run dev
3、入门
3.1、数据绑定
<template>
<div id="app">
<h2>{{msg}}</h2>
<hr>
<!-- 绑定属性 -->
<div v-bind:title="title">我是绑定属性的例子</div>
<div :title="title">我是绑定属性,不写v-bind,直接写:title的例子</div>
<hr>
<!-- 绑定html -->
<div v-html="h2"></div>
<hr>
<!-- 绑定数据 -->
<h2>{{data1}}</h2>
<h2 v-text="data2"></h2>
<hr>
<!-- 绑定class -->
<ul>
<li v-for="(item,key) in list" :key="key">{{item}}</li>
</ul>
<!-- 绑定class,让第一个变成红色,第三个变成蓝色 -->
<div :class="{'red':flag}">我是简单的绑定class的例子</div>
<div :class="{'red':!flag}">我是简单的绑定class的另外一个例子</div>
<ul>
<li v-for="(item, key) in list" :class="{'red':key==0,'blue':key==2}" :key="key">{{item}}</li>
</ul>
<hr>
<!-- 绑定style -->
<div class="box" :style="{width:boxWidth+'px',height:boxHeight+'px'}">我是绑定style的例子</div>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
msg: '你好vue',
title: "我是title",
h2: "<h2>我是绑定html的例子</h2>",
data1: "我是绑定数据一种方式的例子" ,
data2: "我是绑定数据另一种方式的例子",
list: [111,222,333],
flag: true,
boxWidth: 300,
boxHeight: 300
}
}
}
</script>
<style>
.red {
color:red;
}
.blue {
color:blue;
}
.box {
height:100px;
width:100px;
background-color: red;
}
</style>
3.2、双向数据绑定、Vue事件介绍 以及Vue中的ref获取dom节点
<template>
<div id="app">
<h2>{{msg}}</h2>
<!-- 这里需要定义成v-model才能是一个model,而上面的展示则是一个view -->
<label>这里改变input的值就是model改变,此时会影响上面的视图view</label><br/>
<input type="text" v-model="msg"/><br/>
<!-- 绑定事件 -->
<button v-on:click="getMsg()">获取表单里面的数据</button><br/>
<button v-on:click="setMsg()">设置表单里面的数据</button>
<hr>
<!-- 通过ref获取dom对象,ref有点类似id和name -->
<input type="text" ref="userinfo" /><br/>
<button v-on:click="getInputVal()">获取input的值</button>
<hr>
<!-- 通过ref获取dom之后设置背景颜色 -->
<div ref="box">我是要把背景颜色设置成红色</div>
<button v-on:click="setBackground()">设置背景色为红色</button >
</div>
</template>
<script>
/*
MVVM:双向数据绑定:vue就是一个MVVM框架
M model
V view
MVVM:model改变会影响视图view,view改变反过来影响model
双向数据绑定必须在表单里面使用。
*/
export default {
name: 'app',
data () {
return {
msg: '你好vue'
}
}, methods:{ // 方法定义在methods里面
getMsg() {
// 获取data里面数据的方式
alert(this.msg);
},
setMsg() {
// 设置data里面数据的方式
this.msg = '我是设置表单的数据'
},
getInputVal() {
// 这是通过dom中的ref获取到对应dom结构的方式,注意$refs:this.$refs.userinfo,而.value则是dom获取值的方式,
alert(this.$refs.userinfo.value)
},
setBackground() {
this.$refs.box.style.background = 'red'
}
}
}
</script>
3.3、定义方法 执行方法 获取数据 改变数据 执行方法传值 以及事件对象
<template>
<div id="app">
<h2>{{msg}}</h2>
<!-- 绑定事件的两个方式 -->
<button v-on:click="getMsg()">我是第一种绑定事件的方式</button>
<br />
<button @click="getMsg()">我是第二种绑定事件的方式</button>
<hr>
<!-- 设置data里面的数据 -->
{{msg}} <br />
<button @click="setMsg()">改变data里面的值msg</button>
<hr>
<!-- 设置一个列表 -->
<button @click="requestData()">获取请求的数据设置一个列表</button>
<ul>
<li v-for="(item, key) in list" :key="key">
{{key}}---{{item}}
</li>
</ul>
<hr>
<!-- 执行方法传值 -->
<button @click="deleteMsg('111')">执行方法传值</button>
<hr>
<!-- 获取事件对象和自定义属性 -->
<button data-aid="111" @click="eventFn($event)">获取事件对象和自定义属性</button>
<hr>
</div>
</template>
<script>
/*
MVVM:双向数据绑定:vue就是一个MVVM框架
M model
V view
MVVM:model改变会影响视图view,view改变反过来影响model
双向数据绑定必须在表单里面使用。
*/
export default {
name: 'app',
data () {
return {
msg: '你好vue',
list: []
}
}, methods:{ // 方法定义在methods里面
getMsg: function() {
alert(this.msg)
},
setMsg() {
this.msg = '我是改变后的msg的值'
},
requestData() {
for (var i = 0; i < 10; i++) {
this.list.push('我是第' + i + '条数据')
}
},
deleteMsg(val) {
alert(val)
},
eventFn(e) {
// 获取事件dom对象
e.srcElement.style.background = 'red'
alert(e.srcElement.dataset.aid)
}
}
}
</script>
3.4、组件的引入、挂载、使用
<template>
<div id="app">
<h2>这是一个根组件</h2>
<v-home></v-home>
<hr>
<v-news></v-news>
</div>
</template>
<script>
/**
*
* 1、引入组件:import
*
* 2、挂载组件:components中挂载
*
* 3、使用组件:<v-home></v-home>
*
*
* 生命周期函数(生命周期钩子):
* 组件挂载以及组件更新组件销毁的时候触发一列的方法,这些方法就叫做生命周期函数
*/
import Home from './components/Home.vue'
import News from './components/News.vue'
export default {
name: 'app',
data () {
return {
todo: '',
list: []
}
},
components: { /**前面的组件名称不能和html标签一样 */
'v-home': Home,
'v-news': News
}
}
</script>
<style>
</style>
3.5、生命周期函数
<template>
<div id="life">
生命周期函数的演示 --- {{msg}}
<br>
<button @click="setMsg()">执行方法改变msg</button>
</div>
</template>
<script>
/**
*
* 1、引入组件:import
*
* 2、挂载组件:components中挂载
*
* 3、使用组件:<v-home></v-home>
*
*
* 生命周期函数(生命周期钩子):
* 组件挂载以及组件更新组件销毁的时候触发一列的方法,这些方法就叫做生命周期函数
*/
export default {
data() {
return {
msg : 'msg'
}
},
methods: {
setMsg() {
this.msg = '我是改变后的数据'
}
},
beforeCreate() {
console.log('实例刚刚被创建1')
},
created() {
console.log('实例已经创建完成2')
},
beforeMount() {
console.log('模板编译之前3')
},
mounted() { /** 请求数据、操作dom放在这个里面 */
console.log('模板编译完成4')
},
beforeUpdate() {
console.log('数据更新之前')
},
updated() {
console.log('数据更新完毕')
},
beforeDestroy() { /** 页面销毁的时候要保存一些数据,就可以监听这个销毁的生命周期函数 */
console.log('实例销毁之前')
},
destroyed() {
console.log('实例销毁之后')
}
}
</script>
3.6、请求数据模板axio、fetch-jsonp
// main.js文件
import Vue from 'vue'
import App from './App.vue'
/** 使用vue-resource请求数据的步骤:
*
* 1、需要安装vue-resource模块,注意加上--save
* npm install vue-resource --save
*
* 2、main.js引入 vue-resource
* import VueRrsource from 'vue-resource'
*
* 3、Vue.use(VueResource);
*
* 4、在组件里面直接使用
* this.$http.get(地址).then(response => {
*
* }, response => {
*
* });
*
*/
import VueResource from 'vue-resource'
Vue.use(VueResource);
new Vue({
el: '#app',
render: h => h(App)
})
// App.vue文件
<template>
<div id="app">
<button @click="getData()">请求数据vue-resouce方式</button>
<hr>
<ul>
<li v-for="item in list">
{{item.title}}
</li>
</ul>
</div>
</template>
<script>
/**
*
* 请求数据的模板:
*
* vue-resource 官方提供的vue的一个插件
*
* axios
*
* fetch-jsonp
*
*
*/
export default {
name: 'app',
data () {
return {
list: []
}
},
methods: {
getData() {
let api = 'http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1';
this.$http.get(api).then(response => {
console.log(response);
this.list = response.body.result;
}, err => {
console.log(err);
})
}
},
mounted() {
this.getData();
}
}
</script>
<style>
</style>
// axios和fetch-jsonp类似
<script>
/**
*
* 请求数据的模板:
*
* 2、axios/fetch-jsonp
* npm install axios --save
* / npm install fetch-jsonp
*
* 在.vue里面引入
*
*/
import Axios from 'axios'
// import FecthJsonp from 'fetch-jsonp'
export default {
name: 'app',
data () {
return {
list: []
}
},
methods: {
getData() {
let api = 'http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1';
Axios.get(api).then(response => {
this.list = response.data.result;
}).catch(err => {
console.log(err);
})
// FecthJsonp.get(api).then(response => {
// this.list = response.data.result;
// }).catch(err => {
// console.log(err);
// })
}
},
mounted() {
this.getData();
}
}
</script>
3.7、父子组件传值(父组件给子组件传值:验证方式)
// 父组件:Home.vue
<template>
<div>
<v-header ref="header" :title="title" :msg="msg" :run="run" :home="this"></v-header>
<hr>
这是一个首页组件
<button @click="getChildData()">获取子组件的数据和方法</button>
</div>
</template>
<script>
/**
*
* 父组件给子父组件传值、方法、当前home对象:
* 1、父组件调用子组件的时候,绑定动态属性
* <v-header :title="title" :msg="msg" :run="run" :home="this"></v-header>
* 2、在子组件里面通过props接收父组件传过去的数据
*
*/
/**
*
* 父组件主动获取子组件的数据和方法:
* 1、在子组件中定义ref
* <v-header ref="header"></v-header>
* 2、this.$refs.header.数据
* this.$refs.header.方法
*
* 子组件主动获取父组件的数据和方法:
* this.$parent.数据
* this.$parent.方法
*/
import Header from './Header.vue'
export default {
data() {
return {
msg: '我是一个home组件',
title: '首页111'
}
},
components: {
'v-header': Header
},
methods: {
run(val) {
alert('我是父组件的run方法' + val);
},
getChildData() {
alert(this.$refs.header.childmsg);
this.$refs.header.run();
}
}
}
</script>
// 子组件:Header.vue
<template>
<div>
<h2>这是一个头部组件 ---- {{title}} ----- {{msg}}</h2>
<button @click="run(123)">执行父组件的run方法</button>
<br/>
<button @click="getParent()">获取父组件的数据和方法</button>
<br/>
<button @click="getParentData()">获取父组件的数据和方法</button>
</div>
</template>
<script>
export default {
data() {
return {
childmsg: '我是子组件的msg'
}
},
methods: {
getParent() {
console.log(this.title);
// => console.log(this.home.title);
this.run();
// => this.home.run();
},
run() {
alert('我是子组件的run方法');
},
getParentData() {
alert(this.$parent.msg);
this.$parent.run(666);
}
},
props: ['title', 'msg', 'run', 'home'] // 动态接收父组件传过来的数据
// 父组件给子组件传值:验证方式
/**
* props: {
* propA: String,
* propB: [String, Number],
* propC: {
* type: String,
* required: true
* },
* propD: {
* type: Number,
* default: 100
* },
* propE: {
* type: Object,
* default: function() {
* return {
* message: 'hello'
* }
* }
* },
* // 自定义验证函数
* propF: {
* validator: function(value) {
* return value > 10
* }
* }
* }
*
*/
}
</script>
3.8、非父子组件传值
/**
*
* 非父子组件传值
*
* 1、新建一个js文件,然后引入vue,实例化vue,最后暴露这个实例
*
* 2、在要广播的地方引入刚才定义的实例
*
* 3、通过VueEmit.$emit('名称','数据')广播数据
*
* 4、在接收数据的地方,通过$on接收广播的数据
* VueEmit.$on('名称', function(data) {
*
* })
*
*/
// VueEvent.js
import Vue from 'Vue'
var VueEvent = new Vue()
export default VueEvent;
// Home.vue文件
<template>
<div>
我是首页组件
<br>
<button @click="emitHome()">给News广播的数据</button>
</div>
</template>
<script>
import VueEvent from '../model/VueEvent.js'
export default {
data() {
return {
msg: '这是一个首页组件'
}
},
methods: {
run() {
alert('这是首页组件的run方法');
},
emitHome() {
VueEvent.$emit('from-home', this.msg);
}
},
mounted() {
VueEvent.$on('from-news',data => {
alert(data);
})
}
}
</script>
// News.vue文件
<template>
<div>
<input v-model="home_msg"/>
我是新闻组件
<br>
<button @click="emitNews()">给Home广播的数据</button>
</div>
</template>
<script>
import VueEvent from '../model/VueEvent.js'
export default {
data() {
return {
msg: '这是一个新闻组件',
home_msg:''
}
},
methods: {
run() {
alert('这是新闻组件的run方法');
},
emitNews() {
// 广播数据
VueEvent.$emit('from-news', this.msg);
}
},
mounted() {
// 监听Home广播的数据
VueEvent.$on('from-home', data => {
// alert(data);
this.home_msg = data;
});
}
}
</script>
3.9、路由(<router-view></router-view>对直接访问路由很重要,不能省略)
// 安装
npm install vue-router --save / cnpm install vue-router --save
// main.js文件
/**
* 1、引入vue-router
* 2、创建组件
* 3、配置路由
* 4、实例化VueRouter
* 5、挂载路由
* 6、<router-view></router-view> 放在App.vue里面
*
*/
import Vue from 'vue'
import App from './App.vue'
/**
* 引入vue-router
*
*/
import VueRouter from 'vue-router'
Vue.use(VueRouter)
/**
*
* 1、创建组件
*
*/
import Home from './components/Home.vue'
import News from './components/News.vue'
import Content from './components/Content.vue'
import Pcontent from './components/Pcontent.vue'
/**
*
* 2、配置路由
*
*/
const routes = [
{ path: '/home', component: Home },
{ path: '/news', component: News },
{ path: '/content/:aid', component: Content },
{ path: '/pcontent', component: Pcontent },
{ path: '*', redirect: '/home' }
]
/**
*
* 3、实例化VueRouter
*
*/
const router = new VueRouter({
routes
})
/**
*
* 4、挂载路由
*
*/
new Vue({
el: '#app',
router,
render: h => h(App)
})
/**
*
* 5、<router-view></router-view> 放在App.vue里面
*
*/
// App.vue
<template>
<div id="app">
<router-link to="/home">首页</router-link>
<router-link to="/news">新闻</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
// News.vue
<template>
<div>
我是新闻组件
<ul>
<li v-for="(item,key) in list" :key="key">
<router-link :to="'/content/' + (key + 1)">{{key + 1}} --- {{item}}</router-link>
</li>
</ul>
<br>
</div>
</template>
<script>
/**
* 不同路由传值
*
* 一、动态路由
*
* 1、配置动态路由
*
* routes = [
* { path: '/user/:id', component: User }
* ]
*
* 2、在对应的页面获取动态路由的值
* mounted() {
* this.$route.params
* }
*
*/
export default {
data() {
return {
msg: '这是一个新闻组件',
list: ['111111','222222','3333333']
}
}
}
</script>
// Content.vue
<template>
<div>
我是内容组件
</div>
</template>
<script>
export default {
data() {
return {
msg: '数据'
}
},
mounted() {
console.log(this.$route.params);
}
}
</script>
// Home.vue
<template>
<div>
我是首页组件
<ul>
<li v-for="(item,key) in list" :key="key">
<router-link :to="'/pcontent?id=' + (key + 1)">
{{key + 1}} --- {{item}}
</router-link>
</li>
</ul>
<br>
</div>
</template>
<script>
/**
* 不同路由传值
*
* 二、获取get传值
*
* this.$route.query
*
*/
export default {
data() {
return {
msg: '这是一个首页组件',
list: ['商品1','商品2','商品3']
}
}
}
</script>
// PContent.vue
<template>
<div>
我是内容组件
</div>
</template>
<script>
export default {
data() {
return {
msg: '数据'
}
},
mounted() {
console.log(this.$route.query);
}
}
</script>
3.10、路由跳转(导航式编程)
// Home.vue
<template>
<div id="home">
我是首页组件
<ul>
<li v-for="(item,key) in list" :key="key">
<router-link :to="'/pcontent?id=' + (key + 1)">
{{key + 1}} --- {{item}}
</router-link>
</li>
</ul>
<br>
<button @click="goNews()">通过js跳转到新闻页面</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: '这是一个首页组件',
list: ['商品1','商品2','商品3']
}
},
methods: {
goNews() {
/**
* 编程式导航,其实就是通过js跳转页面
*/
/**
* 跳转方式一
*/
// this.$router.push({ path: 'news' });
// this.$router.push({ path: '/content/499' });
/**
* 跳转方式二:
* 在main.js中,routes里面给路由设置别名
* 例如: { path: '/news', component: News, name: "news" }
* 可以带参数的动态路由:
* this.$router.push({ name: 'content', params: {id: 123} })
*/
this.$router.push({ name: 'news' })
}
}
}
</script>
3.11、路由嵌套
/*
路由嵌套配置:
1、配置路由
{
path: '/user',
component: User,
children: [
{ path: 'useradd', component: UserAdd },
{ path: 'userlist', component: UserList }
]
},
2、父路由里面配置子路由现实的地方
<router-view></router-view>
*/
// main.js文件
import Vue from 'vue'
import App from './App.vue'
// 引入公共的scss,注意:创建项目的时候必须用scss
// import './assets/css/basic.scss';
/*
路由嵌套配置:
1、配置路由
{
path: '/user',
component: User,
children: [
{ path: 'useradd', component: UserAdd },
{ path: 'userlist', component: UserList }
]
},
2、父路由里面配置子路由现实的地方
<router-view></router-view>
*/
import VueResource from 'vue-resource'
Vue.use(VueResource)
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import Home from './components/Home.vue'
import News from './components/News.vue'
import Content from './components/Content.vue'
import Pcontent from './components/Pcontent.vue'
import User from './components/User.vue'
import UserAdd from './components/User/UserAdd.vue'
import UserList from './components/User/UserList.vue'
const routes = [
{ path: '/home', component: Home },
{ path: '/news', component: News, name: "news" },
{ path: '/content/:aid', component: Content },
{ path: '/pcontent', component: Pcontent },
{
path: '/user',
component: User,
children: [
{ path: 'useradd', component: UserAdd },
{ path: 'userlist', component: UserList }
]
},
{ path: '*', redirect: '/home' }
]
const router = new VueRouter({
mode: 'history', /* 默认路由是hash模式,即http://localhost:8080/#/news带#号的,而history不会带#号 */
routes
})
new Vue({
el: '#app',
router,
render: h => h(App)
})
/**
*
* <router-view></router-view> 放在App.vue里面
*
*/
// User.js文件
<template>
<div id="user">
<div class="user">
<div class="left">
<ul>
<li>
<router-link to="/user/useradd">添加用户</router-link>
</li>
</ul>
<ul>
<li>
<router-link to="/user/userlist">用户列表</router-link>
</li>
</ul>
</div>
<div class="right">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
msg: '这是一个用户组件'
}
}
}
</script>
<style lang="scss">
.user {
display: flex;
.left {
width: 200px;
min-height: 400px;
border-right: 1px solid #eee;
li {
line-height: 2;
}
}
.right {
flex: 1;
}
}
</style>
// UserAdd.vue文件
<template>
<div id="useradd">
添加用户
</div>
</template>
// UserList.vue文件
<template>
<div id="userlist">
用户列表
</div>
</template>