【IMWeb训练营作业】select

时间:2022-08-09 21:58:40

前言

通过这几天的学习我又加深了对Vue的了解,例如Vue组件的作用、使用props传递数据,特殊is属性扩展原生html元素,v-bind动态绑定数据,利用自定义事件通信,单向数据流等一些内容。

这次的作业就是对上面知识的一个综合应用,下面就是运行效果图:

【IMWeb训练营作业】select

下面是核心代码

<div id="app">
<div style="float: left;">
<h2>选择省份下拉框</h2>
<custom-select btn="省份" :list="list1"></custom-select>
</div>
<div style="float:left;">
<h2>选择市区下拉框</h2>
<custom-select btn="市区" :list="list2"></custom-select>
</div>
</div>
<script type="text/javascript">
Vue.component('custom-select', {
data() {
return {
selectShow:false,
val:''
}
},
props:['btn','list'],
template:`<section class="warp">
<div class="searchIpt clearFix">
<div class="clearFix">
<input type="text" class="keyWord" :value="val" @click="selectShow = !selectShow" />
<input type="button" :value="btn">
<span></span>
</div>
<custom-list
v-show="selectShow"
:list="list"
v-on:receive="changeValueHandle"
>
</custom-list>
</div>
</section>`,
methods: {
changeValueHandle(value) {
this.val = value;
}
}
});
Vue.component('custom-list', {
props:['list'],
template:`<ul class="list">
<li v-for="item of list" @click="selectValueHandle(item)">{{item}}</li>
</ul>`,
methods: {
selectValueHandle(item) {
this.$emit('receive', item);
}
}
})
new Vue({
el: '#app',
data: {
list1:["北京","上海","广州","深圳"],
list2:["东城区","西城区","朝阳区","丰台区","海淀区","石景山区"]
}
})
</script>

这些知识算是对Vue的一个进阶学习吧,来谈谈我对这些知识的理解吧

组件

Vue的组件吸收了React里面的组件思想,而组件的设计初衷就是为了增加代码的复用性,定义了一个全局组件后,就可以在页面的任何地方都可以使用,简洁高效,非常方便。谈到组件,就不得不说组件之间的通信了,

组件的通信

父组件到子组件

组件之间的通信无外非两种,父子组件的通信,和非父子组件之间的通信,这次我主要讲父子组件的通信。组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,我们需要通过子组件的props选项。props的作用就是可以把父组件上的数据传递到子组件,然后子组件根据父组件传递的不同的内容渲染成不同的效果。

为什么会有props这个选项,之前谈到组件是为了增加代码的复用性,可以在页面的任何地方使用,但是有时我们在做项目的时候经常会遇到两个非常相似的组件,知识里面某处内容不一样,如果为了实现这个效果定义两个非常类似的组件就会增加代码的冗余,这是不理想的,那么有什么办法,可以让子组件里面的代码随着父组件上绑定的不同参数而实现这种效果呢?props就是这样的作用,他可以把父组件上定义的一个自定义属性绑定到子组件上,props里面的值和这个自定义属性名称一样即可。在模板中,要动态地绑定父组件的数据到子模板的props,与绑定到任何普通的HTML特性相类似,就是用 v-bind。每当父组件的数据变化时,该变化也会传导给子组件

子组件到父组件

上面说到,父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,应该怎样做?那就是自定义事件!首先在父组件上使用v-on指令绑定自定义事件,然后在子组件中使用 $emit(eventName,参数) 触发事件,这个eventName就是自定义事件的名称,参数就是可以传递给父组件的数据。

特殊is属性扩展原生html元素

有时候我们需要把某个组件定义在html标签内,但是总所周知,有些html标签符合W3C标准,只可以嵌套某些指定的标签,如ul里只可以嵌套li标签,table里只可以嵌套thead、tbody,tr、td之类的标签,这个时候如果把组件嵌套在这些特俗标签里,那么在页面渲染的时候,就不会把这个组件的内容渲染在这些标签里面,而是在外面,那么这个时候怎么办呢,一种就是尽量避免在这些特殊标签嵌套组件,还有就是使用Vue提供的is属性来扩展原生html元素,用法就是is属性里面的值是组件的名称,这样就可以渲染成功了。

单向数据流

prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop 。如果你这么做了,虽然可能会达到效果,但是Vue 会在控制台给出警告。这个时候如果想修改props,有两种方法:
1. 定义一个局部变量,并用 prop 的值初始化它:

props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}

我们可以通过这个修改this.initialCounter这个方法来达到修改props的目的,这样就不会在子组件里修改props,也可以实现我们想要的效果
2. 定义一个计算属性,处理 prop 的值并返回。

props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}

后记

路漫漫其修远兮,吾将上下而求索。。。