vuejs学习笔记—-父子组件传值、动态组件、自定义组件、vue-router、vue-link、state
简书地址
本片是看视频记录零碎知识点
1、使用mustache输出内容时将输入框输入的内容做处理,使用计算属性,不需要使用监听等功能实现。
export default {
data () {
return {
myValue : ''
}
},
computed: {
checkData () {
this.myValue.replace(/\d/g, '');
}
}
}
使用的地方
<input type="text" v-model="myValue">
{{ checkData }}
想实现的就是在input输入框输入内容时,后面只显示字母,遇数字相当于隐藏。
当然,还有一种实现方式,就是在methods里写个方法,同时在input后面使用数据检查方法来实现。
那么,这两种方式有什么区别呢?哪种更推荐呢?
推荐第一种。
2、 父子组件间传值,在vue2.0以上版本,父子组件传值方式如下
举例,父组件
<template>
<div>
<!-- 参数不区分大小写,也就是最好不要使用驼峰命名,用中线链接即可 -->
<!-- 传固定值 -->
<!-- <com-a number-to-do=78></com-a> -->
<!-- 动态传值 -->
<input type="text" v-model="myVal">
<com-a :my-value = "myVal" @my-event="getMyEvent">
<p slot="header">xxxxx header</p>
<p>1、sloat 使用插槽的方式用来将子组件里的内容插入到父组件中。还可以设定默认值</p>
<p>2、插槽内容比较多的话,可以使用命名的方式指定个字要处理的插槽数据</p>
<p slot="footer">xxxxx footer</p>
</com-a>
<p :is="currentView"></p>
</div>
</template>
<script>
import Vue from 'vue'
import ComA from '../components/comA'
export default {
components: {
ComA
},
data () {
return {
currentView: 'com-a',
myVal : "",
myList: [
{
name:'appale',
price: 2.50
},
{
name:'banaber',
price:8.50
}
]
}
},
methods: {
getMyEvent(hello) {
console.log('I got my event and ' + hello)
}
}
}
</script>
子组件接收参数例子
<template>
<div class="comA">
{{ hello }}
{{ numberToDo}}
<button @click="emitMyEvent">emit</button>
<!-- slot中间的内容是slot的默认值 -->
<slot name = "header">no slot</slot>
<slot>no slot</slot>
<slot name = "footer">no slot</slot>
</div>
</template>
<script>
export default {
// props接收两种类型的参数
// 一种是数组,一种是对象。对象用的比较多,接收时可以限定类型
// props: ['number-to-do'],
props: {
// 'number-to-do': [Number, String, Object]
'my-value': [Number, String, Object]
},
data () {
return {
hello : "I am component A"
}
},
methods : {
emitMyEvent () {
this.$emit('my-event', this.hello);
}
}
}
</script>
<style>
.comA {
background-color: antiquewhite;
}
</style>
3、动态组件
及在template中动态加载需要的组件的功能,比如:
<template>
<div>
<input type="text" v-model="myVal">
<keep-alive>
<p :is="currentView"></p>
</keep-alive>
</div>
</template>
<script>
import Vue from 'vue'
import ComA from '../components/comA'
export default {
components: {
ComA
},
data () {
return {
currentView: 'com-a',
}
}
:is 实现动态组件切换,比如 :is=”currentView” 而在data里给currentView赋值comA。
此时可以用keep-alive将组件缓存,比如comA和comB互相切换时会将不显示的内容进行缓存,提高切换时显示速度。
4、css阶段类名
<button v-on:click="show = !show">
Toggle
</button>
<!-- <p v-color="'red'">Hello World</p> -->
<div class="ab">
<transition name="fade">
<p v-show="show">透明切换效果</p>
</transition>
<transition name="my-trans">
<p v-show="show">上入下出动画</p>
</transition>
</div>
<style>
.fade-enter-active, .fade-leave-active {
/* opacity是透明度的意思,如果是所有属性都要transition,要将opacity改成all */
transition: opacity .5s;
}
.fade-enter, .fade-leave {
opacity: 0;
}
.my-trans-enter-active, .my-trans-leave-active {
transition: all 0.5s ease-out;
}
.my-trans-enter {
transform: translateY(-500px);
opacity: 0;
}
.my-trans-leave-active {
transform: translateY(500px);
opacity: 0;
}
</style>
enter-active前面的名字就是name前面的名字。该处的演示元素用的是p标签,其实可以是一个div,也可以是一个component,实现动态组件过渡。transition 默认的mode是in-out,也可以改成out-in,也就是新的出来的实现和旧的消失的时机问题。
5、元素/组件进入/离开 & 列表过渡
官网
<button v-on:click="show = !show">
进入/离开过渡动画
</button>
<div class="ab">
<transition
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
:css="false">
<p class="animate-p" v-show="show">I am show</p>
</transition>
</div>
methods: {
getMyEvent(hello) {
console.log('I got my event and ' + hello)
},
beforeEnter: (el) => {
$(el).css({
left:'-500px',
opacity:0
});
},
enter: function(el, done) {
$(el).animate({
left:0,
opacity:1
}, {
duration: 1500,
complete: done
});
},
leave: function(el, done) {
$(el).animate({
left: '500px',
opacity:0
}, {
duration:1500,
complete:done
})
}
}
6、自定义指令
自定义指令function使用direactives来定义,与data,method等平行。使用时是’v-xxx’的形式,后面的xxx与directives里的function名要一致。
<p v-color="'red'">v-xxx 的自定义指令</p>
directives: {
color: function(el, binding) {
el.style.color = binding.value
}
}
这是在组件内部,也就是说v-color指令只能在这个组件内使用。那么,怎么定一个全局的指令,可以在所有组件内使用呢?答案是将此定义放在Vue实例化的地方,比如main.js里面。
7、vue-cli 脚手架的安装和使用
8、cnpm的使用
9、vue-router添加子组件
注意一点,如果路由有子路由,比如http://localhost:3000/apple/ 和http://localhost:3000/apple/red,其中第二是就是第一个的子路由,路由代码是这样的
{
path: '/apple',
component: Apple,
children: [
{
path: 'red',
component: RedApple
}
]
},
这时候如果要让red这个子路由生效,必须在apple这个父组件中也使用<router-view></router-view>
,才能打包目的,apple/red才能渲染出redapple中的内容
apple.vue文件的内容:
<template>
<div class="content">
<img class="img" src="../assets/apple.jpg" alt="appale">
<button @click="getParam">get route param</button>
<router-view></router-view>
</div>
</template>
10、vue-link
这个组件也是设置路由用的,可以绑定需要跳转的地址,用法如下:
<router-link :to="{name: 'applePage'}"></router-link>
<router-link :to="'goods'"> to goodsList </router-link>
<router-link :to="{path : 'banana', param:{color:'yellow'}}"> to banana </router-link>
<router-link :to="{path : 'apple/red'}"> to red apple </router-link>
<router-link :to="goodsDetail"> to goods detail </router-link>
上面的applePage和goods是要在data里定义的,不然是会报错的。
当然,这个是在入口的App.vue里,因为跳转地址都是根路径。什么意思呢?举个例子,如果这段代码在apple.vue这个类中,页面如下:
那这些按钮点下去以后url会变成什么呢?比如第一个goodsList,就会是这样:
可以看到,在路由的前面都有一个apple
这个路径。
其他看vue-route官网吧
命名路由
命名路由是指在route-view标签上指定组件名称,比如<router-view name="viewA"></router-view> <router-view name="viewB"></router-view>
响应的在router里指定组件就可以:
{ path: '/apple', component: { viewA: Apple, viewB: RedApple }, children: [ { path: 'red', component: RedApple } ] },
这样匹配来用。
重定向
目标:访问根目录是自动访问apple这个路径。{ path: '/', redirect: 'apple' }
11、 vuex – 官网
vuex是状态管理插件。将组件之间共享的状态,公用型内容的改动等使用统一的状态管理插件起来。
数据状态管理模式图:
flux:状态管理实现流程:
![vuex-flux(/images/fontend/vuex-flux.png)
action和mutatons的区别,munation本身可以修改state的值,但是为什么还要通过action来处理呢?因为action这一步可以加比如异步、网络请求等这样的实现逻辑,而mutation只能是同步的,也不能在其中发出http请求。
vuex常用的有state,muntions,getters,actions,modules这几个核心的concepts,更详细的请参考官网.
示例代码:
vuex.vue入口文件
<template>
<div>
<p>{{ msg }}</p>
<p> state 总价: {{ totalPrice }}</p>
<dog></dog>
<cat></cat>
</div>
</template>
<script>
import Dog from '../components/dog'
import Cat from '../components/cat'
export default {
data () {
return {
msg : 'vuex demo'
}
},
components: {
Dog,
Cat
},
computed: {
totalPrice() {
return this.$store.getters.getTotal
//vuex實現了getter方法,因此不推荐直接从state中拿属性的值
// return this.$store.state.totalPrice
}
}
}
</script>
包括的两个子组件dog.vue
<template>
<div>
<p>{{ msg }}</p>
<button @click="addOne">add one</button>
<button @click="minusOne">minus one</button>
</div>
</template>
<script>
export default {
data () {
return {
msg : 'I am a dog, each of me is 5$. ',
price: 5
}
},
methods: {
addOne() {
this.$store.commit('increment', this.price)
},
minusOne() {
this.$store.commit('decrement', this.price)
}
}
}
</script>
和cat.vue
<template>
<div>
<p>{{ msg }}</p>
<button @click="addOne">add one</button>
<button @click="minusOne">minus one</button>
</div>
</template>
<script>
export default {
data () {
return {
msg : 'I am a dog, each of me is 15$. ',
price: 15
}
},
methods: {
addOne() {
//推荐使用action调用mutation的方式
this.$store.dispatch('increase', this.price)
//不推荐使用下面的直接调用mutations方法的方式
// this.$store.commit('increment', this.price)
},
minusOne() {
this.$store.commit('decrement', this.price)
}
}
}
</script>
实现的效果:
视频和源码
视频共享:
链接: https://pan.baidu.com/s/18TFC0-VSCIWFo977p4YcTQ
提取码: rjcp