一 指令
1.数据劫持
<body>
<button id ="btn">修改msg</button>
</body>
</html>
<script>
let obj ={};
let aaa = "你好世界"
Object.defineProperty(obj,"msg",{
get(){
//返回msg 的数据
return aaa;
},
set(newVal){
aaa = newVal;
}
})
console.log(obj.msg);
// 点击按钮修改msg的值
btn.onclick = function(){
obj.msg = " hello world " ; //一旦修改msg就会触发set方法,并且获取到一个新的值
console.log(obj.msg);
}
</script>
2.属性配置
<script>
let obj = {};
Object.defineProperty(obj, "msg", {
value: '你好世界', //给某个key添加值
writable: true, //设置某个key的值可以被修改 (默认值为false,不能修改)
configurable:true, //设置某个key可否被删除 (默认值为false,不能删除)
enumerable:true, //设置当前对象能否枚举所有属性 (默认值为false,不能遍历)
})
console.log(obj.msg); //你好世界
// obj.msg = "hello world"
// console.log(obj.msg); //hello world
// 删除一个属性
// delete obj.msg;
// console.log(obj.msg); //undefined
// 枚举(罗列)一个对象的属性
console.log(Object.keys(obj)); //['msg']
</script>
3.自定义指令
// 注册一个全局自定义指令 v-focus
Vue.directive('demo', {
inserted: function (el, binding, vnode) {
console.log(el, binding, vnode);
}
})
// 组件中注册局部指令
new Vue({
el: '#app',
data: {},
directives: {
demo: {
inserted: function (el, binding, vnode) {
cosnole.log(el, binding, vnode);
}
}
}
})
// 在模板中使用自定义指令
<div v-demo>
</div>
二 Vue 组件化开发
1.全局组件化
<body>
<div id="app">
<my-list></my-list>
<my-list />
</div>
</body>
</html>
<!-- 抽离模板 方便操作修改 -->
<template id="list">
<ul><li><span>你好世界</span><a href="http://baidu.com">百度</a></li></ul>
</template>
<script src="./vue.js"></script>
<script>
// 全局组件 [template : 模板 component:组件]
Vue.component("my-list", {
template: "#list"
})
new Vue({
el: "#app",
data: {}
})
</script>
注意: 组件中data必须是函数
//多次调用一个数据,就需要维护,所以需要套上一个作用域 防止被外部数据污染,ES5 里只有函数才有作用域
Vue.component("my-list", {
template: "#list",
data(){ // 所以组件中data必须是函数
return {msg:'你好 世界'}
}
})
2.局部组件化
// 局部组件
components: {
"my-list": {
template: "#list",
data() { //组件中data必须是函数
return {msg: '你好 世界'}
},
methods: {
btnclick() {console.log(yes)}
}
}
}
3.父子之间的通讯
3.1 父传子
html
<div id="app">
<my-list :con="content" :myhref="link"></my-list>
<my-list />
</div>
模板
<template id="list">
<ul>
<li>
<span>{{msg}}</span>
<a :href="myhref">{{con}}</a>
<button @click="btnclick">按钮</button>
</li>
</ul>
</template>
script
new Vue({
el: "#app",
data: {
content: "跳转到百度",
link: "http://baidu.com"
},
// 局部组件
components: {
"my-list": {
template: "#list",
//props 以数组的形式接受,是简写 的形式
// props: ["con", "myhref"],
props:{
con:{
type:String,
default:"跳转到新浪"
},
myhref:{
type:String,
default:"http://sina.com.cn"
}
},
data() { //组件中data必须是函数
return {
msg: '你好 世界'
}
},
methods: {
btnclick() {
console.log(yes);
}
}
}
}
})
3.2 子传父
html
<div id="app">
<my-list :con="content" :myhref="link" v-on:changecontent="changeContent" @changelink = "changeLink"></my-list>
</div>
模板
<!-- 抽离模板 方便操作修改 -->
<template id="list">
<ul>
<li>
<span>{{msg}}</span>
<a :href="myhref">{{con}}</a>
<button @click="btnclick">按钮</button>
</li>
</ul>
</template>
script
new Vue({
el: "#app",
data: {
content: "跳转到百度",
link: "http://baidu.com"
},
methods:{
changeContent(val){
this.content = val
},
changeLink(val){
this.link = val
}
},
// 局部组件
components: {
"my-list": {
template: "#list",
props: ["con", "myhref"],
data() { return {msg: '你好 憨憨'}},
methods: {
btnclick() {
// vue中对象数据的维护要求非常严格,原始数据在那个组件中,就必须在哪一个组件里修改
// 子组件不能直接修改props,因为vue是单向数据流
// 通知父级修改content和link - emit发射
// this.$emit(事件名称, 传递的参数)
this.$emit('changecontent', "跳转到新浪");
this.$emit('changelink', "http://sina.com.cn")
}
}
}
}
})
三 插槽(slot)
1.匿名插槽
html
<div id="app">
<my-nav>
<input type="text">
</my-nav>
</div>
<template id="mynav">
<div class="nav">
<span><</span>
<section>
<slot></slot>
</section>
<span>...</span>
</div>
</template>
<script src="./vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
},
components:{
MyNav:{
template:"#mynav",
}
}
})
</script>
2.具名插槽
html
<div id="app">
<my-nav :slotname="slotname">
<input type="text" slot="ipt">
<h3 slot="title">标题</h3>
<div slot="list">
<a href="">百度</a>
<a href="">新浪</a>
<a href="">淘宝</a>
</div>
</my-nav>
</div>
<template id="mynav">
<div class="nav">
<span><</span>
<section>
<!-- <slot name='title'></slot> -->
<slot :name='slotname'></slot>
<!-- <slot name='ipt'></slot> -->
</section>
<span>...</span>
</div>
</template>
<script src="./vue.js"></script>
<script>
let vm=new Vue({
el: "#app",
data: {
slotname:"ipt",
},
components: {
MyNav: {
template: "#mynav",
props:["slotname"],
}
}
})
</script>
3.作用域插槽
html
<div id="app">
<my-nav>
<input type="text" slot="ipt">
<h3 slot="title" slot-scope="scope">{{scope.msg}}</h3>
<div slot="list">
<a href="">百度</a>
<a href="">新浪</a>
<a href="">淘宝</a>
</div>
</my-nav>
</div>
<template id="mynav">
<div class="nav">
<span><</span>
<section>
<slot :msg="msg" name="title"></slot>
</section>
<span>...</span>
</div>
</template>
<script src="./vue.js"></script>
<script>
let vm=new Vue({
el: "#app",
components: {
MyNav: {
template: "#mynav",
// 子组件有数据,想要把这个数据共享给插槽
data(){
return {
msg:"新的标题"
}
}
}
}
})
</script>
4.作用域插槽的多种写法
<my-nav v-slot:title="scope">
<!-- <h3 slot="title" slot-scope="scope">{{scope.msg}}</h3> -->
<!-- <template slot="title" slot-scope="scope">
<h3>{{scope.msg}}</h3>
</template> -->
<!-- <template v-slot:title="scope">
<h3>{{scope.msg}}</h3>
</template> -->
<h3>{{scope.msg}}</h3>
</my-nav>