无标题文章

声明式渲染

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统

<div id="app">

  {{ message }}

</div>

var app = new Vue({

  el: '#app',

  data: {

    message: 'Hello Vue!'

  }

})

除了文本插值,我们还可以像这样来绑定元素 attribute:

<div id="app-2">

  <span v-bind:title="message">

    鼠标悬停几秒钟查看此处动态绑定的提示信息!

  </span>

</div>

var app2 = new Vue({

  el: '#app-2',

  data: {

    message: '页面加载于 ' + new Date().toLocaleString()

  }

})

条件与循环

控制元素是否显示

<div id="app-3">

  <p v-if="seen">现在你看到我了</p>

</div>

var app3 = new Vue({

  el: '#app-3',

  data: {

    seen: true

  }

})


在控制台输入 app3.seen = false,你会发现之前显示的消息消失了。

v-for指令可以绑定数组的数据来渲染一个项目列表

<div id="app-4">

  <ol>

    <li v-for="todo in todos">

      {{ todo.text }}

    </li>

  </ol>

</div>

var app4 = new Vue({

  el: '#app-4',

  data: {

    todos: [

      { text: '学习 JavaScript' },

      { text: '学习 Vue' },

      { text: '整个牛项目' }

    ]

  }

})

在控制台里,输入 app4.todos.push({ text: ‘新项目’ }),你会发现列表最后添加了一个新项目。

处理用户输入

v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法:

<div id="app-5">

  <p>{{ message }}</p>

  <button v-on:click="reverseMessage">反转消息</button>

</div>

var app5 = new Vue({

  el: '#app-5',

  data: {

    message: 'Hello Vue.js!'

  },

  methods: {

    reverseMessage: function () {

      this.message = this.message.split('').reverse().join('')

    }

  }

})


v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定

<div id="app-6">

  <p>{{ message }}</p>

  <input v-model="message">

</div>

var app6 = new Vue({

  el: '#app-6',

  data: {

    message: 'Hello Vue!'

  }

})


computed计算属性

计算属性结果会被缓存起来,当依赖的响应式属性 发生变化时,才会重新计算,返回最终结果

1

监听属性:

watch:{

aaa:function(){}

}//侦听 监视的作用:他依赖的属性有没有改变,如果改变,aaa2就会改变


插值

文本

数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本

插值:

<span>Message: {{ msg }}</span>


通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,

插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:

<span v-once>这个将不会改变: {{ msg }}</span>


使用 JavaScript 表达式

模板中,我们一直都只绑定简单的 property 键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>

这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被

解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例

子都不会生效。


<!-- 这是语句,不是表达式 -->

{{ var a = 1 }}

<!-- 流控制也不会生效,请使用三元表达式 -->

{{ if (ok) { return message } }}


指令

v-bind 缩写

<!-- 完整语法 -->

<a v-bind:href="url">...</a>

<!-- 缩写 -->

<a :href="url">...</a>

<!-- 动态参数的缩写 (2.6.0+) -->

<a :[key]="url"> ... </a>


v-on 缩写

<!-- 完整语法 -->

<a v-on:click="doSomething">...</a>

<!-- 缩写 -->

<a @click="doSomething">...</a>

<!-- 动态参数的缩写 (2.6.0+) -->

<a @[event]="doSomething"> ... </a>


看起来可能与普通的 HTML 略有不同,但 : 与 @ 对于 attribute 名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析。

条件渲染

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。

<h1 v-if="awesome">Vue is awesome!</h1>


也可以用 v-else 添加一个“else 块”:

<h1 v-if="awesome">Vue is awesome!</h1>

<h1 v-else>  no </h1>


在 元素上使用 v-if 条件渲染分组

因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 元素。

<template v-if="ok">

  <h1>Title</h1>

  <p>Paragraph 1</p>

  <p>Paragraph 2</p>

</template>


v-else

你可以使用 v-else 指令来表示 v-if 的“else 块”:

<div v-if="Math.random() > 0.5">

  Now you see me

</div>

<div v-else>

  Now you don't

</div>

v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。


v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:

<div v-if="type === 'A'">

  A

</div>

<div v-else-if="type === 'B'">

  B

</div>

<div v-else-if="type === 'C'">

  C

</div>

<div v-else>

  Not A/B/C

</div>

类似于 v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。


v-show 指令

<h1 v-show="ok">Hello!</h1>


不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS property display

注意,v-show 不支持 元素,也不支持 v-else。

列表渲染

v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。

<ul id="example-1">

  <li v-for="item in items" :key="item.message">

    {{ item.message }}

  </li>

</ul>


var example1 = new Vue({

  el: '#example-1',

  data: {

    items: [

      { message: 'Foo' },

      { message: 'Bar' }

    ]

  }

})


v-for 来遍历一个对象的 property。

