当前位置: 首页 > wzjs >正文

慕课网站开发安徽专业网站建设设计

慕课网站开发,安徽专业网站建设设计,一站式做网站哪家好,手机网页制作图片一、组件的三大组成部分(结构/样式/逻辑) 1.组件的三大组成部分- 注意点说明 2.组件的样式冲突scoped /* 1.style中的样式 默认是作用到全局的 2.加上scoped可以让样式变成局部样式 组件都应该有独立的样式,推荐加scoped(原理) ------------…

一、组件的三大组成部分(结构/样式/逻辑)

1.组件的三大组成部分- 注意点说明

2.组件的样式冲突scoped

/*

  1.style中的样式 默认是作用到全局的

  2.加上scoped可以让样式变成局部样式

  组件都应该有独立的样式,推荐加scoped(原理)

  -----------------------------------------------------

  scoped原理:

  1.给当前组件模板的所有元素,都会添加上一个自定义属性

  data-v-hash值

  data-v-5f6a9d56  用于区分开不通的组件

  2.css选择器后面,被自动处理,添加上了属性选择器

  div[data-v-5f6a9d56]

*/

3.data 是一个函数

在 Vue 中,将 data 定义为 函数 而不是直接返回对象是 Vue 的核心设计原则之一。

BaseCount.vue

<template><div class="base-count"><button @click="count--">-</button><span>{{ count }}</span><button @click="count++">+</button></div>
</template><script>
export default {data(){return {count:999}}
}
</script><style scoped>.base-count{margin:20px;
}
</style>

App.vue

<template><div class="app"><BaseCount></BaseCount><BaseCount></BaseCount><BaseCount></BaseCount></div>
</template><script>
import BaseCount from './components/BaseCount.vue'
export default {components: {BaseCount,},
}
</script><style>
</style>

通过将 data 定义为函数,每个组件实例会通过调用 data() 获得独立的 data 对象

这样,每个组件实例的 count 都是独立的,互不干扰。


如果 data 是一个普通对象(非函数),所有组件实例会共享同一个数据对象。例如:

二、组件通信

1.什么是组件通信

2.不同的组件关系和组件通信方案分类

组件通信解决方案:

父子通信流程图:

Son.vue

<template><div style="border:3px solid #000;margin:10px"><!-- 3.直接使用props的值 -->我是Son组件 {{title}}</div>
</template><script>
export default {name: 'Son-Child',// 2.通过props来接受props:['title']
}
</script><style></style>

App.vue

<template><div class="app" style="border: 3px solid #000; margin: 10px">我是APP组件<!-- 1.给组件标签,添加属性方式 赋值 --><Son :title="myTitle"></Son></div>
</template><script>
import Son from './components/Son.vue'
export default {name: 'App',data() {return {myTitle: '世界,你好',}},components: {Son,},
}
</script><style>
</style>

 

Son.vue

