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>

 

posted on 2021-12-16 19:00  hi-gdl  阅读(23)  评论(0编辑  收藏  举报

导航