<ul id="v-for-object" class="demo">

  <li v-for="value in object">

    {{ value }}

  </li>

</ul>


new Vue({

  el: '#v-for-object',

  data: {

    object: {

      title: 'How to do lists in Vue',

      author: 'Jane Doe',

      publishedAt: '2016-04-10'

    }

  }

})


数组检测

变更方法

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

push()

pop()

shift()

unshift()

splice()

sort()

reverse()

你可以打开控制台,然后对前面例子的 items 数组尝试调用变更方法。比如 example1.items.push({ message: ‘Baz’ })。

变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,

例如 filter()、concat() 和 slice()。它们不会变更原始数组,而总是返回一个新数组。

当使用非变更方法时,可以用新数组替换旧数组:

example1.items = example1.items.filter(function (item) {

  return item.message.match(/Foo/)

})

你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为

了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的

数组去替换原来的数组是非常高效的操作。


显示过滤/排序后的结果

我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。

例子:

<li v-for="item in dianji">{{ item }}</li>

1

data: {

  array: [ 1, 2, 3, 4, 5 ]

},

computed: {

  dianji: function () {

    return this.array.filter(function (number) {

      return number % 2 === 0

    })

  }

}


在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个方法:

<ul v-for="set in sets">

  <li v-for="n in even(set)">{{ n }}</li>

</ul>


data: {

  sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]

},

methods: {

  even: function (numbers) {

    return numbers.filter(function (number) {

      return number % 2 === 0

    })

  }

}


事件处理

监听事件

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

例子:

<div id="app">

  <button v-on:click="counter += 1">Add 1</button>

  <p>The button above has been clicked {{ counter }} times.</p>

</div>


var example1 = new Vue({

  el: '#app',

  data: {

    counter: 0

  }

})


事件处理方法

然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称。

例子:

<div id="example-2">

  <!-- `greet` 是在下面定义的方法名 -->

  <button v-on:click="greet">Greet</button>

</div>


var example2 = new Vue({

  el: '#example-2',

  data: {

    name: 'Vue.js'

  },

  // 在 `methods` 对象中定义方法

  methods: {

    greet: function (event) {

      // `this` 在方法里指向当前 Vue 实例

      alert('Hello ' + this.name + '!')

      // `event` 是原生 DOM 事件

      if (event) {

        alert(event.target.tagName)

      }

    }

  }

})

// 也可以用 JavaScript 直接调用方法

example2.greet() // => 'Hello Vue.js!'


内联处理器中的方法

除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:

<div id="example-3">

  <button v-on:click="say('hi')">Say hi</button>

  <button v-on:click="say('what')">Say what</button>

</div>


new Vue({

  el: '#example-3',

  methods: {

    say: function (message) {

      alert(message)

    }

  }

})


有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:

<button v-on:click="warn('Form cannot be submitted yet.', $event)">

  Submit

</button>


methods: {

  warn: function (message, event) {

    // 现在我们可以访问原生事件对象

    if (event) {

      event.preventDefault()

    }

    alert(message)

  }

}


事件修饰符

.stop 阻止事件冒泡

.prevent阻止事件的默认行为

.capture事件捕获

.self自身触发

.once只触发一次

<!-- 阻止单击事件继续传播 -->

<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->

<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->

<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->

<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->

<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->

<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->

<!-- 即事件不是从内部元素触发的 -->

<div v-on:click.self="doThat">...</div>

<!-- 点击事件将只会触发一次 -->

<a v-on:click.once="doThis"></a>


使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

.once 修饰符还能被用到自定义的组件事件上

Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符。

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->

<!-- 而不会等待 `onScroll` 完成  -->

<!-- 这其中包含 `event.preventDefault()` 的情况 -->

<div v-on:scroll.passive="onScroll">...</div>

这个 .passive 修饰符尤其能够提升移动端的性能。


不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。

按键修饰符

在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->

<input v-on:keyup.enter="submit">


你可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。

<input v-on:keyup.page-down="onPageDown">


在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用。

表单输入绑定

你可以用 v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

基础用法

文本

<input v-model="message" placeholder="edit me">

<p>Message is: {{ message }}</p>


多行文本

<span>Multiline message is:</span>

<p style="white-space: pre-line;">{{ message }}</p>

<br>

<textarea v-model="message" placeholder="add multiple lines"></textarea>


在文本区域插值 ({{text}}) 并不会生效,应用 v-model 来代替。

复选框

单个复选框,绑定到布尔值:

<input type="checkbox" id="checkbox" v-model="checked">

<label for="checkbox">{{ checked }}</label>


多个复选框,绑定到同一个数组:

<div id='example-3'>

  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">

  <label for="jack">Jack</label>

  <input type="checkbox" id="john" value="John" v-model="checkedNames">

  <label for="john">John</label>

  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">

  <label for="mike">Mike</label>

  <br>

  <span>Checked names: {{ checkedNames }}</span>

