Vuejs2 如何使el select和v-model在提取自定义组件时协同工作
我正在使用来构建一个select组件。大概是这样的:Vuejs2 如何使el select和v-model在提取自定义组件时协同工作,vuejs2,vue-component,element-ui,Vuejs2,Vue Component,Element Ui,我正在使用来构建一个select组件。大概是这样的: <template> //omitted code <el-select v-model="filterForm.client" filterable remote placeholder="Please enter a keyword" :remot
<template>
//omitted code
<el-select v-model="filterForm.client"
filterable
remote
placeholder="Please enter a keyword"
:remote-method="filterClients"
:loading="loading">
<el-option
v-for="item in clientCandidates"
:key="item._id"
:label="item.name"
:value="item._id">
</el-option>
</el-select>
</template>
<scripts>
export default {
data() {
filterForm: {
client: ''
},
clientCandidates: [],
loading: false
},
methods: {
filterClients(query) {
if (query !== '') {
this.loading = true;
setTimeout(() => {
this.loading = false;
this.clientCandidates = [{_id: '1', name: 'foo'}, {_id: '2', name: 'bar'}];
}, 200);
} else {
this.clientCandidates = [];
}
}
}
}
</scripts>
<template>
<el-select
v-bind:value="clientId"
v-on:input="$emit('input', $event)"
placeholder="Filter by short name"
filterable="true"
remote="true"
:remote-method="filter"
:loading="loading">
<el-option
v-for="item in clients"
:key="item._id"
:label="item.name"
:value="item._id">
</el-option>
</el-select>
</template>
<scripts>
export default {
props: {
clientId: {
type: String,
required: true
}
},
data() {
return {
clients: [],
loading: false,
}
},
methods: {
filter(query) {
if (query !== '') {
this.loading = true;
setTimeout(() => {
this.loading = false;
this.clients = [{_id: '1', name: 'foo'}, {_id: '2', name: 'bar'}];
}, 200);
} else {
this.clients = [];
}
}
}
}
</scripts>
<select-client v-model="filterForm.clientId"></select-client>
相当于
v-bind:value="fullName"
v-on:input="$emit('input', $event)"
因此,我提取了选择组件,如下所示:
<template>
//omitted code
<el-select v-model="filterForm.client"
filterable
remote
placeholder="Please enter a keyword"
:remote-method="filterClients"
:loading="loading">
<el-option
v-for="item in clientCandidates"
:key="item._id"
:label="item.name"
:value="item._id">
</el-option>
</el-select>
</template>
<scripts>
export default {
data() {
filterForm: {
client: ''
},
clientCandidates: [],
loading: false
},
methods: {
filterClients(query) {
if (query !== '') {
this.loading = true;
setTimeout(() => {
this.loading = false;
this.clientCandidates = [{_id: '1', name: 'foo'}, {_id: '2', name: 'bar'}];
}, 200);
} else {
this.clientCandidates = [];
}
}
}
}
</scripts>
<template>
<el-select
v-bind:value="clientId"
v-on:input="$emit('input', $event)"
placeholder="Filter by short name"
filterable="true"
remote="true"
:remote-method="filter"
:loading="loading">
<el-option
v-for="item in clients"
:key="item._id"
:label="item.name"
:value="item._id">
</el-option>
</el-select>
</template>
<scripts>
export default {
props: {
clientId: {
type: String,
required: true
}
},
data() {
return {
clients: [],
loading: false,
}
},
methods: {
filter(query) {
if (query !== '') {
this.loading = true;
setTimeout(() => {
this.loading = false;
this.clients = [{_id: '1', name: 'foo'}, {_id: '2', name: 'bar'}];
}, 200);
} else {
this.clients = [];
}
}
}
}
</scripts>
<select-client v-model="filterForm.clientId"></select-client>
您将看到一个包含3种选择的简单页面:左侧是一个用原始选择编写的自定义组件,工作正常。
中间的一个是在
el select
中编写的自定义组件,下拉列表仍然为空,但单击Filter
按钮后,您可以在控制台中看到filterForm.elClientId
。这就是我提出这个问题的原因。右边的是一个普通的
el-select
,它工作得很好。指南说v-model
相当于v-bind:value
和v-on:input
,但是如果仔细观察,在侦听器函数中,变量binded是用事件属性设置的。您在示例中所做的不一样,在侦听器中您发出另一个事件。除非捕获此新事件,否则将永远不会设置您的值
另一件事是你不能修改道具,你应该把它看作是只读变量。< /P>
如果您想从父组件监听子组件中发出的事件,必须执行以下操作
<template>
<el-select
:value="selected"
@input="dispatch"
placeholder="Filter by short name"
:filterable="true"
:remote="true"
:remote-method="filter"
:loading="loading">
<el-option
v-for="item in clients"
:key="item._id"
:label="item.name"
:value="item._id">
</el-option>
</el-select>
</template>
<script>
export default {
name: 'SelectClient',
data() {
return {
selected: '',
clients: [],
loading: false,
}
},
methods: {
filter(query) {
if (query !== '') {
this.loading = true;
setTimeout(() => {
this.loading = false
this.clients = [{_id: '1', name: 'foo'}, {_id: '2', name: 'bar'}]
}, 200)
} else {
this.clients = []
}
},
dispatch (e) {
this.$emit('input', e)
this.selected = e
}
}
}
</script>
<template lang="html">
<select
v-model="clientId">
<option
disabled
value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
</template>
<script>
export default {
data () {
return {
clientId: ''
}
},
watch: {
clientId (newValue) {
// Do something else here if you want then commit it
// Of course, listen for the 'setClientId' mutation in your store
this.$store.commit('setClientId', newValue)
}
}
}
</script>
然后在您的其他组件中,您可以监听
$store.state.clientId
value。指南说v-model
相当于v-bind:value
和v-on:input
,但是如果您仔细观察,在侦听器函数中,binded变量是用事件属性设置的。您在示例中所做的不一样,在侦听器中您发出另一个事件。除非捕获此新事件,否则将永远不会设置您的值
另一件事是你不能修改道具,你应该把它看作是只读变量。< /P>
如果您想从父组件监听子组件中发出的事件,必须执行以下操作
<template>
<el-select
:value="selected"
@input="dispatch"
placeholder="Filter by short name"
:filterable="true"
:remote="true"
:remote-method="filter"
:loading="loading">
<el-option
v-for="item in clients"
:key="item._id"
:label="item.name"
:value="item._id">
</el-option>
</el-select>
</template>
<script>
export default {
name: 'SelectClient',
data() {
return {
selected: '',
clients: [],
loading: false,
}
},
methods: {
filter(query) {
if (query !== '') {
this.loading = true;
setTimeout(() => {
this.loading = false
this.clients = [{_id: '1', name: 'foo'}, {_id: '2', name: 'bar'}]
}, 200)
} else {
this.clients = []
}
},
dispatch (e) {
this.$emit('input', e)
this.selected = e
}
}
}
</script>
<template lang="html">
<select
v-model="clientId">
<option
disabled
value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
</template>
<script>
export default {
data () {
return {
clientId: ''
}
},
watch: {
clientId (newValue) {
// Do something else here if you want then commit it
// Of course, listen for the 'setClientId' mutation in your store
this.$store.commit('setClientId', newValue)
}
}
}
</script>
然后在您的其他组件中,您可以收听
$store.state.clientId
value.请?@JacobGoh谢谢,我已经用github示例更新了问题。我完成了您的回购,并在这里为您制作了PR>请?@JacobGoh谢谢,我用一个github示例更新了这个问题。我完成了你的回购,并在这里为你做了公关>谢谢你的回复。我试过你的代码,它不起作用。控制台告诉我未定义的selectedOptions
,我认为el select
会转换原始事件,因此事件。目标
不再存在。我对前端非常陌生,所以可能会弄错:-(只是一个注释:“this.selected=e”在中,dispatch
也是非常重要的,我相信
没有得到很好的实现,因为对于
,我不必设置这个。value=e
明确地感谢您。我一直在寻找完全相同的解决方案……我也在使用元素UI。el select组件有点混乱,因为您不知道lly是触发输入事件的el select,或el选项。事实上,我认为它们都在触发事件,但最好的方法是只查看顶层。我看了一下元素ui源代码,也有一种很好的事件传播方式,但代码可能看起来有点过于复杂,还有其他东西。也许我会当我有更多的时间时,再多写一点代码(aka..never;P)非常感谢!我正在构建一个类似的组件,突然,我发现当您通过代码删除或设置一个值时,组件本身没有刷新filterForm.clientId=null
,我指的是选择的变量
。为了修复这种情况,我必须在组件本身添加一个手表,例如下面:watch:{'value':函数(pnew,pold){if(pnew==null)this.selected=null;}
谢谢你的回复。我尝试了你的代码,但它不起作用。控制台告诉我未定义的selectedOptions
,我认为el select
转换原始事件,因此event.target
不再存在。我对前端非常陌生,因此可能会出错:-(只需注意:“this.selected=e”在中,dispatch
也是非常重要的,我相信
没有得到很好的实现,因为对于
,我不必设置这个。value=e
明确地感谢您。我一直在寻找完全相同的解决方案……我也在使用元素UI。el select组件有点混乱,因为您不知道lly是触发输入事件的el select,或el选项。事实上,我认为它们都在触发事件,但最好的方法是只查看顶层。我看了一下元素ui源代码,也有一种很好的事件传播方式,但代码可能看起来有点过于复杂,还有其他东西。也许我会当我有更多的时间时,再多写一点代码(aka..never;P)非常感谢!我正在构建一个类似的组件,突然,我发现当您通过代码删除或设置一个值时,组件本身没有刷新filterForm.clientId=null
,我指的是选择的变量
。为了修复这种情况,我必须在组件本身添加一个手表,例如下面:watch:{'value':函数(pnew,pold){if(pnew==null)this.selected=null;}}