基本结构
new Vue({
data:{//用于绑定数据
a:1,
b:[]
},
methods:{//用于绑定的方法
doSomething:function(){
this.a++;
}
},
watch:{//用于监听数据变化
'a':function(new,old){
console.log(new,old)
}
},
computed:{//用于计算数据
myValueWithoutNumber() {
return this.myValue.replace(/\d/g,'')
}
},
})
源生指令
v-text指定节点文本
v-html指定html格式并解析
v-show隐藏,利用display
v-if隐藏,直接销毁节点
v-else前面必须有v-if v-else-if
v-for="item in arr" {{item}}变量
v-for="(item,index) in arr" {{index}}角标
v-for="(val,key,index) in obj" 值,键,角标 遍历对象
加上:key="item" 提高效率
v-on事件绑定
v-bind属性绑定
v-model数据绑定,一般用于input
checkbox绑定多个:value可修改数组
修饰符:.number .trim .lazy
v-once只绑定一次
v-pre不解析
绑定事件
//只触发一次使用v-once
<button v-on:click="doThis"></button>
<button @click="doThis"></button>
methods:{
doThis:function(){
}
}
数据渲染
<p>{{a}}</p>
<p v-text="a"></p><!--格式处理-->
<p v-html="a"></p><!--格式保存-->
new Vue({
data:{
a:1,
b:[]
}
})
//强制渲染函数
app.$forceUpdate()
控制隐藏
<p v-if="isShow"></p><!--直接删除标签-->
<p v-show="isShow"></p><!--通过display属性渲染-->
new Vue({
data:{
isShow:true;
}
})
渲染循环
<ul>
<li v-for='item in items'>
<p v-text='item.label'></p>
</li>
</ul>
data:{
item:[
{
label:'apple'
},
{
lable:'banana'
}
]
},
数据绑定
<img v-bind:src="imageSrc">
<img :src="imageSrc"><!--简写形式-->
<div :class="{red:isRed}"></div><!--当isRed为true时,将类名设置为red-->
<div :class="[classA,classB]"></div>
<div :class="[classA,{classB:isB,classC:isC}]"></div>
<a :href="link"></a>
data(){
return{
link:https://www.baidu.com
}
}
<!--各种类型表单演示-->
<select v-model="mySelection">
<option v-for="item in selectOption" :value="item.value">{{item.name}}</option>
</select>
{{mySelection}}
<input v-model="myRadio" type="radio" value="apple"/>
<input v-model="myRadio" type="radio" value="banana"/>
{{myRadio}}
<input v-model.lazy="myValue" type="text" /><!--trim,number-->
{{myValue}}
<input type="checkbox" v-model="myCheckBox" v-for="item in boxex" :value="item"/>
{{myCheckBox}}
data() {
return {
selection:'',
selectOption:[
{
name:'apple',
value:0
},
{
name:'banana',
value:1
}
],
boxex:['apple','banana'],
myRadio:'',
myValue:'',
myCheckBox:[]
};
},
{{false ? 'a':'b'}}//b
v-html="<span>123</span>"//123
绑定style会给根据浏览器自动加前缀
app.$set(app.obj,'a',1)
app.$delelte(app.obj,'a',1)
引入组件
import comA from './components/a'<!--导入-->
export default{
components:{comA}<!--注册-->
}
组件间通信
<!--父组件:-->
<com-a @my-event="onComaMyEvent"></com-a><!--声明my-event事件,并绑定onComaMyEvent方法-->
<script>
import comA from "./components/a"
export default {//导入并注册
components:{comA},
methods:{
onComaMyEvent(param) {
console.log('on my comA'+param)
}
}
}
</script>
<!--子组件:-->
<button @click="emitMyEvent"></button>
methods:{
emitMyEvent() {
this.$emit('my-event',this.hello)<!--通过$emit方法传值-->
}
}
计算属性
//自带缓存
<!--便与实现复杂功能-->
<input type="text" v-model="myValue"/>
{{myValueWithoutNumber}}
computed:{
myValueWithoutNumber() {
return this.myValue.replace(/\d/g,'')
}
},
<!--或(通过调用方法实现实时更新)-->
<input type="text" v-model="myValue"/>
{{getMyValueWithoutNumber}}
methods:{
getMyValueWithoutNumber() {
return this.myValue.replace(/\d/g,'')
}
},
通过$(this.val)获取
监听器
<input type="text" v-model="myValue"/>
watch:{
myValue:function (val,old) {
console.log(val,old)
}
},
handle (){},immediate:true//会让方法初始化时执行一次
deep:true//false时,没有引用时改变对象的属性不会触发,或者监听obj.a
父子组件通信
子————>父(通过触发emit事件)
父————>子(通过属性传递)
<!--1. 父组件:-->
<input type="text" v-model="myValue"/>
<!--动态绑定myValue属性,传递给子组件,并在触发my-event事件时调用getMyEvent方法-->
<com-a :my-value="myValue" @my-event="getMyEvent"></com-a>
methods:{
getMyEvent(hello) {<!--接收子组件传递的参数-->
console.log('i got my event'+hello)
}
}
<!-- 2. 子组件-->
{{myValue}}<!--接收父组件属性myValue-->
<button @click="emitMyEvent"></button>
props:{
'my-value':[Number,String]<!--注册父属性my-value,并指定参数的数据类型-->
},
data() {
return {
hello: 'i am a component a '
}
},
methods:{
emitMyEvent() {
<!--$emit方法用于将子组件的数据传递给父组件中的my-event事件,将hello数据传递给父组件-->
this.$emit('my-event',this.hello)
}
}
插槽功能
<!--父组件:-->
<com-a>
<!--将模板插到对应的子组件标签里-->
<p slot="header">header</p>
<p slot="footer">footer</p>
</com-a>
<!--子组件:-->
<!--slot标签接收模板-->
<slot name="header"></slot>
<slot>XXX</slot>
<slot name="footer"></slot>
//作用域插槽
<slot aaa="123" bbb="456"></slot>
//在被引用元素中获取到插槽属性
<span slot-scope="props">{{props.aaa + props.bbb}}</slot>
//组件沟通
privide(){}和inject(){}
Object.defineprojerty的get方法
动态组件
<!--通过改变currentView实现动态加载组件-->
<keep-alive><!--keep-alive将之前的组件缓存起来,提高组件切换速度-->
<p :is="currentView"></p>
</keep-alive>
动画
<!--若标签名相同会出bug,通过属性key="XXX"区分-->
<button @click="show = !show">Toggle</button>
<div class="ab">
<transition name="fade" mode="out-in"><!--通过transition标签实现-->
<p v-show="show">i am show</p>
</transition>
</div>
<!--淡入淡出-->
<style>
.fade-enter-active,.fade-leave-active{
transition: opacity .5s ease-out;
}
.fade-enter,.fade-leave-active{
opacity: 0;
}
</style>
路由
<!-- main.js -->
import VRouter from 'vue-router'<!-- 导入路由组件 -->
import Apple from './components/apple'<!-- 导入两个组件 -->
import Banana from './components/banana'
Vue.use(VRouter)<!-- 注册 -->
let router = new VRouter({
mode:'history',//去掉url中的#号
//base: '/base/'// 基路径为/base/
// linkActiveClass: 'active link', //被激活的路径会添加class
// linkExactActiveClass: 'exact link',//被完全激活的路径添加class
scrollBehavior (to, from, savedPosition){
//返回时页面处于用户之前所停留的位置
if (savedPosition) {
return savedPosition
} else {
return { x:0, y:0 }
}
},
fallback: true //当浏览器不支持跳转时开启多页模式
routes: [
{
<!-- :后面为参数传给指定组件 -->
path: '/apple/:color/detail/:type',
props: true,//直接把参数传到子组件中的props中
component:Apple,
name:'applePage',<!-- 自定义命名 -->
meta: {
title: 'this is app',
description: '123'
},
children:[<!-- 子路由 -->
{
path:'red',<!-- tp://localhost:8080/apple/red -->
component:RedApple
}
]
},{
path: '/banana',
component:Banana
}
]
});
new Vue({
el: '#app',
router,<!-- 将上面配置的router实例化 -->
render:function (h) {
return h(App);
}
})
<!-- 在Apple组件中,用内置对象$route.params接收参数Json对象 -->
<!-- App.vue -->
<router-view></router-view><!-- 内置组件 -->
//router-link 本身是一个a标签
<router-link :to="{path:'/apple',params:{color:'yellow'}}">to apple</router-link><!-- 或把path:'/apple'替换为name:'applePage' -->
<router-link to="/banana">to banana</router-link>
<router-link :to="{path:'/apple/red'}">to apple red</router-link>
<!-- 命名路由 -->
routes: [
{
path: '/apple',
component:{
ViewA:Apple,
ViewB:RedApple
}
},
{
path: '/banana',
component:Banana
}
]
<!-- App.vue中 -->
<router-view name="viewA"></router-view>
<router-view name="viewB"></router-view>
<!-- 重定向 -->
routes: [
{<!-- 将根目录重定向到/apple -->
path:'/',
redirect:'/apple'
},
]
通过this.$route获取到全部路径信息
//webpack.config.client.js 配置刷新路径
historyApiFallback: {
index: 'index.html'
}
状态管理
组件-->actions-->Mutations-->State
<!-- main.js中引入Vuex -->
import Vuex from 'vuex'
Vue.use(Vuex)<!-- 注册 -->
let store = new Vuex.Store({
state:{<!-- 保存状态 -->
totalPrice:0
},
getters:{<!-- 将状态封装 -->
getTotal(state) {
return state.totalPrice
}
},
mutations:{<!-- 减少两个方法 -->
increment(state,price) {
state.totalPrice += price
},
decrement(state,price) {
state.totalPrice -= price
}
}
})
new Vue({
el: '#app',
store<!-- 实例化,在子组件中通过this.$store.state.commit调用 -->
})
<!-- App.vue -->
<template>
<div>
{{totalPrice}}
<apple></apple>
<banana></banana>
</div>
</template>
<script>
import Apple from './components/apple'
import Banana from './components/banana'
export default {
components:{
Apple,Banana
},
computed:{
totalPrice() {/* 通过封装的getters获取状态中的总价 */
return this.$store.getters.getTotal
}
},
}
</script>
<!-- Apple组件中 -->
methods: {
addOne() {<!-- 通过commit方法,来触发mutations中的方法,并传入调用的方法名和参数 -->
this.$store.commit('increment', this.price)
},
minuOne() {
this.$store.commit('decrement', this.price)
}
}
<!-- 通过action触发mutations -->
<!-- main.js -->
mutations:{
increment(state,price) {
state.totalPrice += price
},
decrement(state,price) {
state.totalPrice -= price
}
},
actions:{<!-- 只能调用mutations里面的方法 -->
increase(context,price) {
context.commit('increment',price)
}
}
<!-- 在Apple组件中这样调用-->
addOne() {
<!-- dispatch 专门用来触发action -->
this.$store.dispatch('increase', this.price)
},
总结: 1. 异步修改store数据的情况下,使用action
2.同步的情况下使用mutation
vue-resource(ajax)
import VueResource from 'vue-resource'
Vue.use(VueResource)//注册插件
//在页面初始化时
created:function(){
this.$http.get('getList').then(//POST:post('getList',{userId:123})
function(data) {
console.log(data)
},function(err) {
console.log(err)
}
)
},
生命周期
beforeCreate(){},//初始化一定会执行,
create(){},//初始化完毕执行
beforeMount(){},//挂载到页面才会执行,由最外层节点调用,其他方法
mounted(){},//挂载完毕执行
beforeUpdate(){},//每次有数据更新才会执行
updated(){},//更新完毕执行
activated(){},
deactivated(){},
beforeDestroy(){},//Vue实例被销毁时执行
destroyed(){},//销毁后执行
errorCaptured(){}//向上冒泡,收集错误信息
定义组件
Vue.component('CompOne',component)//定义全局组件,驼峰命名,类似于Java类
components:{ CompOne: component},
<comp-one></comp-one>//自动转为-形式
非new Vue形式的组件,定义data属性:
data () {
return {
text: 123
}
}
props: {//从父组件传进来的属性
active: Boolean
}
<comp-one :active="true"></comp-one>
在子组件调用this.$parent.text改变父组件的数据
组件间数据双向绑定
import Vue from 'vue'
const component = {
model: {
prop: 'value1',
event: 'change'
},
props: ['value1'],
template: `
<div>
<input type="text" @input="handleInput" :value="value1">
</div>
`,
methods: {
handleInput (e) {
this.$emit('change', e.target.value)
}
}
}
new Vue({
components: {
CompOne: component
},
el: '#root',
data () {
return {
value: '123'
}
},
template: `
<div>
<comp-one v-model="value"></comp-one>
</div>
`
})
如果你想把一个对象的所有属性作为 prop
进行传递,可以使用不带任何参数的 v-bind (即用
v-bind 而不是 v-bind:prop-name)。例如,已知一个todo 对象:
todo: {
text: 'Learn Vue',
isComplete: false
}
然后:
<todo-item v-bind="todo"></todo-item>
将等价于:
<todo-item
v-bind:text="todo.text"
v-bind:is-complete="todo.isComplete"
></todo-item>
自定义事件
使用 $on(eventName) 监听事件
使用 $emit(eventName, optionalPayload) 触发事件
父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
Table属性
在el-table中声明slot-scope="scope",单行中使用scope.row获取某行的属性
//把数组里符合条件的数据筛选出来
this.tableData = this.tableData.filter(o=>o.goods.goodsId!=goods.goodsId);
//固定表头
只要在el-table元素中定义了height属性,即可实现固定表头的表格,而不需要额外的代码。
//固定一列
固定列需要使用fixed属性,它接受 Boolean 值或者leftright,表示左边固定还是右边固定。
//多级表头
只需要在 el-table-column 里面嵌套 el-table-column,就可以实现多级表头。
//展开行
通过设置 type="expand" 和 Scoped slot 可以开启展开行功能,el-table-column 的模板会被渲染成为展开行的内容,展开行可访问的属性与使用自定义列模板时的 Scoped slot 相同。
网友评论