Vue照着文档巧的一些案例 包括组件。。。

slot

slot 将html传递给组件

<div id="app1">
    <navigation-link url="/profile">
        <p class="fa fa-user"> 测试 p 标签 其他组件</p>

        <custom-input v-model="searchText"></custom-input>
        Your Profile
    </navigation-link>

</div>

<script>
Vue.component('navigation-link', {
    props: ['url'],
  template: `
        <a
        v-bind:href="url"
        class="nav-link"
        >
        <slot></slot>
        </a>
    `}
    )

Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})


new Vue({
    el:'#app1',
    data:{
      searchText: ''
    }

})
</script>

组件

官方写那么短是真的是很有用,这么长我粘贴完了也不怎么想看了。。有时间还是看官方文档吧,多敲敲代码

prop

<body>

    <div id="prop-example">
        <base-input
        label="Username:"
        v-model="username"
        required
        placeholder="Enter your username"
        ></base-input>
    </div>
</body>


<!-- -------------------------------------------------------------------------------------------------------------------------------- -->

<script>
Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on:input="$emit('input', $event.target.value)"
      >
    </label>
  `
})
new Vue({
    el:'#prop-example'
})
</script>

v-for

组件和v-for配合遍历


<body>

    <div id="todo-list-example">
        <!-- preventDefault() 方法阻止元素发生默认的行为(例如,当点击提交按钮时阻止对表单的提交) -->
        <form v-on:submit.prevent="addNewTodo">
          <label for="new-todo">Add a todo</label>
          <input
            v-model="newTodoText"
            id="new-todo"
            placeholder="E.g. Feed the cat"
          >
          <button>Add</button>
        </form>
        <ul>
            <!-- splice() 方法向/从数组添加/删除项目,并返回删除的项目。 -->
          <li
            is="todo-item"
            v-for="(todo, index) in todos"
            v-bind:key="todo.id"
            v-bind:title="todo.title"
            v-on:remove="todos.splice(index, 1)"
          ></li>
        </ul>
      </div>
<!-- -------------------------------------------------------------------------------------------------------------------------------- -->

<script>
    Vue.component('todo-item', {
  template: '\
    <li>\
      {{ title }}\
      <button v-on:click="$emit(\'remove\')">Remove</button>\
    </li>\
  ',
  props: ['title']
})

var v = new Vue({
  el: '#todo-list-example',
  data: {
    newTodoText: '',
    todos: [
      {
        id: 1,
        title: 'Do the dishes',
      },
      {
        id: 2,
        title: 'Take out the trash',
      },
      {
        id: 3,
        title: 'Mow the lawn'
      }
    ],
    nextTodoId: 4
  },
  methods: {
    addNewTodo: function () {
      this.todos.push({
        id: this.nextTodoId++,
        title: this.newTodoText
      })
      this.newTodoText = ''
    }
  }
})
</script>

v-model绑定

<body>
    <!-- test1 用v-model 实现表单和对象的双向绑定 -->
    <!-- v-model 实际上是下面的这段实现
        <input type="text" 
      :value="price"  
      @input="price=$event.target.value">
     -->
    <div id = 'app1'>
        <input v-model="price">
    </div>

    <hr>
    <!-- 
        自定义组件不能直接用v-model 
        控制台输入vm2.price = 1 能改变 input的value值
        但是前端输入的值不会被绑定到 vm2的 price
    -->
    <div id = 'app2'>
            <input-price v-model="price">
    </div>
    <!-- 

        首先根据我们的v-model语法糖来看

    1、我们的子组件(input-price)的value需要绑定一个从父组件传来的值,通过子组件的props接收
    2、在子组件上有新的输入时需要触发父组件的input事件,并将新的值作为参数传递给父组件

     -->
     <hr>
    <div id= "app3"> 
        <!-- <price-input v-model="price"></price-input> -->
        
        <!-- 手动实现了v-model双向绑定 -->
        <!-- 3、父组件的input事件被触发,将传来的值赋给父组件的变量price -->
        <!-- 4、父组件value的值绑定到price -->
        <price-input2 :value="price" @input="onInput"></price-input2>
        <p>{{price}}</p>
    </div>
    <br>
    <br>
    <hr>
    <p> 1.v-bind只能实现单向绑定</P>
    <p> 2.v-model(v-bind+触发的input事件)实现双向绑定</p>  
    <hr>
    <div id= "app4"> 
        <!-- <price-input v-model="price"></price-input> -->
        
        <!-- 实现了v-model双向绑定 -->
        <price-input3 v-model="jie"></price-input3>
        <p>{{jie}}</p>
    </div>
    <p>上面的例子代码简化</p>
<!-- -------------------------------------------------------------------------------------------------------------------------------- -->

<script>
    var vm1 = new Vue({
        el:"#app1",
        data: {
            price:"请输入金额"
        }
    })

    Vue.component('input-price', {
        template: '<input type="text">'
    });

    var vm2 = new Vue({
        el:"#app2",
        data: {
            price:"请输入金额"
        }
    })


    Vue.component('price-input2', {
    // 5、将父组件的value值通过props传递给子组件
    // 1、当有数据输入时触发了该组件的input事件
    template: '<input :value="value" @input="updateVal($event.target.value)" type="text">',
    props: ["value"],
    methods: {
         updateVal: function(val) {
            // 2、手动触发父组件的input事件并将值传给父组件
            this.$emit('input', val);
         }
     }
});
var vm3 = new Vue({
     el: '#app3',
     data: {
         price: ''
     },
     methods: {
          onInput: function(val) {
               this.price = val;
          }
      }
 });



 Vue.component('price-input3', {
    model:{
        prop:'price',
        event:'change'
    },
    props: ["price"],
    template: ` 
    <input :value="price" @change="$emit('change', $event.target.value)" type="text">
        `,
    // methods: {
    //      updateVal: function(val) {
    //         // 2、手动触发父组件的input事件并将值传给父组件
    //         this.$emit('input', val);
    //      }
    //  }

});

var vm4 = new Vue({
     el: '#app4',
     data: {
         jie: 'lovingVue'
     },
 });

参考文章 https://www.cnblogs.com/lhuser/p/11269546.html

组件化

vue实例 property 与方法

它们都有前缀 $

<body>
    <div id="app-7">
        <ol>
            <!--
                现在我们为每个 todo-item 提供 todo 对象
                todo 对象是变量,即其内容可以是动态的。
                我们也需要为每个组件提供一个“key”,稍后再
                作详细解释。
            -->
            <todo-item
            v-for="item in groceryList"
            v-bind:todo="item"
            v-bind:key="item.id"
          ></todo-item>
        </ol>
    </div>

    <div id="app">
        <p>{{ foo }}</p>
        <!-- 这里的 `foo` 不会更新! -->
        <button v-on:click="foo = 'baz'">Change it</button>
    </div>
<!-- -------------------------------------------------------------------------------------------------------------------------------- -->

<script>
    // 定义名为 todo-item 的新组件
   // Vue.component('todo-item', {
   //   template: '<li>这是个待办项</li>'
   // })
   //我们应该能从父作用域将数据传到子组件才对。让我们来修改一下组件的定义,使之能够接受一个 prop
   Vue.component('todo-item',{
     // todo-item 组件现在接受一个
     // "prop",类似于一个自定义 attribute。
     // 这个 prop 名为 todo。
     props: ['todo'],
     template: '<li>{{ todo.text }}</li>'
   })
   var app7 = new Vue({
    el: '#app-7',
    data: {
        groceryList: [
        { id: 0, text: '蔬菜' },
        { id: 1, text: '奶酪' },
        { id: 2, text: '随便其它什么人吃的东西' }
        ]
    }
    })
   

    var obj = {
        foo: 'bar'
    }
    // Object.freeze(),这会阻止修改现有的 property,也意味着响应系统无法再追踪变化。
    Object.freeze(obj)

    new Vue({
        el: '#app',
        data: obj
    })

    //除了数据 property,Vue 实例还暴露了一些有用的实例 property 与方法。它们都有前缀 $,以便与用户定义的 property 区分开来。例如:
    var data = { a: 1 }
    var vm = new Vue({
      el: '#example',
      data: data
    })  

    vm.$data === data // => true
    vm.$el === document.getElementById('example') // => true    

    // $watch 是一个实例方法
    vm.$watch('a', function (newValue, oldValue) {
      // 这个回调将在 `vm.a` 改变后调用
    })
</script>


组件基础


<body>


    <div id="components-demo">
        <button-counter></button-counter>
    </div>
<div id="components-demo2">
    <blog-post title="My journey with Vue"></blog-post>
    <blog-post title="Blogging with Vue"></blog-post>
    <blog-post title="Why Vue is so fun"></blog-post>
</div>
</select>

<div id ='blog-post-demo'>
<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
></blog-post>
</div>


<div id="blog-posts-events-demo">
    <div :style="{ fontSize: postFontSize + 'em' }">
      <blog-post
        v-for="post in posts"
        v-bind:key="post.id"
        v-bind:post="post"
        v-on:enlarge-text="postFontSize += 0.1"
      ></blog-post>
    </div>
  </div>

<br>
<br>
<br>



<input v-model="searchText">

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

<div id="custom-input">
   
    <br>
    <br>
    <br>
    <!-- <custom-input
    v-bind:value="searchText"
    v-on:input="searchText = $event"
  ></custom-input> -->
  <custom-input v-model="searchText"></custom-input>
</div>

<!-- 通过插槽分发内容 -->
<!-- -------------------------------------------------------------------------------------------------------------------------------- -->
<alert-box>
    Something bad happened.
  </alert-box>

<script>
  Vue.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
})
    
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
    //data 必须是一个函数
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
new Vue({ el: '#components-demo' })

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

new Vue({ el: '#components-demo2' })



new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})



Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div class="blog-post">
      <h3>{{ post.title }}</h3>
        <button v-on:click="$emit('enlarge-text')">
            Enlarge text
        </button>
      <div v-html="post.content"></div>
    </div>
  `
})


