<template>
<div>
<p>我是父组件p>
<button @click="btnClick">点我button>
<son ref="son">son>
div>
template>
<script>
// 1.导入子组件
import son from "./components/son";
export default {
// 2.注册组件
components: {
son
},
methods: {
btnClick() {
//按按钮修改子组件的msg,和调用子组件的sayHi方法.
//console.log(this.$refs.son);//这就等价于子组件this
this.$refs.son.sonMsg = "呵呵";
this.$refs.son.sonSayhi();
}
},
mounted() {
//如果你想在 进入页面就改子组件中的值,而不是按按钮就写在钩子mounted函数里面
// 不能写在created里面,因为父组件和子组件的生命周期, 都是独立的.
// 就算父组件创建了,子组件说不定还没创建好,所以访问子组件的msg访问不到
// 那如果是mounted里面就不一样,mounted都渲染出来那子组件里的msg肯定也可以访问到
//console.log(this.$refs.son.sonMsg);
this.$refs.son.sonMsg='嘻嘻嘻嘻嘻嘻嘻'
},
};
script>
<style>
style>
<template>
<div class="son">
<p>我是子组件p>
<div>{{sonMsg}}div>
div>
template>
<script>
export default {
data() {
return {
sonMsg: "我是子组件的msg"
};
},
methods: {
sonSayhi() {
console.log("我是子组件的方法");
}
}
};
script>
<style>
.son {
width: 200px;
height: 200px;
background-color: pink;
}
style>
效果展示说明: 没点按钮之前子组件的msg:"我是子组件的msg,
由于在主组件的mounted钩子函数中设置了一进入页面修改子组件的msg:“嘻嘻嘻嘻嘻嘻嘻”
然后又设置了点击按钮修改子组件的msg:‘呵呵’,并调用了子组件的方法打印了出来
<template>
<div>
<p>我是主组件p>
<div>{{fatherMsg}}div>
<son>son>
div>
template>
<script>
// 导入组件
import son from './components/son'
export default {
// 注册组件
components:{
son
},
data() {
return {
fatherMsg: "我是主组件的msg"
};
},
methods: {
fatherSayhi() {
console.log("我是主组件的方法");
}
}
};
script>
<style>
style>
<template>
<div class="son">
<p>我是子组件p>
<button @click="btnClick">点我button>
div>
template>
<script>
export default {
methods: {
btnClick() {
// 修改父组价的data中的msg,并调用父节点的方法
this.$parent.fatherMsg = "呵呵";
this.$parent.fatherSayhi();
}
},
mounted() {
// 如果你想直接打开页面就修改主组件的msg值,而不是按按钮就写在mounted钩子函数里
//注意: 父组件的生命周期和 子组件的生命周期是独立的.
//这里要延时,因为怕主组件还没渲染出来
setTimeout(() => {
//console.log(this.$parent.fatherMsg);
this.$parent.fatherMsg = "嘻嘻嘻嘻嘻嘻";
}, 10);
}
};
script>
<style>
.son {
width: 300px;
height: 300px;
background-color: aqua;
}
style>
效果展示说明: 没点按钮之前子组件的msg:"我是主组件的msg,
由于在子组件的mounted钩子函数中设置了一进入页面修改主组件的msg:“嘻嘻嘻嘻嘻嘻”
然后又设置了点击按钮修改主组件的msg:‘呵呵’,并调用了主组件的方法打印了出来
<template>
<div>
<p>我是主组件p>
<son>son>
div>
template>
<script>
// 导入子组件
import son from './components/son'
// 导入外部js文件
import obj from './assets/sb'
export default {
// 注册组件
components:{
son
},
created() {
console.log(obj)
},
}
script>
<style>
style>
<template>
<div>
<p>我是子组件p>
<p>{{msg}}p>
div>
template>
<script>
export default {
data() {
return {
msg:'你好鸭'
}
},
}
script>
<style>
style>
let obj = {
name: '杨杨',
age: 19,
gender: '男'
}
//只能有一个输出
export default obj;
效果展示说明: 运行主组件,(主组件里面有子组件,也有sb.js文件)
子组件son.vue与sb.js都有导出export default(导出只能有一个输出), 主组件就有导入import这两个文件
sb.js文件就写了一个obj对象并且写在主组件的created里面打印出来,所以一打开页面就会出现打印台有这个obj对象
<template>
<div class="wrap">
<div class="play_wrap" id="player">
<div class="search_bar">
<img src="./assets/images/player_title.png" alt />
<input type="text" v-model="songName" @keyup.enter="search" />
div>
<div class="center_con">
<songList ref="songList">songList>
<middle ref="middle">middle>
<comments ref="comments">comments>
div>
<div class="audio_con">
<audio @pause="pauseEvent" @play="playEvent" :src="songUrl" autoplay controls loop class="myaudio" >audio>
div>
div>
div>
template>
<script>
//安装导入axios
import axios from "axios";
//导入左边歌曲列表子组件songList.vue
import songList from "./components/songList";
// 导入右边评论子组件comment.vue
import comments from "./components/comment";
//导入中间碟片动画子组件middle.vue
import middle from "./components/middle";
export default {
//c2.注册组件
components: {
songList,
comments,
middle
},
data() {
return {
//搜索的歌曲名字
songName: "",
// 歌曲播放地址
songUrl: ""
};
},
methods: {
// 搜索事件
search() {
//b3.利用axios发送ajax请求 得到搜索相应的所有歌曲
axios({
url: "http://183.237.67.218:3000/search",
params: {
keywords: this.songName,
//网易云音乐看你这个ip一直发请求,会把你跨域限制.
//加这个随机数参数就是不会出现跨域
xxx: Math.random() * 99999
}
}).then(res => {
// console.log(res);
// 把返回的所有歌曲保存到子组件的list数组中,然后显示在页面上
this.$refs.songList.list = res.data.result.songs;
// 搜索的时候就调用子组件的重新刷新方法,重新加载滚动条高度
this.$refs.songList.reload();
});
},
getSongInfo(id) {
//1. 获取歌曲的url
axios({
url: "https://autumnfish.cn/song/url",
params: {
id
}
}).then(res => {
//console.log(res);
this.songUrl = res.data.data[0].url;
});
// 2.获取歌曲的评论
axios({
url: "https://autumnfish.cn/comment/music",
params: {
id
}
}).then(res => {
//console.log(res);
// 主组件传值子组件
this.$refs.comments.list = res.data.hotComments;
// 调用评论子组件中的刷新方法,来刷新滚动条
this.$refs.comments.reload();
});
//3.获得碟片中间动画的图片封面
axios({
url: "https://autumnfish.cn/song/detail",
params: {
ids: id
}
}).then(res => {
//console.log(res);
this.$refs.middle.picUrl = res.data.songs[0].al.picUrl;
});
},
// 播放触发的事件
pauseEvent() {
// 当播放条暂时播放时,让中间碟片停下来起来也就是取消playing类
this.$refs.middle.playing = false;
},
// 暂停触发的事件
playEvent() {
// 当播放条开始播放时,让中间碟片动起来也就是加上playing类
this.$refs.middle.playing = true;
}
}
};
script>
<style>
body,
ul,
dl,
dd {
margin: 0px;
padding: 0px;
}
.wrap {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url("./assets/images/bg.jpg") no-repeat;
background-size: 100% 100%;
}
.play_wrap {
width: 800px;
height: 544px;
position: fixed;
left: 50%;
top: 50%;
margin-left: -400px;
margin-top: -272px;
/* background-color: #f9f9f9; */
}
.search_bar {
height: 60px;
background-color: #1eacda;
overflow: hidden;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
z-index: 11;
}
.search_bar img {
margin-left: 23px;
}
.search_bar input {
margin-right: 23px;
width: 296px;
height: 34px;
border-radius: 17px;
border: 0px;
background: url("./assets/images/zoom.png") 265px center no-repeat
rgba(255, 255, 255, 0.45);
text-indent: 15px;
outline: none;
}
.center_con {
height: 435px;
background-color: rgba(255, 255, 255, 0.5);
display: flex;
}
.song_wrapper {
width: 200px;
height: 435px;
box-sizing: border-box;
padding: 10px;
list-style: none;
background: url("./assets/images/line.png") right center no-repeat;
position: relative;
overflow: hidden;
}
.song_list li {
font-size: 12px;
color: #333;
line-height: 36px;
width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
.song_list .active {
color: #da651e;
}
.player_con {
width: 400px;
height: 435px;
position: relative;
}
.disc {
position: absolute;
left: 73px;
top: 60px;
z-index: 9;
}
.cover {
position: absolute;
left: 125px;
top: 112px;
width: 150px;
height: 150px;
border-radius: 75px;
z-index: 8;
}
.comment_list {
width: 200px;
height: 435px;
box-sizing: border-box;
padding: 10px;
list-style: none;
background: url("./assets/images/line.png") left center no-repeat;
overflow: hidden;
position: relative;
}
.comment_list dl {
padding-left: 55px;
position: relative;
margin-bottom: 20px;
}
.comment_list dt {
position: absolute;
left: 4px;
top: 0px;
}
.comment_list dt img {
width: 40px;
height: 40px;
border-radius: 20px;
}
.comment_list dd {
font-size: 12px;
}
.comment_list .name {
font-weight: bold;
color: #333;
margin-top: 5px;
}
.comment_list .detail {
color: #666;
margin-top: 5px;
line-height: 18px;
}
.audio_con {
height: 50px;
background-color: #f1f3f4;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
.myaudio {
width: 800px;
height: 40px;
margin-top: 5px;
outline: none;
background-color: #f1f3f4;
}
/* 旋转的动画 */
@keyframes Rotate {
from {
transform: rotateZ(0);
}
to {
transform: rotateZ(360deg);
}
}
/* 旋转的类名 */
.autoRotate {
animation-name: Rotate;
animation-iteration-count: infinite;
animation-play-state: paused;
animation-timing-function: linear;
animation-duration: 5s;
}
/* 是否正在播放 */
.playing {
animation-play-state: running;
}
.play_bar {
position: absolute;
left: 200px;
top: -10px;
z-index: 10;
transform: rotate(-25deg);
transform-origin: 12px 12px;
transition: 1s;
}
/* 播放杆 转回去 */
.play_bar.playing {
transform: rotate(0);
}
style>
<template>
<div class="song_wrapper" ref="song_wrapper">
<ul class="song_list">
<li v-for="(item, index) in list" :key="index" @dblclick="play(item.id)">{{item.name}}li>
ul>
div>
template>
<script>
// 要给左边歌曲列表滚动条,导入IScroll
import iscroll from "iscroll";
export default {
data() {
return {
// 存放搜索对应的所有歌曲的数组
list: [],
// 滚动条实例
myIscroll: "",
};
},
methods: {
// 滚动条刷新方法
reload() {
//$nextTick只适用于vue,它自动帮每次增加了新的li渲染完毕之后就帮我们刷新
this.$nextTick(() => {
this.myIscroll.refresh();
});
},
// 双击左边的歌曲li播放音乐
play(id) {
// 调用主组件的getUrl方法
this.$parent.getSongInfo(id)
}
},
//列表渲染出来就有滚动条
mounted() {
this.myIscroll = new iscroll(this.$refs.song_wrapper, {
mouseWheel: true,
scrollbars: true
});
}
};
script>
<style>
style>
<template>
<div class="player_con">
<img src="../assets/images/player_bar.png" class="play_bar" :class="{playing:playing}"/>
<img src="../assets/images/disc.png" class="disc autoRotate" :class="{playing:playing}"/>
<img :src="picUrl" class="cover autoRotate" :class="{playing:playing}"/>
div>
template>
<script>
export default {
data() {
return {
// 控制是否加playing这个class的变量
playing:false,
// 中间图片封面
picUrl:'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1589124884781&di=a6c25dd1c055f8afd1ee1fcb7008c5d0&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201704%2F11%2F20170411194843_HGBrC.thumb.700_0.jpeg'
}
},
};
script>
<style>
style>
<template>
<div class="comment_list" ref="comment_list">
<div>
<dl v-for="(item, index) in list" :key="index">
<dt>
<img :src="item.user.avatarUrl" alt />
dt>
<dd class="name">{{item.user.nickname}}dd>
<dd class="detail">{{item.content}}dd>
dl>
div>
div>
template>
<script>
// 1.导入滚动条外部插件
import iscroll from "iscroll";
export default {
data() {
return {
// 存放评论的数组
list: [],
//评论区滚动条实例
myIscroll: ""
};
},
methods: {
// 刷新滚动条方法
reload() {
this.$nextTick(() => {
this.myIscroll.refresh();
});
}
},
mounted() {
// 使用 实例化滚动条
this.myIscroll = new iscroll(this.$refs.comment_list, {
mouseWheel: true,
scrollbars: true
});
}
};
script>
<style>
style>
效果展示说明: 该播放器功能分成三个部分,分别是左边歌曲列表,中间动画,右边评论区.
分开开发更有利于团队协作,
现在还没学兄弟之间组件怎么传值所以发送请求歌曲的播放地址,评论,图片封面,的ajax请求都写在主组件在
脚手架就是个项目模板 , 相当于把整个文件基本目录结构搭好了,把必要的文件也建好 了,让我们省了很多事情。脚手架安装: npm install -g @vue/cli ,vue -V 能出现版本号就是安装成功,最好npm配置指向淘宝镜像
1.创建时路径不要选错,就是命令的路径要是需要创建项目的文件夹下
完美选择不出错路径方法:在文件夹相应路径下的地址栏输入cmd —再 回车
2.运行创建命令:vue create 项目名 //这里项目名不要有中文,不要有大写字母,不要搞特殊符号,尽可能有意义 ,像普 通变量命名一样
3.弹出的对话框先选择默认的选项(如下图)
4.稍等一会,等进度条走完 提示如下画面说明成功了,如下图:
5.进入项目文件夹(就是项目名的文件夹):`cd 项目名 直接根据提示即可
6.运行项目:npm run serve
7.稍等片刻 ,出现如下效果说明成功了
a.网络问题换wifi
b.终端的权限问题,新建管理员模式的终端
c. 当前这个文件夹,这个文件被其他软件占用:关闭所有可能影响的软件(重启)
d. npm包管理工具的问题:(昨天那篇安装时已做说明)用yarn来安装或. 清除缓存npm cache clean -f 再重新创建项目
3.创建项目时,用到了第三方模块,文件太多了git人为没有必要管,提示你一下,选择不再显示就OK了,vue-cli创建项目时,已经设置了git忽略文件 就在.gitignore文件当
中