</div>


new Vue({

  el: '#example-3',

  data: {

    checkedNames: []

  }

})


单选按钮

<div id="example-4">

  <input type="radio" id="one" value="One" v-model="picked">

  <label for="one">One</label>

  <br>

  <input type="radio" id="two" value="Two" v-model="picked">

  <label for="two">Two</label>

  <br>

  <span>Picked: {{ picked }}</span>

</div>


new Vue({

  el: '#example-4',

  data: {

    picked: ''

  }

})


选择框

<div id="example-5">

  <select v-model="selected">

    <option disabled value="">请选择</option>

    <option>A</option>

    <option>B</option>

    <option>C</option>

  </select>

  <span>Selected: {{ selected }}</span>

</div>


new Vue({

  el: '...',

  data: {

    selected: ''

  }

})


多选时 (绑定到一个数组):

<div id="example-6">

  <select v-model="selected" multiple style="width: 50px;">

    <option>A</option>

    <option>B</option>

    <option>C</option>

  </select>

  <br>

  <span>Selected: {{ selected }}</span>

</div>


new Vue({

  el: '#example-6',

  data: {

    selected: []

  }

})


用 v-for 渲染的动态选项:

<select v-model="selected">

  <option v-for="option in options" v-bind:value="option.value">

    {{ option.text }}

  </option>

</select>

<span>Selected: {{ selected }}</span>


new Vue({

  el: '...',

  data: {

    selected: 'A',

    options: [

      { text: 'One', value: 'A' },

      { text: 'Two', value: 'B' },

      { text: 'Three', value: 'C' }

    ]

  }

})


值绑定

对于单选按钮,复选框及选择框的选项,v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值):

<!-- 当选中时,`picked` 为字符串 "a" -->

<input type="radio" v-model="picked" value="a">

<!-- `toggle` 为 true 或 false -->

<input type="checkbox" v-model="toggle">

<!-- 当选中第一个选项时,`selected` 为字符串 "abc" -->

<select v-model="selected">

  <option value="abc">ABC</option>

</select>


但是有时我们可能想把值绑定到 Vue 实例的一个动态 property 上,这时可以用 v-bind 实现,并且这个 property 的值可以不是字符串。

复选框

<input

  type="checkbox"

  v-model="toggle"

  true-value="yes"

  false-value="no"

>


// 当选中时

vm.toggle === 'yes'

// 当没有选中时

vm.toggle === 'no'


单选按钮

<input type="radio" v-model="pick" v-bind:value="a">


// 当选中时

vm.pick === vm.a


选择框的选项

<select v-model="selected">

    <!-- 内联对象字面量 -->

  <option v-bind:value="{ number: 123 }">123</option>

</select>


// 当选中时

typeof vm.selected // => 'object'

vm.selected.number // => 123


修饰符

.lazy

<!-- 在“change”时而非“input”时更新 -->

<input v-model.lazy="msg">


.number

如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:

<input v-model.number="age" type="number">


这通常很有用,因为即使在 type=“number” 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

.trim

如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

<input v-model.trim="msg">


组件

组件式vue最强大的功能之一

​ 可以扩展html元素,封装可以重用的代码

​ 优点:

能减少代码的重用,提高开发效率

降低页面的融合度,使页面更方便维护和管理

// `` es6模板字符串

var str = "hello world";

var str = `hello world`;

//``支持强制换行不出错! 而''强制换行会报错


组件注册

在注册一个组件的时候,我们始终需要给它一个名字。比如在全局注册的时候我们已经看到了:

Vue.component('my-component-name', { /* ... */ })


组件名就是 Vue.component 的第一个参数

组件名大小写

定义组件名的方式有两种:

使用 kebab-case

Vue.component('my-component-name', { /* ... */ })


当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 。

使用 PascalCase

Vue.component('MyComponentName', { /* ... */ })


当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 和 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的

全局注册

Vue.component 来创建组件:

Vue.component('my-component-name', {

  // ... 选项 ...

})


这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。比如:

Vue.component('component-a', { /* ... */ })

Vue.component('component-b', { /* ... */ })

Vue.component('component-c', { /* ... */ })

new Vue({ el: '#app' })


<div id="app">

  <component-a></component-a>

  <component-b></component-b>

  <component-c></component-c>

</div>


在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。

局部注册

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:

var ComponentA = { /* ... */ }

var ComponentB = { /* ... */ }

var ComponentC = { /* ... */ }


然后在 components 选项中定义你想要使用的组件:

new Vue({

  el: '#app',

  components: {

    'component-a': ComponentA,

    'component-b': ComponentB

  }

})


对于 components 对象中的每个 property 来说,其 property 名就是自定义元素的名字,其 property 值就是这个组件的选项对象。组件代码!

