Vue-resource(了解)
是发送ajax请求的插件库。
首先安装——在main.js中引入
// 引入Vue-resource插件库
import VueResource from "vue-resource"
// 使用
Vue.use(VueResource)
可以将axios.get()替换为下边的写法:
this.$http.get(`https://api.github.com/search/users?q=${this.keywords}`).then(
response=>{......}
error=>{...... }
插槽
作用:让父组件可以向子组件指定位置插入html结构,也是一种数组间的通信方式,适用于父组件==>子组件
分类:默认插槽,具名插槽,作用域插槽
理解:数据在组件自身(CategoryData),但根据数据生成的结构需要组件的使用者(App)来决定
默认插槽
语义化:子组件挖坑,父组件填土
App.vue
<template>
<div class="main">
<CategoryItem title="美食">
<a href="http://www.baidu.com">此处是图片</a>
</CategoryItem>
<CategoryItem title="游戏">
<ul>
<li v-for="(item,index) in games" :key="index">{{item}}</li>
</ul>
</CategoryItem>
<CategoryItem title="电影">
<a href="http://www.baidu.com">此处是视频</a>
</CategoryItem>
</div>
</template>
CategoryItem.vue
<template>
<div class="demo">
<h3>{{title}}</h3>
<!-- 定义一个插槽 -->
<!-- 指定图片和视频所放的位置 -->
<slot></slot>
<!-- <slot>你好啊</slot>,插槽里可以写一些内容,当插槽里没有内容时会显示这些内容-->
</div>
</template>
具名插槽
语义化:子组件挖坑的同时取一个名字,父组件填土
CategoryItem.vue
<template>
<div class="demo">
<h3>{{title}}</h3>
<!-- 定义一个插槽 -->
<!-- 指定图片和视频所放的位置 -->
<slot name="picture"></slot>
<slot name="content"></slot>
</div>
</template>
<script>
export default {
name:"CategoryItem",
props:["title"]
}
</script>
<style>
.demo {
width: 200px;
height: 300px;
background-color: skyblue;
}
h3 {
background-color: orange;
margin-top: 10px;
text-align: center;
}
</style>
App.vue
<template>
<div class="main">
<CategoryItem title="美食">
<a slot="picture" href="http://www.baidu.com">此处是图片</a> <!-- 放入名字为content的插槽 -->
<h2 slot="content">欣赏一下图片吧</h2> <!-- 放入名字为picture的插槽 -->
</CategoryItem>
<CategoryItem title="游戏">
<ul slot="picture"> <!-- 放入名字为picture的插槽 -->
<li v-for="(item,index) in games" :key="index">{{item}}</li>
</ul>
<!-- 注意点1: -->
<!-- 想要将下面的链接分隔出间距,直接在链接后面加上 并不能起作用,标准写法:写一个div,把他们包裹起来,统一规定放哪个插槽,并给这个div增加样式,对他们进行间隔排列-->
<div class="foot" slot="picture">
<a href="http://www.baidu.com">单机游戏</a>
<a href="http://www.baidu.com">网络游戏</a>
<a href="http://www.baidu.com">其他游戏</a>
</div>
</CategoryItem>
<CategoryItem title="电影">
<a slot="picture" href="http://www.baidu.com">此处是视频</a>
<!-- 注意点2: -->
<!-- 当有很多元素都要放入picture的插槽时,可以包裹元素,但不生成新的DOM元素 ,所以可以用template标签,如果用div,则会有一个多余的盒子,使用template更好-->
<!-- 当使用template标签时,可以有另一种写法,即<template v-slot:"picture"> -->
<template slot="picture">
<div class="foot">
<a href="http://www.baidu.com">经典</a>
<a href="http://www.baidu.com">热门</a>
<a href="http://www.baidu.com">推荐</a>
</div>
<h4>欢迎来看电影</h4>
</template>
</CategoryItem>
</div>
</template>
<script>
import CategoryItem from "./components/CategoryItem.vue"
export default {
components: {CategoryItem},
name: 'App',
data(){
return {
foods:["火锅","烧烤","小龙虾","牛排"],
games:["王者荣耀","我的世界","第五人格","蛋仔派对"],
films:["《教父》","《我是证人》","《消失的她》","《律政俏佳人》"]
}
}
}
</script>
<style>
.main,.foot{
display: flex;
justify-content: space-around;
}
h4 {
text-align: center;
}
</style>
效果示例:
作用域插槽
语义化:子组件挖坑的同时取一个名字,并在挖坑时将数据传递给父组件使用
要求:现在使数据在子组件中,且第一个是无序列表,第二个是有序列表,第三个满足每一个li是h4标题
CategoryItem.vue:
<template>
<div class="demo">
<h3>{{title}}</h3>
<!-- games传递给插槽的使用者,即谁往这个插槽里塞结构,games就传给了谁-->
<slot :foods="foods"></slot>
<slot :games="games"></slot>
<slot :films="films"></slot>
</div>
</template>
<script>
export default {
name:"CategoryItem",
props:["title"],
data(){
return {
foods:["火锅","烧烤","小龙虾","牛排"],
games:["王者荣耀","我的世界","第五人格","蛋仔派对"],
films:["《教父》","《我是证人》","《消失的她》","《律政俏佳人》"]
}
}
}
</script>
App.vue
<template>
<div class="main">
<CategoryItem title="美食">
<!-- 另一种写法:(解构赋值) -->
<template scope="{foods}">
<ul>
<li v-for="(item,index) in foods" :key="index">{{item}}</li>
</ul>
</template>
</CategoryItem>
<CategoryItem title="游戏">
<!-- 这里必须在最外层加上template,注意:后面写scope,而不是scoped -->
<template scope="acquire">
<!-- 这里的{{acquire}}是games:["王者荣耀","我的世界","第五人格","蛋仔派对"], -->
<ol>
<li v-for="(item,index) in acquire.games" :key="index">{{item}}</li>
</ol>
</template>
</CategoryItem>
<CategoryItem title="电影">
<template scope="acquireFilm">
<h4 v-for="(item,index) in acquireFilm.films" :key="index">{{item}}</h4>
</template>
</CategoryItem>
</div>
</template>
<script>
import CategoryItem from "./components/CategoryItem.vue"
export default {
components: {CategoryItem},
name: 'App',
}
</script>
效果:
在作用域插槽中和具名插槽中需要包裹的情况下需要使用到template标签
vuex
概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中
多个组件的共享状态进行集中式管理(读/写),也是种组件间通信的方式,且适用于任意组件间通信。
什么时候使用Vuex?
1.多个组件依赖于同一状态
2.来自不同组件的行为需要变更同一状态
搭建vuex环境
1.创建文件:src/store/index.js
// 该文件用于创建Vuex中最为核心的store
// 想要在index.js中使用Vuex,需要先引入Vue
import Vue from 'vue'
// 引入Vuex
import Vuex from "vuex"
// 使用vuex
Vue.use(Vuex)
// 准备actions——用于响应组件中的动作
const actions={}
// 准备mutations——用于操作数据(state)
const mutations={}
// 准备state——用于存储数据
const state={}
// 创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state
})
2.在main.js中创建vm时传入store配置项
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 引入store
import store from "./store/index"
// // 使用vuex
// Vue.use(Vuex) 写在这里会报错,顺序不对。正确写法写在index.js中
new Vue({
el:"#app",
render: h => h(App),
// 配置store
store,
// 安装全局事件总线
beforeCreate(){
Vue.prototype.$bus=this
}
})
vuex的原理图
vuex基本使用——使用vuex写求和案例
CountData.vue
<template>
<div>
<h1>当前求和为:{{$store.state.sum}}</h1>
<select v-model.number="n"> <!-- 添加v-model="n"为了获取用户的输入。.number将值1.2.3全部转化为数字,不然全是字符串不能相加减。或者在value前加: -->
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<button @click="incrementodd">当前和为奇数再加</button>
<button @click="incrementwait">等一等再加</button>
</div>
</template>
<script>
export default {
name:"CountData",
data(){
return {
n:1
}
},
methods:{
increment(){
this.$store.dispatch("jia",this.n)
},
decrement(){
this.$store.dispatch("jian",this.n)
},
incrementodd(){
// 第一种写法:
// if(this.$store.state.sum%2){
// this.$store.dispatch("jia",this.n)
// }
// 第二种写法
this.$store.dispatch("jiaOdd",this.n)
},
incrementwait(){
// 第一种写法:
// setTimeout(()=>{
// this.$store.dispatch("jia",this.n)
// },500)
// 第二种写法
this.$store.dispatch("jiawait",this.n)
}
}
}
</script>
<style>
button {
margin-left:5px;
}
</style>
index.js
// 准备actions——用于响应组件中的动作
const actions={
jia(context,value){
context.commit("JIA",value) //jia是actions中的,JIA是mutations中的
},
jian(context,value){
context.commit("JIAN",value)
},
jiaOdd(context,value){
if(context.state.sum%2){ //这里注意怎么获取sum
context.commit("JIAODD",value)
}
},
jiawait(context,value){
setTimeout(()=>{
context.commit("JIAWAIT",value)
},800)
}
}
// 准备mutations——用于操作数据(state)
const mutations={
JIA(state,value){
state.sum+=value
},
JIAN(state,value){
state.sum-=value
},
JIAODD(state,value){
state.sum+=value
},
JIAWAIT(state,value){
state.sum+=value
}
}
// 准备state——用于存储数据
const state={
sum:0 //当前的和
}
组件中读取vuex中的数据:
$store.state.sum
(在模板中)
this.$store.state.sum
(不在模板中)