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'
},
});
组件化
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>