初识Vue
- 框架作者 尤雨溪
- 官网 Vue
生命周期
vue.png- beforeCreate:组件刚刚被创建
- created:组件创建完成
- beforeMount:挂载之前
- mounted:挂载之后
Ajax请求和DOM操作是在这里进行的 - beforeDestory:组件销毁前调用
- destoryed:组件销毁后调用
安装Vue
- 全局安装vue-cli,如果安装不上就以管理员身份尝试安装
npm install -g vue-cli
- 创建一个基于webpack模板的新项目
vue init webpack my-project(你的项目名)
Install vue-router? (Y/n) => 这里要输入Y
Use ESlint to lint your code? (Y/n) => 这里最好输入Y,是用于规范代码的
- 安装依赖包
cd my-project(你的项目名)
npm install
npm run dev
或者npm start
都可以
模板语法
<template>
<div>
<!-- 数据绑定 -->
<div>{{title}}</div>
<!-- 函数绑定 -->
<div>computed:{{aDouble}}</div>
<!-- 事件绑定 -->
<div v-on:click="say('hi')">点击我</div>
<div @click="say('hi')">点击我</div> <!-- 简写方式 -->
<!-- 快速创建子元素 -->
<div v-html="rawHtml"></div>
<!-- 动态修改class -->
<div v-bind:class="color">修改class</div>
<div :class="color">修改class</div> <!-- 简写方式 -->
<!-- 过滤器 -->
<div>{{message | capitalize}}</div> <!-- 如果定义了capitalize,显示capitalize中的内容 -->
</div>
</template>
<script>
export default {
// 全局组件的变量定义
data() {
return {
title: "《诗经国风 .周南》",
num: 1,
rawHtml: '<span>123</span>',
color: 'red',
message: 'message'
};
},
// 计算属性
// 一般的函数定义都放在这里
computed: {
aDouble() {
return this.num * 2;
}
},
// 绑定事件的定义都放在这里
methods: {
say(h) {
alert(h);
}
}
// 过滤器
filters: {
capitalize() {
return '123';
}
}
};
</script>
Class与style绑定
<template>
<div>
<!-- class绑定 -->
<!-- 第一种绑定方式 -->
<div class="static" v-bind:class="{'active':isActive,'text-danger':hasError}">
class1
</div>
<!-- 第二种绑定方式 -->
<div :class="classObject">
class2
</div>
<!-- 第三种绑定方式 -->
<div :class="[activeClass, errorClass]">
class3
</div>
<!-- style绑定 -->
<!-- 第一种绑定方式 -->
<div :style="{'color':activeColor,'fontSize':fontSize + 'px'}">
style1
</div>
<!-- 第二种绑定方式 -->
<div :style="styleObject">
style2
</div>
<!-- 第三种绑定方式 -->
<div :style="[baseStyles, overridingStyles]">
style3
</div>
</div>
</template>
<script>
export default {
data() {
return {
isActive: true, // true的话,这个class会留下
hasError: false, // false的话,这个class不会留下
classObject: {
'active': true,
'text-danger': false
},
activeClass: 'active',
errorClass: 'text-danger',
activeColor: 'red',
fontSize: 26,
styleObject:{
'color':'blue',
'fontSize':'26px'
},
baseStyles: {
'color':'black',
},
overridingStyles: {
'fontSize':'26px'
},
}
},
}
</script>
条件渲染
<template>
<div>
<h1 v-if="ok">Yes</h1> <!-- ok的值是true,所以会显示-->
<div v-if="type==='A'">
A
</div>
<div v-else-if="type==='B'"> <!-- type的值是B,所以会显示B-->
B
</div>
<div v-else-if="type==='C'">
C
</div>
<div v-else>
Not A/B/C
</div>
<div v-show="isShow">123</div> <!-- isShow的值是true,所以会显示-->
</div>
</template>
<script>
export default {
data() {
return {
ok: true,
type: "B",
isShow: true
};
},
};
</script>
列表渲染
列表渲染指令v-for可以用于数组和对象
<template>
<div>
<!-- 用于数组 -->
<ul id="example-1">
<li v-for="(item,index) in items" :key="index">
{{index}}- {{item.message}}
</li>
</ul>
<!-- 用于对象 -->
<ul id="example-2">
<li v-for="(value,key) in object" :key="key">
{{key}} : {{value}}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
],
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
};
},
};
</script>
事件处理器
<template>
<div>
<div id="example-1">
<!-- 直接把触发后的处理写在这里 -->
<button v-on:click="counter += 1">增加1</button>
<p>这个按钮被点击了{{counter}}次</p>
</div>
<div id="example-2">
<!-- 把触发后的处理写在方法greet里 -->
<!-- 写成@click="greet()"也是一样的,因为这里不带参数,所以可以省略() -->
<button @click="greet">Greet</button>
<p>这个按钮被点击了{{counter}}次</p>
</div>
<div id="example-3">
<!-- 带参数的方法say -->
<button @click="say('hi')">say</button>
</div>
<div @click="dothis2">
<!-- 事件修饰符(stop):阻止事件冒泡 -->
<!-- 父元素上的dothis2事件不会被触发 -->
<button @click.stop="doThis">
dothis
</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
counter:0
};
},
methods:{
greet(){
this.counter += 1;
},
say(h){
alert(h);
},
dothis2(){
alert('dothis2');
},
doThis(){
alert('doThis');
}
}
};
</script>
表单控件绑定
<template>
<div>
<!-- input中的内容改变了,message的值也会随之改变 -->
<input v-model="message"/>
<p>Message is {{message}}</p>
<!-- checkbox中的内容改变了,checkedNames的值也会随之改变 -->
<input type="checkbox" value="Jack" v-model="checkedNames"/>
<input type="checkbox" value="Rose" v-model="checkedNames"/>
<br/>
<span>Checked names:{{checkedNames}}</span>
<!-- select 中的内容改变了,selected的值也会随之改变 -->
<div>
<select v-model="selected">
<option disabled>请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>selected:{{selected}}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
message:'message',
checkedNames:[],
selected:'',
};
},
};
</script>
自定义组件
index.vue(使用组件)
<template>
<div>
<CountDown color="blue" @end="ending()"/> <!-- 组件使用 -->
<!-- color="blue":传递参数给组件 -->
<!-- @end="ending()":由组件触发的事件 -->
</div>
</template>
<script>
import CountDown from '@/components/CountDown.vue'; // 组件导入
export default {
methods:{
ending(){
alert("已经结束了");
}
},
// 组件注册
components:{
CountDown
// 'count-down':countDown // 组件重名名
}
};
</script>
CountDown.vue(定义组件)
<template>
<p :style="{color:color}">{{time}}</p>
</template>
<script>
export default {
data() {
return {
time:10
};
},
mounted(){
var vm = this;
var t = setInterval(() => {
vm.time--;
if(vm.time === 0){
clearInterval(t);
vm.$emit("end"); // 在这里触发end事件,父组件会响应到
}
}, 1000);
},
// 接受父组件传递过来的参数color
props:{
color:{
type:String, // 参数的类型是字符串
default:'black' // 参数的默认值是'black'
}
},
};
</script>
Vue中的DOM操作
<template>
<div>
<div ref="rhead" class="chead" id="ihead"></div>
</div>
</template>
<script>
export default {
mounted(){
// DOM已经生成
// 如果已经引入jQuery,可以直接这样操作
// $(".chead").html("123");
// 利用原生javascript找到元素
// document.getElementById("ihead");
// Vue提供的找到元素方法
this.$refs.rhead.innerHTML = 'helloworld';
}
};
</script>
Vue中的过渡效果
<template>
<div>
<div id="demo">
<!-- 点击按钮会慢慢显示/隐藏hello -->
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
</div>
</template>
<script>
export default {
data() {
return {
show: false
};
},
};
</script>
<style>
/* xx是transition标签中name属性的值 */
/* 显示:xx-enter(显示开始) -> xx-enter-active(显示进行中) -> xx-enter-to(显示结束) */
/* 隐藏:xx-leave(隐藏开始) -> xx-leave-active(隐藏进行中) -> xx-leave-to(隐藏结束) */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0; /* 刚开始显示 和 隐藏结束 的时候,透明度是0,没有显示 */
}
.fade-leave,
.fade-enter-to {
opacity: 1; /* 刚开始隐藏 和 显示结束 的时候,透明度是1,完全显示 */
}
</style>
Vue-router:官网
<template>
<div>
<!-- 第一种跳转写法:一个简单的跳转 -->
<router-link to="/demo9">demo9</router-link>
<!-- 第二种跳转写法:传递参数 -->
<router-link :to="{name:'demo9',params:{userId:123}}">demo9-params</router-link>
<!-- 第三种跳转写法:普通参数 + 查询参数 -->
<router-link :to="{name:'demo9',params:{userId:123},query:{plan:'private'}}">demo9-query</router-link>
<!-- 其他跳转写法 -->
<button @click="toURL">跳转</button>
</div>
</template>
<script>
export default {
data() {
return {
show: true
};
},
methods: {
toURL() {
// !!注意这里是router
// 第四种跳转写法:与第一种类似
// this.$router.push({ path: '/demo8' });
// 第五种跳转写法:与第二种类似
// this.$router.push({ name: 'demo9', params: { userId: 123 } });
// 第六种跳转写法:与第三种类似
this.$router.push({ name: 'demo9', params: { userId: 123 }, query:{plan:'private'} });
},
}
};
</script>
问题1:路由中该怎么设定,才能让demo9接收到参数?
{
path: '/demo9/:userId', // 这里表示接收一个参数,名字叫userId
name: 'demo9',
component: Demo9
},
问题2:demo9中怎么接收参数?
mounted(){
// !!注意这里是$route
console.log(this.$route.params.userId);
console.log(this.$route.query.plan);
}
状态管理vuex:官网
- npm install 引入vuex包
npm install vuex --save
- 全局状态管理,所有页面共享数据
- 设置数据:this.$store.dispatch('increment',1000)
- 获取数据:this.$store.state.num
使用步骤1:新建src/store/index.js文件,以应用vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex) // 调用Vuex
// state:数据,用于全局共享
// mutations:转换,想做的操作
// actions:动作,用于调用mutations里的处理
export default new Vuex.Store({
state: {
count: 0,
num: 1
},
mutations: {
increment(state, num) { // num是用户传入的参数,经由actions传递,就是下面的obj
state.count++;
state.num = num;
}
},
actions: {
inc({ commit }, obj) {
commit('increment', obj); // obj是用户传入的参数,调用increment的时候会传递给它
}
}
})
使用步骤2:main.js中引入和使用store,以构建可用的vuex环境
import store from './store' // 引入store
// ...其他import内容此处省略...
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, // 使用store
components: { App },
template: '<App/>'
})
使用步骤3:获取和设置数据
<template>
<div>
<div>{{msg}}</div>
<button @click="change">change</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: '123'
};
},
methods: {
change(){
// vuex修改数据
this.$store.dispatch('inc',1000);
// vuex取得数据
this.msg = this.$store.state.num;
}
}
};
</script>
Slot插槽:常用于组件调用中
定义组件:components/slot.vue
<template>
<div>
<slot></slot> <!-- 第一个插槽 -->
<slot name="bottom"></slot> <!-- 第二个插槽 -->
</div>
</template>
使用组件:pages/xxx.vue
<template>
<div>
<Slots>
<!-- 以下两个标签会插入到组件Slots的第一个插槽中 -->
<div>插卡1</div>
<div>插卡2</div>
<!-- 以下标签会插入到组件Slots的第二个插槽中,因为设置了属性slot="bottom" -->
<div slot="bottom">插卡3</div>
</Slots>
</div>
</template>
<script>
import Slots from '@/components/slot.vue'; // 引入组件
export default {
components: {
Slots // 定义组件
}
};
</script>
移动组件库Mint UI
- npm install 引入Mint UI包
npm install mint-ui@1 --save
使用步骤1:main.js中引入和使用mint-ui,以构建可用的mint-ui环境
import MintUI from 'mint-ui' // 引入mint-ui
import 'mint-ui/lib/style.css' // 引入mint-ui的样式
Vue.use(MintUI); // 全局使用
使用步骤2:使用mint-ui移动组件
<template>
<div>
<mt-tabbar>
<mt-tab-item id="外卖">
<img slot="icon" src="../../assets/logo.png">
外卖
</mt-tab-item>
<mt-tab-item id="订单">
<img slot="icon" src="../../assets/logo.png">
订单
</mt-tab-item>
<mt-tab-item id="发现">
<img slot="icon" src="../../assets/logo.png">
发现
</mt-tab-item>
<mt-tab-item id="我的">
<img slot="icon" src="../../assets/logo.png">
我的
</mt-tab-item>
</mt-tabbar>
</div>
</template>
<script>
import Vue from 'vue'
import { Toast, MessageBox, Tabbar, TabItem } from 'mint-ui';
// 相当于组件注册
Vue.component(Tabbar.name, Tabbar);
Vue.component(TabItem.name, TabItem);
export default {
mounted() {
Toast('提示信息');
MessageBox('提示','操作成功');
}
};
</script>
网友评论