Vue笔记2
<!-- 计算属性 computed https://www.runoob.com/vue2/vue-computed.html --> <div id="app"> <p>原始字符串: {{ message }}</p> <!-- 获取计算后的属性(用于复杂逻辑) --> <p>computed计算后反转字符串: {{ reversedMessage1 }}</p> <!-- 我们可以使用 methods 来替代 computed,效果上两个都是一样的, 但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。 而使用 methods ,在重新渲染的时候,函数总会重新调用执行 --> <p>methods计算后反转字符串: {{ reversedMessage2() }}</p> </div> <script> var vm = new Vue({ el: '#app', data: { name: 'Google', message: 'Runoob!' }, methods: { reversedMessage2: function () { return this.message.split('').reverse().join('') } }, computed: { // 计算属性的 getter reversedMessage1: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') }, site : { get:function(){//默认只有 getter return this.name + ':' + this.message ; } set:function(newValue){// 手动提供一个 setter var vals = newValue.split(' '); this.name = vals[0] this.message = vals[ vals.length - 1] } } } }) </script> <!-- 监听属性watch https://www.runoob.com/vue2/vue-watch.html --> <div id = "computed_props"><!-- 千米与米之间的换算示例 --> 千米 : <input type = "text" v-model = "kilometers"> 米 : <input type = "text" v-model = "meters"> </div> <p id="info"></p> <script type = "text/javascript"> var vm = new Vue({ el: '#computed_props', data: { kilometers : 0, meters:0 }, watch : { kilometers:function(val) { this.kilometers = val; this.meters = this.kilometers * 1000 ; }, meters : function (val) { this.kilometers = val/ 1000; this.meters = val; } } }); // $watch 是一个实例方法 vm.$watch('kilometers', function (newValue, oldValue) { // 这个回调将在 vm.kilometers 改变后调用 document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue; }) </script> <!-----------------------------------------------------> <!-- 表单 表单双向绑定 --> <div id="app"> <!-- 文本框 --> <p>input 元素:</p> <input v-model="message" placeholder="编辑我……"> <p>消息是: {{ message }}</p> <p>textarea 元素:</p> <p style="white-space: pre">{{ message2 }}</p> <textarea v-model="message2" placeholder="多行文本输入……"></textarea> <hr> <!-- 单选框与复选框 --> <p>单个复选框:</p> <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label> <p>多个复选框:</p> <input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames"> <label for="runoob">Runoob</label> <input type="checkbox" id="google" value="Google" v-model="checkedNames"> <label for="google">Google</label> <input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames"> <label for="taobao">taobao</label> <br> <span>选择的值为: {{ checkedNames }}</span> </div> <hr> <!-- select下拉框 --> <select v-model="selected" name="fruit"> <option value="">选择一个网站</option> <option value="www.runoob.com">Runoob</option> <option value="www.google.com">Google</option> </select> <div id="output"> 选择的网站是: {{selected}} </div> <script> new Vue({ el: '#app', data: { message: 'Runoob', message2: '菜鸟教程\r\nhttp://www.runoob.com' , checked : false, checkedNames: [], selected : '' } }) </script> <!-- 关于表单修饰符 TODO 待详细了解 --> <!-- 在 "change" 而不是 "input" 事件中更新 --> <input v-model.lazy="msg" > <!-- 自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值) --> <input v-model.number="age" type="number"> <!-- 过滤用户输入的首尾空格 --> <input v-model.trim="msg"> <!-----------------------------------------------------> <!-- 组件 element ui中使用了大量el开头的标签 , 可能是通过此种方法实现 --> <div id="app"> <runoob></runoob> <child message="hello!"></child> </div> <script> //导入全局组件 import Editor from "@/components/Editor" // 富文本组件 Vue.component('Editor', Editor); // 注册 Vue.component('child', { // 声明 props , 用来声明参数名称 props: ['message'],//prop 是子组件用来接受父组件传递过来的数据的一个自定义属性 // 同样也可以在 vm 实例中像 "this.message" 这样使用 template: '<span>{{ message }}</span>' }); var Child = {//即将应用于实例的组件 template: '<h1>自定义组件!</h1>' } new Vue({// 创建根实例 el: '#app', components: { // <runoob> 将只在父模板可用 'runoob': Child } }); </script> <!-- 组件 : 动态 Prop 和 Prop 验证 参考 : https://www.runoob.com/try/try.php?filename=vue2-component4 https://www.runoob.com/try/try.php?filename=vue2-component5 --> <div id="app"> <div> <input v-model="parentMsg"> <br> <!-- child 是一个自定义的组件标签,上面文本框中的值将动态传入到child组件中 --> <child v-bind:message="parentMsg"></child> </div> <ol> <todo-item v-for="item in sites" v-bind:todo="item"></todo-item> </ol> </div> <script> // 注册 Vue.component('child', { // 声明 props props: ['message'], // 同样也可以在 vm 实例中像 "this.message" 这样使用 template: '<span>{{ message }}</span>' }) // 创建根实例 new Vue({ el: '#app', data: { parentMsg: '父组件内容' , sites: [ { text: 'Runoob' }, { text: 'Google' }, { text: 'Taobao' } ] } }); <!-- Prop 验证 传值类型包含以下 : String,Number,Boolean,Array,Object,Date,Function,Symbol 也可以使用validator自定义验证参数 --> Vue.component('my-component', { props: { // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证) propA: Number, // 多个可能的类型 propB: [String, Number], // 必填的字符串 propC: { type: String, //type 也可以是一个自定义构造器,使用 instanceof 检测 required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function () { return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function (value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } } } }) </script> <!-----------------------------------------------------> <!-- 组件自定义事件 (子组件要把数据传递回去,需要使用自定义事件) 使用 $on(eventName) 监听事件 (另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件) 使用 $emit(eventName) 触发事件 https://www.runoob.com/vue2/vue-component-custom-event.html --> <div id="app"> <div id="counter-event-example"> <p>{{ total }}</p> <!-- this.$emit('increment') 触发父组件的事件 --> <button-counter v-on:increment="incrementTotal"></button-counter> <button-counter v-on:increment="incrementTotal"></button-counter> </div> </div> <script> //看起来 Vue.component 的结构有点类似 , 有data ,有methods (待了解组件参数) Vue.component('button-counter', { template: '<button v-on:click="incrementHandler">{{ counter }}</button>', data: function () { return {//这样的好处就是每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例 counter: 0 } }, methods: { incrementHandler: function () { this.counter += 1 ;//this.counter 两个button-counter组件,每个组件的counter都是独立的 this.$emit('increment') ;//触发increment对应的父组件事件 } }, }) new Vue({ el: '#counter-event-example', data: { total: 0 }, methods: { incrementTotal: function () { this.total += 1 } } }) </script> <!-- native修饰符用来监听原生事件--> <my-component v-on:click.native="doTheThing"></my-component> <!-- 自定义组件的 v-model https://www.runoob.com/try/try.php?filename=vue2-component8 <input v-model="parentData"> 等价于 <input :value="parentData" @input="parentData = $event.target.value"> v-bind: 缩写 : v-on:click缩写@ --> <div id="app"> <runoob-input v-model="num"></runoob-input> <p>输入的数字为:{{num}}</p> </div> <script> Vue.component('runoob-input', { template: ` <p> <!-- 包含了名为 input 的事件 --> <input ref="input" :value="value" @input="$emit('input', $event.target.value)" > </p> `, props: ['value'], // 名为 value 的 prop }) new Vue({ el: '#app', data: { num: 100, } }) </script>