我的模板中有这个代码:
<div class="input-field col s6">
<select v-on:change="selectChaned" v-model="item.size">
<option value="" disabled selected>Choose your option</option>
<option v-on:click="optionClicked" v-for="size in case_sizes" v-bind:value="{{ size }}">{{ size }}</option>
</select>
<label for="size">Size</label>
</div>
根据Materialisecss文档,我调用$('select').material_select();
将默认选择字段转换为可爱的字段。它的作用是什么 - 它用<select>
和<option>
替换<ul>
和<li>
标签。
因此,我无法在ViewModel js文件中访问 item.size 的值。我甚至试图听一下选项字段的点击并调用optionClicked方法(这应该只是提醒一条消息),试图听取selectChaned。什么都没有。
如何在ViewModel中获取选项值?
P.S。仅供参考:我只对选择字段有疑问。例如,输入字段工作正常:
<input placeholder="" name="name" type="text" class="validate" v-model="item.name">
在ViewModel中,我可以访问item.name
答案 0 :(得分:11)
似乎Materialise不会发送任何事件,所以我找不到一个优雅的解决方案。但似乎以下Vuejs指令+ jQuery解决方法正在起作用:
Vue.directive("select", {
"twoWay": true,
"bind": function () {
$(this.el).material_select();
var self = this;
$(this.el).on('change', function() {
self.set($(self.el).val());
});
},
update: function (newValue, oldValue) {
$(this.el).val(newValue);
},
"unbind": function () {
$(this.el).material_select('destroy');
}
});
然后在你的HTML中 - bind&lt; select&gt;使用v-select而不是v-model。
答案 1 :(得分:7)
Vue.js 2.0
<强>模板:强>
<div v-text="selected"></div>
<material-select v-bind="selected = selected || options[0].value" v-model="selected">
<option v-for="option in options" :value="option.value" v-text="option.name"></option>
</material-select>
<强>组件:强>
"use strict";
Vue.component("material-select", {
template: '<select><slot></slot></select>',
props: ['value'],
watch: {
value: function (value) {
this.relaod(value);
}
},
methods:{
relaod : function (value) {
var select = $(this.$el);
select.val(value || this.value);
select.material_select('destroy');
select.material_select();
}
},
mounted: function () {
var vm = this;
var select = $(this.$el);
select
.val(this.value)
.on('change', function () {
vm.$emit('input', this.value);
});
select.material_select();
},
updated: function () {
this.relaod();
},
destroyed: function () {
$(this.$el).material_select('destroy');
}
});
答案 2 :(得分:2)
Vue.directive('material-select', {
bind:function(el,binding,vnode){
$(function () {
$(el).material_select();
});
var arg = binding.arg;
if(!arg)arg="change";
arg = "on"+arg;
el[arg]=function() {
if (binding.expression) {
if (binding.expression in vnode.context.$data) {
vnode.context.$data[binding.expression] = el.value;
} else if (vnode.context[binding.expression] &&
vnode.context[binding.expression].length <= 1) {
vnode.context[binding.expression](el.value);
} else {
throw new Error('Directive v-' + binding.name + " can not take more than 1 argument");
}
}
else {
throw new Error('Directive v-' + binding.name + " must take value");
}
}
},
unbind:function(el) {
$(el).material_select('destroy');
}
});
new Vue({
el: '#exemple1',
data:function(){
return {
selected: '',
options:[
{value:"v1",text:'description 1'},
{value:"v2",text:'description 2'},
{value:"v3",text:'description 3'},
{value:"v4",text:'description 4'},
{value:"v5",text:'description 5'},
]
}
}
});
new Vue({
el: '#exemple2',
data:function() {
return{
selected: null,
options:[
{value:"v1",text:'description 1'},
{value:"v2",text:'description 2'},
{value:"v3",text:'description 3'},
{value:"v4",text:'description 4'},
{value:"v5",text:'description 5'},
]
}
},
methods:{
change:function(value){
this.selected = value;
alert(value);
}
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/js/materialize.min.js"></script>
<h4>vue js materialize</h4>
<h5>Exemple1</h5>
<div id="exemple1">
<select v-material-select:change="selected" class="blue-text">
<option value="" disabled selected ><slot>Defaut message</slot></option>
<option v-for="option in options" :value="option.value">{{ option.text}}</option>
</select>
</div>
<h5>Exemple2</h5>
<div id="exemple2">
<select v-material-select:change="change" class="blue-text">
<option disabled selected ><slot>Choisir Votre Abonnement</slot></option>
<option v-for="option in options" :value="option.value">{{ option.text}}</option>
</select>
</div>
答案 3 :(得分:2)
最佳答案很好,但对Vue 2不起作用。
这是一个有效的更新(可能仍然有点hacky)。我将jQuery挂钩移动到update()
,因为bind
函数调用太早,无法实现。
Vue.directive("select", {
"twoWay": true,
update: function(el, binding, vnode) {
if(!vnode.elm.dataset.vueSelectReady) {
$(el).on('change', function() {
vnode.context.$set(vnode.context, binding.expression, el.value);
});
$(el).material_select();
vnode.elm.dataset.vueSelectReady = true
}
},
unbind: function(el, binding, vnode) {
$(el).material_select('destroy');
}
});
HTML:
<select v-select=selected>
<option value="" disabled selected>Choose your option</option>
<option :value="item" v-for='item in items'>{{ item }}</option>
<label>Materialize Select</label>
</select>
答案 4 :(得分:1)
您可以通过简单的技巧在Vue + Materializecss中进行动态选择
$('#select').val(1).material_select(); // Set value and reinitialize materializecss select
mounted () {
$("#select").change(function(){
this.update_result.category = $("#select").val();
}.bind(this)); // To set the user selected value to the data property
update_result.
}
如果您使用meterializecss beta版本,则用于初始化选择的函数名称将有所不同。
答案 5 :(得分:0)
我有类似的问题。这里的问题是,只有在Vue应用程序的DOM准备就绪后才需要发出$('select').material_select();
。因此,您可以为Vue应用添加一个就绪方法,并在准备好的方法中包含$('select').material_select();
。
var vm = new Vue({
data: function() {
locations: ["Clayton", "Mt Meigs", "Birmingham", "Helena", "Albertville", "Albertville", "Grant"]
},
ready: function() {
$('select').material_select();
}});
确保首先包含Jquery,然后在html文件中包含materialize.js后跟Vue.js。
答案 6 :(得分:0)
我想要包含我为我的项目构建的自定义select2指令的工作小提琴。它还支持多种选择: fiddle
data: function() {
return {
names: [
{id: 1, value: 'Alice'},
{id: 1, value: 'Bob'},
{id: 1, value: 'Simona'}
],
myStudents: {
names: ['Alice', 'Bob'],
}
}
},
directives: {
'select': {
twoWay: true,
params: ['options'],
bind: function () {
var self = this
$(this.el).select2().on('change', function() {
self.set($(self.el).val())
})
},
update: function (value) {
$(this.el).val(value).trigger('change')
},
},
},
<select multiple v-select="myStudents.names" name="names" v-model="myStudents.names">
<option v-for="name in names" value="{{ name.value }}">{{ name.value }}</option>
</select>
答案 7 :(得分:0)
v- VueJs2.4 上述答案都不是针对多个选择元素的。我通过遍历select元素选项来实现它。这不是一个正确的方法和一种黑客,但有效。
<h4>vue js materialize select</h4>
<div class="row" id="app" style="padding-bottom:2em;">
<div class="input-field col s12 m8">
<select multiple v-material-select:change="selected">
<option value="AngularJs">AngularJs</option>
<option value="Bootstrap3">Bootstrap3</option>
<option value="Bootstrap4">Bootstrap4</option>
<option value="SCSS">SCSS</option>
<option value="Ionic">Ionic</option>
<option value="Angular2">Angular2</option>
<option value="Angular4">Angular4</option>
<option value="React">React</option>
<option value="React Native">React Native</option>
<option value="Html5">Html5</option>
<option value="CSS3">CSS3</option>
<option value="UI/UX">UI/UX</option>
</select>
<label>Technologies Used</label>
</div>
<h2>Your selected options</h2>
<p>{{$data.selected}}</p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script src="https://unpkg.com/vue@2.4.4/dist/vue.js"></script>
<script> Vue.directive("material-select", {
bind: function(el, binding, vnode) {
$(function() {
$(el).material_select();
});
var arg = binding.arg;
if (!arg) arg = "change";
arg = "on" + arg;
el[arg] = function() {
vnode.context.$data.selected = [];
for (let i = 0; i < 12; i++) {
if (el[i].selected === true) {
vnode.context.$data.selected.push(el[i].value);
}
}
};
},
unbind: function(el) {
$(el).material_select("destroy");
}
});
var app = new Vue({el: "#app",data: { selected: []},
ready: function() {
$("select").material_select(); }});</script>
答案 8 :(得分:0)
我找到的可能解决方案是使用输入,并将其附加到下拉内容。即使在动态创建下拉列表时,它也适用于vue。并且它具有反应性,您不必发出任何其他事件来绑定值。
Codepen:https://codepen.io/aaha/project/editor/DGJNLE
<style>
input{
cursor: pointer;
}
.caret{
float:right;
position: relative;
cursor: pointer;
top:-50px;
}
ul{
width: 100%;
}
</style>
<script>
Vue.component('paper-dropdown', {
template: '<div> \
<div class="input-field">\
<input type="text" class="dropdown-button" v-bind:data-activates="_id"\
v-bind:value="value"> \
<label>{{label}}</label> \
</div> \
<i class="material-icons caret">arrow_drop_down</i>\
<ul v-bind:id="_id" class="dropdown-content"> \
<li v-for="item in options" v-on:click="setselected"><a v-bind:value="item">{{item}}</a></li> \
</ul>\
</div>',
watch: {
value: function(){
Materialize.updateTextFields();
}
},
computed:{
_id: function(){
if(this.id != null) return this.id;
return Math.random().toString(36).substr(2);
}
},
props: {
label:{
type: [String, Number],
default: ''
},
options:{
type: Array,
default: []
},
placeholder:{
type: String,
default: 'Choose your option'
},
value:{
type: String,
default: ''
},
id:{
type: String,
default: 'me'
}
},
methods:{
setselected: function(e){
this.$emit('input', e.target.getAttribute("value"));
}
},
mounted: function(){
$('.dropdown-button').dropdown({
inDuration: 300,
outDuration: 225,
constrainWidth: false, // Does not change width of dropdown to that of the activator
hover: false, // Activate on hover
gutter: 0, // Spacing from edge
belowOrigin: false, // Displays dropdown below the button
alignment: 'left', // Displays dropdown with edge aligned to the left of button
stopPropagation: false // Stops event propagation
}
);
}
});
</script>
答案 9 :(得分:0)
我做了一些简单得多的事情,只是在安装好的情况下:
....
mounted() {
$(this.$el)
.find(".mdb-select")
.material_select();
const self = this;
$(this.$el).on("change", function(e) {
self.$emit('input', this.inputValue);
});
},
.....