new Vue({
  el: '#blog-posts-events-demo',
  data: {
    posts: [
        { id: 1, title: 'My journey with Vue',content: 'My journey' },
        { id: 2, title: 'Blogging with Vue' ,content: 'Blogging' },
        { id: 3, title: 'Why Vue is so fun' ,content: 'Why Vue ' }
    ],
    postFontSize: 1
  }
})



Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})

new Vue({
    el:'custom-input'
})
</script>

自定义事件


<body>
  <div id="checkbox">
    <!-- // v-model 绑定了 input的value -->
    <base-checkbox v-model="lovingVue"></base-checkbox>
    <p>{{lovingVue}}</p>
  </div>

    <div id="example">
        <base-input        
        label="Username:"
        v-model = "ceshi"
        v-on:focus="onFocus"></base-input>
    </div>
</body>


<!-- -------------------------------------------------------------------------------------------------------------------------------- -->

<script>
Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

var checkbox = new Vue({
  el:'#checkbox',
  data:{
    lovingVue:true
  }
})

Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  computed: {
    inputListeners: function () {
      var vm = this
      // `Object.assign` 将所有的对象合并为一个新对象
      return Object.assign({},
        // 我们从父级添加所有的监听器
        this.$listeners,
        // 然后我们添加自定义监听器,
        // 或覆写一些监听器的行为
        {
          // 这里确保组件配合 `v-model` 的工作
          input: function (event) {
            // 这个value是focus对象
            vm.$emit('input', event.target.value)
          }
        }
      )
    }
  },
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on="inputListeners"
      >
    </label>
  `
})
var app = new Vue({
    el:'#example',
    data:{
    ceshi: ''
    },
    methods:{
        onFocus: function(message){
            console.log(message)
            console.log(this.ceshi)
        }
    }
})

</script>
posted @ 2021-12-02 17:01  _Salvatore  阅读(44)  评论(0)    收藏  举报