VUE实现双向绑定
绑定文本框
用React写一个文本框:
class TextBox extends Component { constructor(props) { super(props); this.state = { txtValue: 'hello world' }; this.setTxtValue = this.setTxtValue.bind(this); } setTxtValue(e) { this.setValue({txtValue: e.target.value}) } render() { return ( <div> <input type="text" onChange={this.setTxtValue} value={this.state.txtValue} /> </div> ) }}
为了取数据要专门写个事件处理,还要bind,很啰嗦,要是来十个文本框,手指受不了,眼睛也受不了。
让我们看看VUE的伟大吧
<template> <div> <input type="text" v-mode="txtValue"> </div></template><script>export default { data() { return { txtValue: 'hello world' } }}</script>
一眼就看到底了,爽得不要不要的。
入了门就看个更有趣的例子,做个问卷调查:
既然是数据驱动,就先设计一下数据模型:
sessions:[ // 每个问题及选项称为一个session { question: '3. Which langurage are you using?', //问题文本 type: 'checkbox', // 问题类型,单选、多选 answer: [], // 多选题答案 value: '', // 单选题答案 errMsg: '', // 错误信息 options: [ // 答案的选项 { label: 'Java', value: '1', }, ... // 更多的选项 ] }, ... // 更多的session ]
设计一个组件,显示session
<template> <div class="question"> <div><label>{{session.question}} -- {{session.answer}}</label></div> <div v-if="session.type === 'checkbox'"> <div v-for="(option, okey, oidx) in session.options" :key="oidx"> <label> <input :type="session.type" v-model="session.answer" :value="option.value" /> {{option.label}} </label> </div> </div> <div v-if="session.type === 'radio'"> <div v-for="(option, okey, oidx) in session.options" :key="oidx"> <label> <input :type="session.type" v-model="session.value" :value="option.value" @change="handleRadio(session)" /> {{option.label}} </label> </div> </div> <div class="err-msg">{{session.errMsg}}</div> </div></template><script>export default { props: ['session'], methods: { handleRadio(session) { session.answer = [ session.value ] }, }}</script>
接收并显示一个session,会根据session的类型做不同的绑定:
类型是多选时,input的值绑定到session.answer,结果是一个数组,例如 ['1','2']类型是单选时,input的值绑定到session.value,结果是一个值,如'1'。为了统一效果,加了一个处理将单选的结果也放入session.answer,例如 ['1']我们引入vuex作为全局的状态管理:
Vue.use(Vuex);var state = { sessions: [ { question: '3. Which langurage are you using?', type: 'checkbox', answer: [], value: '', errMsg: '', options: [ { label: 'Java', value: '1', }, { label: 'python', value: '2', }, { label: 'C', value: '3', }, { label: 'swift', value: '4', }, ] }, ... ]}var actions = { submitAnswer({ commit, state }) { ... }}const store = new Vuex.Store({ state, actions})export default store;
用过Redux的同学看出端倪了吗?不用dispatch,不用reducer,store里面的数据直接绑定在组件上,一旦变化,马上触发UI更新,省去了很多无聊的代码。还有,即使是store里面深层的数据发生变化,vue可以很自然地监察,然后更新页面。不像React,要析构赋值或者combineReducer。
接下来只要再来一段,引入组件,循环使用
<template> <div v-for="(session, key, idx) in $store.state.sessions" :key="idx"> <Session :session="session"></Session> </div></template><script>import Session from '../session';export default { components: { Session },}</script>
就可以做出以下的效果了
在VUE中,dispatch用于触发异步action,例如提交数据等,这里只讨论数据绑定。
相对于React,VUE的数据绑定减少了冗余的代码,让开发者可以更专注于业务。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。