注意局部注册的组件在其子组件中不可用。例如,如果你希望 ComponentA 在 ComponentB 中可用,则你需要这样写:

var ComponentA = { /* ... */ }

var ComponentB = {

  components: {

    'component-a': ComponentA

  },

  // ...

}


或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:

import ComponentA from './ComponentA.vue'

export default {

  components: {

    ComponentA

  },

  // ...

}


注意在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:

用在模板中的自定义元素的名称

包含了这个组件选项的变量名

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <div id="app">

        <cpn></cpn>

        <cpn1></cpn1>

    </div>

    <script src="./vue.js"></script>

    <script>

        Vue.component('cpn',{

            template:`

                <div>

                    <h3>这里是组件啊</h3>   

                </div>

            `

        })

        Vue.component('cpn1',{

            template:`

                <div>

                    <cpn></cpn>

                    <h3>这个更简单诶</h3>   

                </div>

            `

        })

        var vm = new Vue({

            el:"#app",

            data:{


            },

            components:{


            }

        })

    </script>

</body>

</html>


组件之间的通信传值

父组件给子组件传值(当只有一个组件时,vue传值 vue实例是父组件)

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <script src="../vue.js"></script>

</head>

<body>

    <div id="app">

        <cpn :txt="cccc"></cpn>

    </div>

    <script>

        Vue.component('cpn',{

            template:`

                <div>

                    <h1>这里是子组件 父组件是vue实例哦</h1>

                    <p>{{txt}}</p>

                </div>

            `,

            props:['txt']

        })

        var vm = new Vue({

            el:"#app",

            data:{

                cccc:"这里是父组件哦"

            }

        })

    </script>

</body>

</html>


父传子组件传值

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <script src="vue.js"></script>

</head>

<body>

    <div id="app">

        <fu></fu>

    </div>

    <script>

        Vue.component('fu',{

            template:`

                <div>

                    <input type="text" v-model="sj"><button @click="add">提交</button>

                    <zi :list="array"></zi>

                </div>

            `,

            data:function(){

                return{

                    array:["苹果","香蕉","桔子"],

                    sj:""

                }

            },

            methods:{

                add:function(){

                    this.$data.array.push(this.sj);

                    this.sj=""

                }

            }

        })

        Vue.component('zi',{

            props:["list"],

            template:`

                <ul>

                    <li v-for="item in list">{{item}}</li>

                </ul>

            `


        })

        var vm = new Vue({

            el:"#app",

            data:{

            }

        })

    </script>

</body>

</html>


子组件给父组件传值($emit(“事件”,“参数”))

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <script src="./vue.js"></script>

</head>

<body>

    <div id="app">

        <fu></fu>

    </div>

    <script>

        Vue.component('fu',{

            template:`

                <div>

                    <h3>我是父组件</h3>

                    <p>{{aaa}}</p>

                    <zi @zidingyi="rev"></zi>

                </div>

            `,

            data:function(){

                return{

                    aaa:""

                }

            },

            methods:{

                rev:function(txt){

                    this.aaa=txt

                }

            }

        })

        Vue.component('zi',{

            template:`

                <div>

                    <h4>我是子组件</h4>

                    <button @click="add">提交</button>

                </div>

            `,

            data:function(){

                return{

                    aa:"我是子组件,传值给父组件"

                }

            },

            methods:{

                add:function(){

                    this.$emit('zidingyi',this.aa)

                }

            }

        })

        var vm = new Vue({

            el:"#app",

            data:{

            }

        })

    </script>

</body>

</html>


子组件给父组件传值 ($emit(“事件”,“参数”))

<!--$emit("事件","参数")里面定义的是自定义事件,传值到父组件上面!--->

<!----案例子传父实现模拟微信聊天---->

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <script src="./vue.js"></script>

</head>

<body>

    <div id="app">

        <fu></fu>

    </div>

    <script>

        Vue.component('fu',{

            template:`

                <div>

                    <h3>这里是父组件</h3>

                    <ul>

                        <li v-for="item in message">{{item}}</li>   

                    </ul>

                    <zi @zidingyi="adda" txt="c"></zi>

                    <zi @zidingyi="adda" txt="2"></zi>

                </div>

            `,

            data:function(){

                return{

                    message:[],

                    name:1,

                    nam:2

                }

            },

            methods:{

                adda:function(ss){

                    this.message.push(ss);

                }

            }

        })

        Vue.component('zi',{

            template:`

                <div>

                    <input type="text" v-model="mes"/><button @click="add">提交</button>   

                </div>

            `,

            data:function(){

                return{

                    mes:""

                }

            },

            props:['txt'],

            methods:{

                add:function(){

                    this.$emit('zidingyi',this.txt+":"+this.mes);

                    this.mes=""

                }

            }


        })

        var vm = new Vue({

            el:"#app",

            data:{

            }

        })

    </script>

</body>

</html>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343