<template><div class="son" style="border: 3px solid #000; margin: 10px">我是Son组件 {{ title }}<button @click="changeFn">修改title</button></div>
</template><script>
export default {name: 'Son-Child',props: ['title'],methods: {changeFn() {// 通过this.$emit() 向父组件发送通知this.$emit('changTitle','快乐星球')},},
}
</script><style>
</style>

App.vue

<template><div class="app" style="border: 3px solid #000; margin: 10px">我是APP组件<!-- 2.父组件对子组件的消息进行监听 --><Son :title="myTitle" @changTitle="handleChange"></Son></div>
</template><script>
import Son from './components/Son.vue'
export default {name: 'App',data() {return {myTitle: '世界,你好',}},components: {Son,},methods: {// 3.提供处理函数,提供逻辑handleChange(newTitle) {this.myTitle = newTitle},},
}
</script><style>
</style>


3.什么是prop

UserInfo.vue

<template><div class="userinfo"><h3>我是个人信息组件</h3><div>姓名:{{username}}</div><div>年龄:{{age}}</div><div>是否单身:{{isSingle}}</div><div>座驾:{{car.brand}}</div><div>兴趣爱好:{{hobby.join('、')}}</div></div>
</template><script>
export default {props:['username','age','isSingle','car','hobby']
}
</script><style>
.userinfo {width: 300px;border: 3px solid #000;padding: 20px;
}
.userinfo > div {margin: 20px 10px;
}
</style>

App.vue

<template><div class="app"><UserInfo:username="username":age="age":isSingle="isSingle":car="car":hobby="hobby"></UserInfo></div>
</template><script>
import UserInfo from './components/UserInfo.vue'
export default {data() {return {username: '小帅',age: 28,isSingle: true,car: {brand: '宝马',},hobby: ['篮球', '足球', '羽毛球'],}},components: {UserInfo,},
}
</script><style>
</style>

4.props 校验

BaseProgress.vue

<template><div class="base-progress"><div class="inner" :style="{ width: w + '%' }"><span>{{ w }}%</span></div></div>
</template><script>
export default {// 1.基础写法(类型校验)// props: {//   w: Number,// },// 2.完整写法(类型、默认值、非空、自定义校验)props: {w: {type: Number,required: true,  //必须传个值给我default: 0,     //没传值的默认值validator(val) {// console.log(val)if (val >= 100 || val <= 0) {console.error('传入的范围必须是0-100之间')return false} else {return true   //返回true则通过了校验,反之。}},},},
}
</script><style scoped>
.base-progress {height: 26px;width: 400px;border-radius: 15px;background-color: #272425;border: 3px solid #272425;box-sizing: border-box;margin-bottom: 30px;
}
.inner {position: relative;background: #379bff;border-radius: 15px;height: 25px;box-sizing: border-box;left: -3px;top: -2px;
}
.inner span {position: absolute;right: 0;top: 26px;
}
</style>

App.vue

<template><div class="app"><BaseProgress :w="width"></BaseProgress></div>
</template><script>
import BaseProgress from './components/BaseProgress.vue'
export default {data() {return {width: 50,}},components: {BaseProgress,},
}
</script><style>
</style>

5.prop & data、单向数据流

6.非父子通信(拓展) - event bus 事件总线

BaseA.vue

<template><div class="base-a">我是A组件(接受方)<p>{{msg}}</p>  </div>
</template><script>
import Bus from '../utils/EventBus'
export default {data() {return {msg: '',}},created() {Bus.$on('sendMsg', (msg) => {// console.log(msg)this.msg = msg})},
}
</script><style scoped>
.base-a {width: 200px;height: 200px;border: 3px solid #000;border-radius: 3px;margin: 10px;
}
</style>

BaseB.vue

<template><div class="base-b"><div>我是B组件(发布方)</div><button @click="sendMsgFn">发送消息</button></div>
</template><script>
import Bus from '../utils/EventBus'
export default {methods: {sendMsgFn() {Bus.$emit('sendMsg', '今天天气不错,适合旅游')},},
}
</script><style scoped>
.base-b {width: 200px;height: 200px;border: 3px solid #000;border-radius: 3px;margin: 10px;
}
</style>

BaseC.vue

<template><div class="base-c">我是C组件(接受方)<p>{{msg}}</p>  </div>
</template><script>
import Bus from '../utils/EventBus'
export default {data() {return {msg: '',}},created() {Bus.$on('sendMsg', (msg) => {// console.log(msg)this.msg = msg})},
}
</script><style scoped>
.base-c {width: 200px;height: 200px;border: 3px solid #000;border-radius: 3px;margin: 10px;
}
</style>

EventBus.js

import Vue from 'vue'const Bus  =  new Vue()export default Bus

App.vue

<template><div class="app"><BaseA></BaseA><BaseB></BaseB><BaseC></BaseC></div>
</template><script>
import BaseA from './components/BaseA.vue'
import BaseB from './components/BaseB.vue'
import BaseC from './components/BaseC.vue'
export default {components:{BaseA,BaseB,BaseC}
}
</script><style></style>

7.非父子通信(拓展) - provide & inject

GrandSon.vue

<template><div class="grandSon">我是GrandSon{{ color }} -{{ userInfo.name }} -{{ userInfo.age }}</div>
</template><script>
export default {inject: ['color', 'userInfo'],
}
</script><style>
.grandSon {border: 3px solid #000;border-radius: 6px;margin: 10px;height: 100px;
}
</style>

SonA.vue

<template><div class="SonA">我是SonA组件<GrandSon></GrandSon></div>
</template><script>
import GrandSon from '../components/GrandSon.vue'
export default {components:{GrandSon}
}
</script><style>
.SonA {border: 3px solid #000;border-radius: 6px;margin: 10px;height: 200px;
}
</style>

SonB.vue

<template><div class="SonB">我是SonB组件</div>
</template><script>
export default {}
</script><style>
.SonB {border: 3px solid #000;border-radius: 6px;margin: 10px;height: 200px;
}
</style>

App.vue

<template><div class="app">我是APP组件<button @click="change">修改数据</button><SonA></SonA><SonB></SonB></div>
</template><script>
import SonA from './components/SonA.vue'
import SonB from './components/SonB.vue'
export default {provide() {return {// 简单类型 是非响应式的color: this.color,// 复杂类型 是响应式的userInfo: this.userInfo,}},data() {return {color: 'pink',userInfo: {name: 'zs',age: 18,},}},methods: {change() {this.color = 'red'this.userInfo.name = 'ls'},},components: {SonA,SonB,},
}
</script><style>
.app {border: 3px solid #000;border-radius: 6px;margin: 10px;
}
</style>

三、综合案例:小黑记事本(组件版)

代码详见day04

四、进阶语法

1.v-model 原理

App.vue

<template><div class="app"><input type="text" v-model="msg1" /><br /><!-- v-model的底层其实就是:value和 @input的简写 --><input type="text" :value="msg2" @input="msg2 = $event.target.value" /></div>
</template><script>
export default {data() {return {msg1: '',msg2: '',}},
}
</script><style>
</style>

2.表单类组件封装& v-model 简化代码

BaseSelect.vue

<template><div><select :value="selectId" @change="selectCity"><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {props: {selectId: String,},methods: {selectCity(e) {this.$emit('changeCity', e.target.value)},},
}
</script><style>
</style>

App.vue

<template><div class="app"><BaseSelect:selectId="selectId"@changeCity="selectId = $event"></BaseSelect></div>
</template><script>
import BaseSelect from './components/BaseSelect.vue'
export default {data() {return {selectId: '102',}},components: {BaseSelect,},
}
</script><style>
</style>

BaseSelect.vue

<template><div><select :value="value" @change="selectCity"><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {props: {value: String,},methods: {selectCity(e) {this.$emit('input', e.target.value)},},
}
</script><style>
</style>

App.vue

<template><div class="app"><BaseSelectv-model="selectId"></BaseSelect></div>
</template><script>
import BaseSelect from './components/BaseSelect.vue'
export default {data() {return {selectId: '102',}},components: {BaseSelect,},
}
</script><style>
</style>

3.        .sync 修饰符

BaseDialog.vue

<template><div class="base-dialog-wrap" v-show="isShow"><div class="base-dialog"><div class="title"><h3>温馨提示:</h3><button class="close" @click="closeDialog">x</button></div><div class="content"><p>你确认要退出本系统么?</p></div><div class="footer"><button>确认</button><button>取消</button></div></div></div>
</template><script>
export default {props: {isShow: Boolean,},methods:{closeDialog(){this.$emit('update:isShow',false)}}
}
</script><style scoped>
.base-dialog-wrap {width: 300px;height: 200px;box-shadow: 2px 2px 2px 2px #ccc;position: fixed;left: 50%;top: 50%;transform: translate(-50%, -50%);padding: 0 10px;
}
.base-dialog .title {display: flex;justify-content: space-between;align-items: center;border-bottom: 2px solid #000;
}
.base-dialog .content {margin-top: 38px;
}
.base-dialog .title .close {width: 20px;height: 20px;cursor: pointer;line-height: 10px;
}
.footer {display: flex;justify-content: flex-end;margin-top: 26px;
}
.footer button {width: 80px;height: 40px;
}
.footer button:nth-child(1) {margin-right: 10px;cursor: pointer;
}
</style>

App.vue

<template><div class="app"><button @click="openDialog">退出按钮</button><!-- isShow.sync  => :isShow="isShow" @update:isShow="isShow=$event" --><BaseDialog :isShow.sync="isShow"></BaseDialog></div>
</template><script>
import BaseDialog from './components/BaseDialog.vue'
export default {data() {return {isShow: false,}},methods: {openDialog() {this.isShow = true// console.log(document.querySelectorAll('.box')); },},components: {BaseDialog,},
}
</script><style>
</style>

4.ref 和$refs

BaseChart.vue

<template><div class="base-chart-box" ref="baseChartBox">子组件</div>
</template><script>
import * as echarts from 'echarts'export default {mounted() {// 基于准备好的dom,初始化echarts实例// document.querySelector 会查找项目中所有的元素// $refs只会在当前组件查找盒子// var myChart = echarts.init(document.querySelector('.base-chart-box'))var myChart = echarts.init(this.$refs.baseChartBox)// 绘制图表myChart.setOption({title: {text: 'ECharts 入门示例',},tooltip: {},xAxis: {data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],},yAxis: {},series: [{name: '销量',type: 'bar',data: [5, 20, 36, 10, 10, 20],},],})},
}
</script><style scoped>
.base-chart-box {width: 400px;height: 300px;border: 3px solid #000;border-radius: 6px;
}
</style>

App.vue

<template><div class="app"><div class="base-chart-box">这是一个捣乱的盒子</div><BaseChart></BaseChart></div>
</template><script>
import BaseChart from './components/BaseChart.vue'
export default {components:{BaseChart}
}
</script><style>
.base-chart-box {width: 300px;height: 200px;
}
</style>

BaseForm.vue

<template><div><label>账号:<input type="text" v-model="account" /></label><br /><label>密码:<input type="password" v-model="password" /></label><br /><button @click="getFormData">获取数据</button><button @click="resetForm">重置数据</button></div>
</template><script>
export default {data() {return {account: '',password: ''};},methods: {getFormData() {console.log('组件内获取到的账号:', this.account);console.log('组件内获取到的密码:', this.password);},resetForm() {this.account = '';this.password = '';console.log('子组件:表单已重置');}}
};
</script>
  • 模板(<template>
    • 定义了一个包含两个输入框(账号和密码)及两个按钮(“获取数据” 和 “重置数据”)的表单。
    • v-model="account" 和 v-model="password" 实现输入框与组件数据 accountpassword 的双向绑定,输入内容实时同步到对应数据。
    • 按钮通过 @click 绑定方法 getFormData 和 resetForm,点击时触发对应操作。
  • 脚本(<script>
    • data 函数返回组件的响应式数据 account 和 password,用于存储输入框内容。
    • getFormData 方法:打印当前输入的账号和密码,模拟获取表单数据的业务逻辑。
    • resetForm 方法:将 account 和 password 重置为空字符串,清空输入框,并打印提示信息。

App.vue

<template><div><BaseForm ref="baseForm" /><button @click="callChildComponentMethod">父组件调用子组件方法</button></div>
</template><script>
import BaseForm from './components/BaseForm.vue'; // 确保路径正确export default {components: {BaseForm},methods: {callChildComponentMethod() {// 通过 $refs 获取子组件实例const formComponent = this.$refs.baseForm;if (formComponent) {// 调用子组件的方法formComponent.getFormData(); // 输出子组件内获取的数据formComponent.resetForm(); // 调用子组件的重置方法}}}
};
</script>
  • 模板(<template>
    • 使用 <BaseForm ref="baseForm" /> 引入子组件,并通过 ref="baseForm" 为子组件实例命名,便于父组件获取。
    • 定义一个按钮,点击时触发 callChildComponentMethod 方法。
  • 脚本(<script>
    • 先通过 import 引入子组件 BaseForm,再在 components 选项中注册,确保模板中可使用 <BaseForm> 标签。
    • callChildComponentMethod 方法:
      • 通过 this.$refs.baseForm 获取子组件实例(ref 注册的名称需与 $refs 访问的名称一致)。
      • 若实例存在,调用子组件的 getFormData 和 resetForm 方法,实现父组件控制子组件行为(如获取表单数据、重置表单)。

整体功能

  • 子组件 BaseForm.vue 实现了一个简单的表单交互,包含数据输入、获取和重置功能。
  • 父组件通过 ref 和 $refs 获取子组件实例,直接调用子组件方法,实现跨组件的逻辑控制,体现了 Vue 中父组件访问子组件实例及方法的能力。

5.Vue异步更新、$nextTick

需求

编辑标题, 编辑框自动聚焦

  • 点击编辑,显示编辑框

  • 让编辑框,立刻获取焦点

<template><div class="app"><div v-if="isShowEdit"><input type="text" v-model="editValue" ref="inp" /><button>确认</button></div><div v-else><span>{{ title }}</span><button @click="editFn">编辑</button></div></div>
</template><script>
export default {data() {return {title: '大标题',isShowEdit: false,editValue: '',}},methods: {editFn() {// 显示输入框this.isShowEdit = true  // 获取焦点this.$refs.inp.focus() }  },
}
</script> 

问题

"显示之后",立刻获取焦点是不能成功的!

原因:Vue 是异步更新DOM (提升性能)

解决方案

$nextTick:等 DOM更新后,才会触发执行此方法里的函数体

语法: this.$nextTick(函数体)

this.$nextTick(() => {this.$refs.inp.focus()
})

注意:$nextTick 内的函数体 一定是箭头函数,这样才能让函数内部的this指向Vue实例

<template><div class="app"><div v-if="isShowEdit"><input type="text" v-model="editValue" ref="inp" /><button>确认</button></div><div v-else><span>{{ title }}</span><button @click="editFn">编辑</button></div></div>
</template><script>
export default {data() {return {title: '大标题',isShowEdit: false,editValue: '',};},methods: {editFn() {// 显示输入框this.isShowEdit = true;// 获取焦点this.$nextTick(() => {this.$refs.inp.focus();});},},
};
</script>    


文章转载自:

http://tZUi2k0j.rsszk.cn
http://qx99aHFK.rsszk.cn
http://yK6tIxMV.rsszk.cn
http://qrGJtsvm.rsszk.cn
http://cuJgr0b3.rsszk.cn
http://XSDijZiF.rsszk.cn
http://2iuIdfwz.rsszk.cn
http://09FgDtcD.rsszk.cn
http://HZW8HKe1.rsszk.cn
http://P6HzoALI.rsszk.cn
http://Ir7oJGVq.rsszk.cn
http://COIfUPLH.rsszk.cn
http://0eNJgWuI.rsszk.cn
http://eOXKQ2c3.rsszk.cn
http://v3862DLp.rsszk.cn
http://g449sS08.rsszk.cn
http://94pGXvGb.rsszk.cn
http://sgYRAcrd.rsszk.cn
http://DN3AFBfv.rsszk.cn
http://W28aaoph.rsszk.cn
http://9BOvq8pq.rsszk.cn
http://AbLhfROY.rsszk.cn
http://bWAkUOvY.rsszk.cn
http://UiWZXdEs.rsszk.cn
http://sNFKqRJw.rsszk.cn
http://VPhZwe27.rsszk.cn
http://ihE8Dz0D.rsszk.cn
http://nx96OTFO.rsszk.cn
http://k3oUVOWf.rsszk.cn
http://bb1NaQLP.rsszk.cn
http://www.dtcms.com/wzjs/731864.html

相关文章:

  • 为什么我有的网站打不开多语网站wordpress子站点
  • 培训学校网站模板诸塈市建设局网站
  • 福州网站排名推广黄冈网站建设有哪些
  • 网站建设公司需要哪些百度怎么推广网站
  • 个人淘宝客网站东莞微网站
  • 网页标准化对网站开发维护者的好处为网站做电影花絮
  • 陕西专业网站建设宝宝发烧反反复复什么原因导致的
  • 三亚网站建设品牌浦东新区建设工程安全质量监督站网站
  • 企业网页设计模板素材网站快速优化排名
  • 河间网站建设公司河南城乡住房和建设厅网站
  • 甘肃省城乡建设厅网站首页网页设计与制作教程第六版答案
  • 建网站做点什么好做宠物网站需要实现什么功能
  • flash互动网站开发app制作平台灼灼琉璃夏漫画
  • 专做机票网站的软件公司可以做手机网页的网站
  • 怎么做二维码进入公司网站网站开发寻找潜在客户的途径
  • 管理外贸网站模板下载徐州关键词优化
  • 做网站在什么地方发帖子呢wordpress 模版 怎么用
  • 市住房城乡建设网站网页图片设计
  • 知乎营销平台东莞seo建站优化费用
  • 甘肃省城市建设档案馆网站济南招聘网最新招聘
  • 濮阳做网站优化app开发公司招聘
  • 梵客家装公司简介青岛网站seo推广
  • 银河互联网电视有限公司吕梁seo网站建设
  • 沧州网站建设的公司沈阳网站优化排名
  • 购买虚拟机建网站如何删除wordpress
  • ps怎么做网站设计网站开发税率是多少
  • 响应式网站和展示式区别wordpress写入权限
  • 美食网站代做申请建设网站经费申请
  • 湖南省政务服务网 网站建设要求那个软件可以做三个视频网站
  • 网站开发用什么电脑网站免费的