vue 父子组件 基础应用scrollball v-model sync
# 组件之间通信 可以通过 v-model 子组件可以通过 改变数据来改变父组件的数组
* v-model 子组件需要接受value属性,需要出发this.$emit("input","data");
v-model="posStart" === @input="input" :value="posStart" //"input" 底层自己实现 不用写
* sync 同步子组件与父组件的值 子组件需要接受 value1 的值,需要this.$emit("update:value1","data")
:value1.sync = "posStart" === @update:value1 ="input" :value1="posStart" //===后面的父组件需要写input函数 带sync不用写
* 传统的props $emit
# 父组件调用子组件的函数
* 如果是某一个特定的组件 在父组件调用子组件的地方加上ref,用this.$refs.refName.fn();
* 如果是需要调用所有子组件的方法,可以在父组件中使用$children,调用子组件的方法
1.父组件App
1 <template> 2 <div id="app"> 3 <!-- 4 <ScrollBall @input="input" :value="posStart" color="green" :target="posTarget"></ScrollBall>--> 5 <!-- v-model 底层 实现@input="input" :value="posStart" 父组件中不需要写 input函数 v-model底层会自己写赋值--> 6 <ScrollBall v-model="posStart" color="yellow" :target="posTarget"></ScrollBall> 7 <ScrollBall ref="ball2" :value.sync="posStart" color="red" :target="posTarget"></ScrollBall> 8 <!-- 9 <ScrollBall @update:value1 ="input" :value1="posStart" color="red" :target="posTarget"></ScrollBall> 10 --> 11 <button @click="stopHandle"> stop </button> 12 </div> 13 </template> 14 15 <script> 16 import ScrollBall from "./components/ScrollBall.vue"; 17 export default { 18 name: "app", 19 beforeUpdate() { 20 // console.log(this.posStart); 21 }, 22 data() { 23 return { 24 posStart: 160, 25 posTarget: 400 26 }; 27 }, 28 components: { 29 ScrollBall 30 }, 31 methods: { 32 stopHandle(){ 33 this.$children.forEach(ele=>{ 34 ele.stop(); 35 }); 36 console.log(this.$children); 37 // this.$refs.ball2.stop(); 38 } 39 /* input(value) { 40 this.posStart = value; 41 }*/ 42 } 43 }; 44 </script> 45 46 <style lang="less"> 47 </style>
2.子组件
1 <template> 2 <div class="ball" :style="style" :id="ballId"></div> 3 </template> 4 5 <script> 6 export default { 7 name: "ScrollBall", 8 mounted(){ 9 let ball = document.getElementById(this.ballId); 10 //页面加载后让小球运动 11 let fn = () => { 12 let left = this.value; 13 // console.log("left:",left); 14 if(left >= this.target){ 15 return cancelAnimationFrame(this.timer); 16 } 17 // left += 5; 18 this.$emit("input",left+1); //交给父亲去改 19 this.$emit("update:value",left+1); 20 ball.style.transform = `translate(${left}px)`; 21 this.timer = requestAnimationFrame(fn); 22 } 23 this.timer = requestAnimationFrame(fn); //此函数只执行一次 24 }, 25 props: { 26 color: { 27 type: String, 28 default:"white" 29 }, 30 value:{ 31 type:Number, 32 default:0 33 }, 34 target:{ 35 type:Number, 36 default:0 37 } 38 }, 39 computed: { 40 style(){ 41 return {background:this.color} 42 }, 43 ballId(){ 44 return "ball"+this._uid; 45 } 46 }, 47 methods:{ 48 stop(){ 49 cancelAnimationFrame(this.timer); 50 } 51 } 52 }; 53 </script> 54 <style lang="less"> 55 .ball { 56 width: 100px; 57 height: 100px; 58 border: 1px solid #000; 59 border-radius: 50%; 60 box-sizing: border-box; 61 } 62 </style>
涉及的知识点:
vue-cli生成的目录结构
vue create name
node_modules 第三方包存储目录s
public 静态资源 已被托管
src 源代码
-assets 资源目路 存放静态资源
-components 存储其他组件的目录
-App.vue 根组件
-main.js 入口文件
.gitignore git 忽略文件
.vue单文件组件
template 组件的模板
注意 只有一个根节点
script 组件的js 配置组件选项
style scoped 作用域 我的样式只用于当前的组件,不加就是全局的样式
vue组件开发基本使用
scrollball
# 不用创建项目 vue 应用 # npm install -g @vue/cli-service-global
## 完了之后用vue serve
# 创建项目 vue create vue-apply
# 父组件传递背景颜色给子组件 :子组件接受颜色后,需要动态绑定 :style={background:color} 可以用计算属性 :style='stlyleComputed'
# 父组件传值的时候带上:是本身变量,不带是字符串
# 子组件修改父组件的值$emit ,父组件绑定事件用@
# 可以用requestAnmiationFrame来代替setTimeout
# 尽量通过修改父组件的数据,来跟新子组件