文章目录
数据双向绑定底层原理:
vue是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调;
一:组件渲染展示例子
//view
<div id="app-7">
<ol>
<todo-item //第二:展现组件,其中 有一个for循环 ,用v-bind独有的特性,绑定for循环中的->
v-for="item in groceryList" //第二:对象item,并起名为todo;绑定for循环中的对象id,并起名为key;
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
</ol>
</div>
//controller
<script>
Vue.component('todo-item', { //第一 :在此注册一个子模板 todo-item
props: ['todo'], // 第三:子组件接收 todo-item的数据todo;
template: '<li>{{ todo.text }}</li>' //第四:用template特有的模板{{ }}把数据展现出来
})
//model
var app7 = new Vue({ //父组件Vue
el: '#app-7', //挂载dom
data: { //数据
groceryList: [
{ id: 0, text: '啦啦啦' },
{ id: 1, text: 'mite' },
{ id: 2, text: '二珂' }
]}})
</script>
- 我们为每个 todo-item 提供 todo 对象
todo 对象是变量,即其内容可以是动态的。
我们也需要为每个组件提供一个“key”,稍后再
作详细解释。
二: freeze阻止修改现有的属性,也意味着响应系统无法再追踪变化。
var obj = {
foo: 'bar'
}
Object.freeze(obj)
new Vue({
el: '#app',
data: obj
})
<div id="app">
<p>{{ foo }}</p>
<!-- 这里的 `foo` 不会更新! -->
<button v-on:click="foo = 'baz'">Change it</button>
</div>
三:模板语法
- Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。
- 在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
- 如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,直接写渲染 (render) 函数,使用可选的 JSX 语法。
插值----文本
数据绑定最常见的形式:双括号 {{ }}
<span>Message: {{ msg }}</span>
绑定的数据对象上 msg 属性发生了改变,插值处的内容都会更新。
<span v-once>这个将不会改变: {{ msg }}</span>
通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:
插值----原始 HTML
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令
四:使用 JavaScript 表达式
{{ number + 1 }}
{{ ok ? ‘YES’ : ‘NO’ }}
{{ message.split(’’).reverse().join(’’) }}
< div v-bind:id="‘list-’ + id">
五:参数
- v-if 指令将根据表达式 seen 的值的真假来插入/移除
元素。
< p v-if=“seen”>现在你看到我了< / p >
- v-bind能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML 特性:
< a v-bind:href=“url” >…< /a >
- v-on 指令,它用于监听 DOM 事件
< a v-on:click=“doSomething”>…< /a >
五:动态参数
- 用方括号 [ ] 括起来的 JavaScript 表达式作为一个指令的参数,这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值 将会作为最终的参数来使用。
< a v-bind : [attributeName] = “url” > … < /a >
- 同样地,你可以使用动态参数为一个 动态的事件名 绑定处理函数
当 eventName 的值为 “focus” 时,v-on:[eventName] 将等价于 v-on:focus。
< a v-on:[eventName]=“doSomething”> … < /a >
六:修饰符
- 修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():
< form v-on:submit.prevent=“onSubmit”>…< /form >
七:缩写
- v-on--------> @
- v-bind------> :
v-bind指令用于设置HTML属性:v-bind:href 缩写为 :href
v-on 指令用于绑定HTML事件 :v-on:click 缩写为 @click
八:计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。
所以,对于任何复杂逻辑,你都应当使用计算属性。
例如下面:
<div id="example">
<p>不用计算属性: "{{ message }}"</p>
<p>用计算属性: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
fangfa: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
这里我们声明了一个计算属性 fangfa。我们提供的函数将用作属性 vm.fangfa 的 getter 函数:
console.log(vm.fangfa) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.fangfa) // => 'eybdooG'
你可以打开浏览器的控制台,自行修改例子中的 vm。vm.fangfa 的值始终取决于 vm.message 的值。这个计算属性 fangfa 会随着data里面的数据变化而变化;
八:计算属性缓存 vs 方法
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
($event )对象
第一种:<button v-on:click="($event)"> </button> //用小括号 还有$;
第二种:<button v-on:click=" tap"> </button> //直接写入点击对象方法,
methods:{
tap(e ){
console.log(e) //求event对象,必须在点击事件中用($event) 或者 直接写入方法,不用小括号;
}}
例子一: todolist 增删改查 综合考察
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>这个是todulist</title>
<link rel="stylesheet" href="./libs/bootstrap.css" />
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>事项</label>
<input type="text" v-model="content" class="form-control" id="" placeholder="请输入代办内容" />
</div>
<button class="btn btn-primary" @click="tijiao">提交</button>
</div>
</div>
<div class="row">
<div class="col-md-12">
<ul class="list-group">
<li v-for="(t,i) in shuju" :key="i" class="list-group-item">
<span>【{{ t.kj == 0 ? '未完成' : '已完成' }}】</span>
{{ t.ding }}
<button @click="endHandle(i)" v-if="t.kj==0">完成</button>
<button @click="delHandle(i)">删除</button>
</li>
</ul>
</div>
</div>
</div>
<script src="./libs/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: ".container",
data: {
shuju: [],
content: "",
},
methods: {
tijiao() {
this.shuju.push({
//id: Date.now(), // 做什么用的?
ding: this.content,
kj: 0, //状态
});
//this.content="";
},
endHandle(i) {
this.shuju[i].kj = 1;
},
delHandle(i) {
this.shuju.splice(i, 1); //splice() 方法用于添加或删除数组中的元素。
},
},
});
</script>
</body>
</html>
例子二:金额结算 考察compute
在这里插入代码片
例子三:模糊搜索
在这里插入代码片