API:https://vue.docschina.org/v2/guide/installation.html
动画曲线函数:https://cubic-bezier.com/#.63,.11,.51,.69

<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <!-- 1. 导入Vue的包 --> <script src="./lib/vue-2.4.0.js"></script> </head> <body> <!-- 将来 new 的Vue实例,会控制这个 元素中的所有内容 --> <!-- Vue 实例所控制的这个元素区域,就是我们的 V --> <div id="app"> <p>{{ msg }}</p> </div> <script> // 2. 创建一个Vue的实例 // 当我们导入包之后,在浏览器的内存中,就多了一个 Vue 构造函数 // 注意:我们 new 出来的这个 vm 对象,就是我们 MVVM中的 VM调度者 var vm = new Vue({ el: ‘#app‘, // 表示,当前我们 new 的这个 Vue 实例,要控制页面上的哪个区域 // 这里的 data 就是 MVVM中的 M,专门用来保存 每个页面的数据的 data: { // data 属性中,存放的是 el 中要用到的数据 msg: ‘欢迎学习Vue‘ // 通过 Vue 提供的指令,很方便的就能把数据渲染到页面上,程序员不再手动操作DOM元素了【前端的Vue之类的框架,不提倡我们去手动操作DOM元素了】 } }) </script> </body>
{{msg}}
使用插值表达式时,如果vue没有及时被加载出来(网速较慢情况),就会在页面上展现
{{msg}}
而不是具体数据信息,vue的解决方案类似Angular一样,使用属性控制器
<style> [v-cloak] { display: none; } </style> <script src="./lib/vue-2.4.0.js"></script> </head> <body> <div id="app"> <p v-cloak>+++++++{{ msg }}------</p> <p v-text="msg">+++++++--------</p> <!-- 默认v-text 是没有闪烁问题的 --> <!-- v-text 会覆盖元素中原本的内容,但是 插值表达式 只会 替换自己的这个占位符,不会把整个元素的内容清空--> </div>
解决 插值表达式 闪烁问题的指令,使用的同时别忘记添加样式:
<style> [v-cloak] { display: none; } </style>
类似于插值表达式,但是不同于插值表达式的是,使用该指令不会出现闪烁问题,而且其内指定的内容采用覆盖的方式覆盖元素内容,插值表达式不会覆盖只会替换自己占位符的内容。
插值表达式和v-text都只能在元素内插入文本,如果使用这两种方式向元素内插入子元素,需要使用v-html。
goWd(e) { // 判断触发事件的是不是动态绑定的元素 if (e.target.nodeName == "A") { this.$router.push("/wd"); } }
v-bind: 是vue中,提供的用于绑定属性的指令【属性绑定机制】,该指令会告诉vue,冒号后面的属性值里的内容是一个变量。
<div id="app">
    <button title="123">点我</button>
    <!-- v-bind:  是vue中,提供的用于绑定属性的指令,该指令会告诉vue,冒号后面的属性值里的内容是一个变量。 -->
    <button v-bind:title="titl">点vue</button>
    <!-- 既然是变量,当然可以使用字符串拼接等操作 -->
    <button v-bind:title="titl.replace(‘Vue‘,‘vUE‘) + ‘123‘">点vue</button>
    <!-- v-bind:提供了一种简写的方式就是直接在要绑定的元素上写: -->
    <button :title="titl">点vue了吗</button>
</div>
<script>
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            titl: ‘欢迎学习Vue‘
        }
    })
</script>
vue像Angular一样,都不提倡使用dom操作,v-on是vue提供的事件绑定机制。在vue中,指令指定的内容为变量(属性)或者method,类似下面的直接调用alert方法,vue会去methods去寻找这个alert方法或属性,找不到就会报错
<div id="app">
    <!-- 在vue的指令中会把其内内容当作属性(变量)或方法来处理,alert作为一个method并没有在vue中定义,所以点击1会报错 -->
    <!-- <input type="button" value="点击1" v-on:click="alert(‘1bc‘)"> -->
    <input type="button" value="点击2" v-on:click="click_abc">
    <!-- v-on:的缩写是@ -->
    <input type="button" value="点击3" @click="click_abc">
</div>
<script>
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            titl: ‘欢迎学习Vue‘
        },
        methods: {
            click_abc: function () {
                alert(‘abc‘)
            }
        }
    })
</script>
在这里有个问题,vue并没有那么严格的说方法一定要在methods中定义,它也可以在变量(data内属性)中定义:
<div id="app">
    <!-- 在vue的指令中会把其内内容当作属性(变量)或方法来处理,
    alert作为一个method并没有在vue中定义,所以点击1会报错 -->
    <input type="button" value="点击1" v-on:click="alert(‘1bc‘)">
    <input type="button" value="点击2" v-on:click="click_abc">
</div>
<script>
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            titl: ‘欢迎学习Vue‘,
            alert:function (x) {
                alert(x)
            }
        },
        methods: {
            click_abc: function () {
                alert(‘abc‘)
            }
        }
    })
</script>
不过还是不推荐这种写法,毕竟一个好的约定习惯是data内只封装数据。
1、在vm实例中,如果想要获取 data 上的数据,或者 想要调用methods 中的方法,必须通过this.数据属性名 或 this.方法名 来进行访问,这里的this就表示我们 new 出来的 vm实例对象。
2、vm实例,会监听自己身上 data 中所有数据的改变,只要数据一旦发生变化,就会自动把最新的数据从data上同步到页面中去。 [好处:程序员只需要关心数据,不需要考虑怎么渲染数据了
<div id="app">
    <input type="button" value="浪起来" @click="bll">
    <input type="button" value="稳住" @click="wz">
    <h3>{{msg}}</h3>
</div>
<script>
    // 注意:在vm实例中,如果想要获取 data 上的数据,或者 想要调用
    // methods 中的方法,必须通过this.数据属性名 或 this.方法名 来
    // 进行访问,这里的this就表示我们 new 出来的 vm实例对象
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            msg: ‘猥琐发育,别浪!!‘,
            inter: null
        },
        methods: {
            bl() {
                if (this.inter != null) return;
                let that = this;
                that.inter = setInterval(function () {
                    let start = that.msg.substring(0, 1);
                    let end = that.msg.substring(1);
                    that.msg = end + start;
                    // 注意:vm实例,会监听自己身上 data 中所有数据的改变,只要数据
                    // 一旦发生变化,就会自动把最新的数据从data上同步到页面中去。
                    // [好处:程序员只需要关心数据,不需要考虑怎么渲染数据了。]
                }, 500);
            },
            bll() {
                // 使用箭头函数解决this指向问题。箭头函数内部的this永远和箭头
                // 函数外部的this保持一致。
                if (this.inter != null) return;
                this.inter = setInterval(() => {
                    let start = this.msg.substring(0, 1);
                    let end = this.msg.substring(1);
                    this.msg = end + start;
                    // 注意:vm实例,会监听自己身上 data 中所有数据的改变,只要数据
                    // 一旦发生变化,就会自动把最新的数据从data上同步到页面中去。
                    // [好处:程序员只需要关心数据,不需要考虑怎么渲染数据了。]
                }, 500);
            },
            wz() {
                clearInterval(this.inter);
                this.inter = null;
            }
        }
    })
</script>
v-model只能运用在表单元素中,用于双向数据绑定。注意v-bind只能用于单向数据绑定。
<div id="app">
    <!-- v-bind只能用于实现数据的单向绑定,从M 自动绑定到 V,无法实现数据的双向绑定 -->
    <input type="text" v-bind:value="msg">
    <!-- 使用 v-model 指令,可以实现 表单元素和Model中数据的双向绑定 -->
    <!-- 注意:v-model 只能运用在 表单元素中 -->
    <input type="text" v-model:value="msg">
</div>
<script>
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            msg: ‘Hello Vue‘
        },
        methods: {}
    })
</script>
<div id="app">
    <ul>
        <!--<li v-for="value in common">{{value}}</li>-->
        <li v-for="(value,index) in common">索引:{{index}},值:{{value}}</li>
    </ul>
    <ul>
        <!--<li v-for="(k,v) in obj">键:{{v}},值:{{k}}</li>-->
        <!-- 在遍历对象的时候,还有可以获取索引 -->
        <li v-for="(k,v,i) in obj">键:{{v}},值:{{k}},索引:{{i}}</li>
    </ul>
    <ul>
        <!-- 如果迭代数字的话是从1开始的 -->
        <li v-for="num in 10">{{num}}</li>
    </ul>
    <ul>
        <li v-for="str in ‘Hello_World‘">{{str}}</li>
    </ul>
</div>
<script>
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            // 循环普通数组
            common: [1, 2, 3, 4, 5],
            // 循环对象
            obj: {maomao: ‘24‘, keke: 24, jiji: 22, mimi: 22}
        },
        methods: {}
    })
</script>
使用v-for可能存在一定的问题,建议在使用v-for时指定:key
<div id="app">
    <div>
        <label>id:
            <input type="text" v-model="id">
        </label>
        <label>name:
            <input type="text" v-model="name">
        </label>
        <input type="button" value="添加" @click="add">
    </div>
    <!-- 如果不使用用:key强制绑定对象与元素唯一关联,可能会导致意想不到的问题:
            例如:如果你勾选了最后一项,然后添加一组数据,会发现原来勾选的
            变为了倒数第二个了!
     -->
    <!--<p v-for="mate in roommates">-->
        <!--<input type="checkbox">{{mate.id}}---{{mate.name}}-->
    <!--</p>-->
    <!--
        注意:在v-for遍历的时候,key 属性只能使用number或者string。
        注意:key在使用的时候,必须使用 v-bind 属性绑定的形式,指定key的值。
        在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for有问题,必须
        在使用v-for的同时,指定唯一的 字符串/数字 类型 :key 值
     -->
    <p v-for="mate in roommates" :key="mate.id">
        <input type="checkbox">{{mate.id}}---{{mate.name}}
    </p>
</div>
<script>
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            id: ‘‘,
            name: ‘‘,
            roommates: [
                {id: 1, name: ‘毛毛‘},
                {id: 2, name: ‘吉吉‘},
                {id: 3, name: ‘可可‘},
                {id: 4, name: ‘咪咪‘},
                {id: 5, name: ‘德玛‘}
            ]
        },
        methods: {
            add() {
                this.roommates.unshift({
                    id: this.id,
                    name: this.name
                });
            }
        }
    })
</script>
<div id="app">
    <!--<button @click="toggle">toggle</button>-->
    <!-- 如果事件内逻辑就一行代码,可以直接写 -->
    <button @click="flag=!flag">toggle</button>
    <!--
        v-if 的特点:每次都会重新删除或创建元素
        v-show 的特点:每次不会重新进行DOM的删除和创建操作,只是切换了
        元素的 display:none 样式。
        v-if 有较高的切换性能消耗
        v-show 有较高的初始渲染消耗
        如果元素涉及到频繁的切换,最好不要使用v-if,而是推荐使用v-show
        如果元素可能永远也不会被显示出来被用户看到,则推荐使用v-if
     -->
    <p v-if="flag">我是v-if</p>
    <p v-show="flag">我是v-show</p>
</div>
<script>
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            flag: true
        },
        methods: {
            toggle() {
                this.flag = !this.flag;
            }
        }
    })
</script>
// 注册一个名为 `v-focus` 的全局自定义指令 Vue.directive(‘focus‘, { // 当绑定的元素插入到 DOM 时调用此函数…… inserted: function (el) { // 元素调用 focus 获取焦点 el.focus() } }) //如果你想要注册一个局部指令,也可以通过设置组件的 directives 选项: directives: { focus: { // 指令定义对象 inserted: function (el) { el.focus() } } }
全局自定义指令中参数1:指令的名称,在定义的名称前面,不需要加 v- 前缀。但是在调用的时候,必须 在指令名称前 加上 v- 前缀来进行调用。
全局自定义指令中参数2:是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关操作。
<div id="app"> 自定义指令自动获取焦点:<input type="text" v-focus v-color="‘red‘"> <!--<p v-fontSize="‘40px‘">哈哈哈哈,我使用了简写方式</p>--> <p v-font-size="‘40px‘">哈哈哈哈,我使用了简写方式</p> </div> <script> <!-- 定义全局指令 --> Vue.directive(‘focus‘, { bind: (el, binding) => { // 每当指令绑定到元素上的时候,会立即执行这个bind函数,只 // 执行一次。 // 注意在 每个 函数中,第一个参数,永远是el,表示 被绑定了指令的那个元素, // 这个el参数,是个原生的js对象。 // 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候 // 调用focus方法没有作用,因为,一个元素,只有插入DOM之后,才能获取焦点 // el.focus() // 和样式相关的操作,一般都可以在bind执行 }, inserted: (el, binding) => { // 在已绑定的元素插入到父节点时调用(只能保证父 // 节点存在,不一定存在于 document 中)。 el.focus(); // 和JS行为有关的操作,最好在inserted中去执行,放置 JS行为不生效 }, update: (el, binding) => { // 当BNode更新的时候,会执行 updated,可能会触发多次 }, componentUpdated: (el, binding) => { }, unbind: (el, binding) => { } }); Vue.directive(‘color‘, { bind(el, binding) { console.log(‘指令名称‘, binding.name); console.log(‘指令值‘, binding.value); console.log(‘指令值(未计算过的)‘, binding.expression); el.style.color = binding.value; } }); // 使用简写 // 不能在自定义指令中使用驼峰命名法,要么全小写,要么使用font-size的形式 // Vue.directive(‘fontSize‘, function (el, binding) { // el.style.fontSize = parseInt(binding.value) + ‘px‘; // }) Vue.directive(‘font-size‘, function (el, binding) { el.style.fontSize = parseInt(binding.value) + ‘px‘; }); let vm = new Vue({ el: ‘#app‘, data: {}, methods: {}, directives: { focus: { // 指令名称 // 指令定义对象 inserted: function (el) { el.focus() } }, // 简写方式:表示给fontSize写两个方法bind和update,且这两个方法公用同样的方法体 // 不能在自定义指令中使用驼峰命名法,要么全小写,要么使用font-size的形式 // fontSize: function(el, binding){ // el.style.fontSize = parseInt(binding.value) + ‘px‘; // } ‘font-size‘:(el,binding)=>{ el.style.fontSize = parseInt(binding.value) + ‘px‘; } } }) </script>
<div id="app">
    <!-- 过滤器可以在两种场景中使用:双花括号插
    值(mustache interpolation)和 v-bind 表达
    式(后者在 2.1.0+ 版本支持) -->
    <!-- 类似django模板过滤 -->
    <p>{{ msg | StrFilter }}</p>
    <!-- 可以连续过滤 -->
    <p>{{ msg | StrFilter | blackFilter }}</p>
    <!-- 可以传递多个参数:1-msg,2-*,3-* -->
    <p>{{ msg | strictFilter({name:‘毛毛‘},[‘1‘,2,3]) }}</p>
    <!-- 使用组件内部过滤器 -->
    <p>{{ msg | doFilter }}</p>
    <!-- 还可以用于属性绑定 -->
    <p :title="msg | doFilter">鼠标悬停一会看看</p>
</div>
<script>
    // vue定义全局过滤器[必须在创建实例之前!!!]
    Vue.filter(‘StrFilter‘, (str) => {
        return str.replace(/大/g, ‘小‘);
    });
    Vue.filter(‘blackFilter‘, (str) => {
        return str.replace(/黑/g, ‘白‘);
    });
    Vue.filter(‘strictFilter‘, (str, arg1, arg2) => {
        console.log(arg1, arg2);
        return str.replace(/黑/g, ‘白‘);
    });
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            msg: ‘安徽省阜阳市是一个大大大的市区,里面有很多大佬和黑帮。‘
        },
        methods: {},
        filters: {
            // 组件内部的过滤器
            doFilter(str) {
                return str.replace(/安徽省阜阳市/g, ‘**省**市‘);
            }
        }
    });
</script>
event.preventDefault() 或 event.stopPropagation()
是非常常见的需求。尽管我们可以在methods中轻松实现这点,但更好的方式是:methods只有存粹的数据逻辑,而不是去处理DOM事件细节。为了解决这个问题,vue为v-on提供了事件修饰符。修饰符是以点(.)开头的指令后缀来表示。
<style> .inner { padding: 50px; margin: 2px; background-color: darkolivegreen; } </style> <script src="./lib/vue-2.4.0.js"></script> </head> <body> <div id="app"> <!-- 停止默认事件,提交/跳转等事件不再有效 --> <!--<a href="https://www.baidu.com" @click.prevent="doThis">去百度</a>--> <!-- 停止事件向上冒泡 --> <!--<div class="inner" @click="innerDivHandler"> <button @click="doThis">去百度1</button> </div> <div class="inner" @click="innerDivHandler"> <button @click.stop="doThis">去百度2</button> </div>--> <!-- 只要event.target是元素自身时,才触发处理函数 --> <!-- 也就是说,event.target 是子元素时,不触发处理函数 --> <!--<div class="inner" @click="innerDivHandler"> <button @click="doThis">去百度1</button> </div> <div class="inner" @click.self="innerDivHandler"> <button @click="doThis">去百度2</button> </div>--> <!-- 添加事件监听器,使用事件捕获模式 --> <!-- 也就是说,内部元素触发的事件先在此处处理,然后才交给内部元素进行处理 --> <!--<div @click.capture="doThis">...</div>--> <!-- 事件只会触发一次,修饰符可以链式调用 --> <!--<a href="https://www.baidu.com" @click.prevent.once="doThis">去百度</a>--> <!--<a href="https://www.baidu.com" @click.once.prevent="doThis">去百度</a>--> <!-- 滚动事件的默认行为(滚动)将立即发生, --> <!-- 而不是等待 `onScroll` 完成后才发生, --> <!-- 以防在滚动事件的处理程序中含有 `event.preventDefault()` 调用 --> <!--不要将 .passive 和 .prevent 放在一起使用,因为 --> <!-- .prevent 将被忽略,并且浏览器可能会显示一条警告。 --> <!-- 记住,.passive 会向浏览器传达的意思是,你_并不_希望阻止事件的默认行为。 --> <!--<div v-on:scroll.passive="onScroll">...</div>--> </div> <script> var vm = new Vue({ el: ‘#app‘, data: {}, methods: { doThis() { console.log(‘doThis‘); }, innerDivHandler() { console.log(‘innerDivHandler‘); } } }) </script>
<div id="app">
    <!-- 监听按键码为13的keyup事件 -->
    按键码:<input type="text" v-model="msg" @keyup.13="add">
    <!-- enter为vue提供的一些常用按键别名 -->
    按键别名:<input type="text" v-model="msg" @keyup.enter="add">
    <!-- 使用自定义的按键别名 -->
    自定义按键别名:<input type="text" v-model="msg" @keyup.f1="add">
    <!-- 可以串联响应多个按键  -->
    串联响应多个按键:<input type="text" v-model="msg" @keyup.up.enter="add">
    <p>回车输出:{{txt}}</p>
</div>
<script>
    <!--自定义按键别名-->
    Vue.config.keyCodes.f1=13
    let vm = new Vue({
        el: ‘#app‘,
        data: {
            msg: ‘‘,
            txt: ‘‘
        },
        methods: {
            add() {
                this.txt = this.msg;
            }
        }
    })
</script>
仅在以下修饰符对应的按键被按下时,才会触发鼠标或键盘事件监听器:
<div id="app">
    <!-- ctrl+enter触发add方法 -->
    按键码:<input type="text" v-model="msg" @keyup.ctrl.enter="add">
    <p>回车输出:{{txt}}</p>
</div>
<div id="app">
    <!-- ctrl+enter触发add方法 -->
    按键码:<input type="text" v-model="msg" @keyup.ctrl.enter="add">
    <!-- Ctrl + Click -->
    <div @click.ctrl="doSomething">做一些操作</div>
    <p>回车输出:{{txt}}</p>
    <!--.exact 修饰符可以控制触发事件所需的系统辅助按键的准确组合。-->
    <!-- 如果 Alt 键或 Shift 键与  Ctrl 键同时按下,也会触发事件 -->
    <button @click.ctrl="onClick">A</button>
    <!-- 只在 Ctrl 按键按下,其他按键未按下时,触发事件 -->
    <button @click.ctrl.exact="onCtrlClick">A</button>
    <!-- 只在没有系统辅助按键按下时,触发事件 -->
    <button @click.exact="onClick">A</button>
</div>
在数据绑定中,一个常见的需求是,将数据与元素的class列表,以及元素的style内联样式的操作绑定在一起。由于它们都是属性(attribute),因此我们可以使用v-bind来处理它们:只需从表达式中计算出最终的字符串。然而,处理字符串拼接,即麻烦又容易出错。为此,在使用 v-bind 指令来处理 class 和 style 时,Vue 对此做了特别的增强。表达式除了可以是字符串,也能够是对象和数组。
<style> .red { color: red; } .italic { font-style: italic; } .thin { font-weight: 200; } .active { font-size: 50px; } </style> <script src="./lib/vue-2.4.0.js"></script> </head> <body> <div id="app"> <!--<h1 class="red italic thin active">这是一个大的H1</h1>--> <!-- 第一种使用方式,直接传递一个数组,注意:这里的class需要使用 v-bind做数据绑定 --> <!--<h1 :class="[‘thin‘,‘italic‘]">这是一个大的H1</h1>--> <!-- 在数组中使用三元表达式 --> <!--<h1 :class="[‘thin‘,‘italic‘,flag?‘active‘:‘‘]">这是一个大的H1</h1>--> <!-- 在数组中使用 对象 来替代三元表达式,提高代码可读性 --> <!--<h1 :class="[‘thin‘,‘italic‘,{active:flag}]">这是一个大的H1</h1>--> <!-- 在为class使用 v-bind 绑定对象的时候,对象的属性是类名,由于 对象的属性可 带引号,也可以不带引号,所以这里我没写引号;属性的值 是一个标识符 --> <h1 :class="classObj">这是一个大的H1</h1> </div> <script> var vm = new Vue({ el: ‘#app‘, data: { flag: true, classObj: {red: true, italic: true, active: false, thin: true} }, methods: {} }) </script>
<div id="app">
    <!-- 由于对象中的键不允许直接使用-,所以要用引号引起来 -->
    <!--<h1 :style="{color:‘red‘,‘font-size‘:‘50px‘}">这是一个大的H1</h1>-->
    <!-- 在data上直接定义,然后绑定 -->
    <!--<h1 :style="styleObj">这是一个大的H1</h1>-->
    <!-- 通过数组引用多个data上定义的样式对象 -->
    <h1 :style="[styleObj,style2Obj]">这是一个大的H1</h1>
</div>
<script>
    var vm = new Vue({
        el: ‘#app‘,
        data: {
            styleObj: {color: ‘red‘, ‘font-size‘: ‘50px‘},
            style2Obj: {‘font-style‘: ‘italic‘},
        },
        methods: {}
    })
</script>
组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以调用对应的组件即可;
模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;
<body>
<div id="app">
    <!-- 1.3 在页面中引用定义的组件 -->
    <!-- <my-com1></my-com1> -->
    <mycom1></mycom1>
</div>
<script>
    // 1.1 使用Vue.extend 来创建全局的Vue组件模板HTML
    // 通过 template 属性,指定了组件要展示的HTML结构
   // var com1 = Vue.extend({
   //      template:‘<h3>这是使用Vue.extend创建的组件</h3>‘
   //  });
       // 1.2 使用Vue.component(‘组件的名称‘,创建出来的组件模板对象)生成组件
       // Vue.component(‘myCom1‘,com1)
       // 如果使用Vue.component 定义全局组件的时候,组件名称使用了 驼峰命名,则在引用的时候,需要把大写的驼峰改为小写的字母,同时,两个单词之间,使用 - 链接
    // Vue.component(‘myCom1‘,com1);
    // 如果不使用驼峰,则直接拿名称来使用即可;
    // Vue.component(‘mycom1‘,com1);
    // 我们其实没必要把创建组件的过程拆分两部,下面将使用一步的方式
    Vue.component(‘mycom1‘,Vue.extend({
        template:‘<h3>这是使用Vue.extend创建的组件</h3>‘
    }))
    var vm = new Vue({
        el: "#app",
        data: {
            
        },
        methods: {
            
        }
    });
</script>
<div id="app">
    <mycom2></mycom2>
</div>
<script>
    <!-- 可以直接在定义组件时,直接写组件模板HTML -->
    Vue.component(‘mycom2‘,{
        //  注意组件内的模板只能有一个根元素
        // template:‘<h2>你好,组件2</h2><span>哈哈啊哈</span>‘
        template:‘<div><h2>你好,组件2</h2><span>哈哈啊哈</span></div>‘
    })
    Vue.filter(‘method‘, (args) => {
        return ``;
    })
    // 实例必须定义,因为组件依赖实例中的el元素
    var vm = new Vue({
        el: "#app",
        data: {
            
        },
        methods: {
            
        }
    });
</script>
<template id="mytemp1">
    <!-- 同样的,只能有一个根元素 -->
    <div>
        <h3>模板3的方式很方便,哈哈哈哈</h3>
    </div>
</template>
<script>
    <!-- 使用前两种创建方式,都不能在template里有html代码提示,第三种方式是将template抽离出来,放到被管理的app之外,然后再template中指定对应的模板,最后在app中直接引入即可 -->
    Vue.component(‘mycom3‘,{
        template:‘#mytemp1‘
    })
    var vm = new Vue({
        el: "#app",
        data: {
            
        },
        methods: {
            
        }
    });
</script>
<div id="app">
            <mycom4>
            </mycom4>
        </div>
        <div id="app2">
            <!-- <mycom4></mycom4> -->
        </div>
        <template id="teml4">
            <h4>
                哈哈我是一个私有组件
            </h4>
        </template>
        <script>
            Vue.filter(‘method‘, (args) => {
                return ``;
            })
            var vm1 = new Vue({
                el: "#app",
                data: {
                    
                },
                methods: {
                    
                },
                filters:{},
                directives:{},
                components:{
                    mycom4:{
                        template:‘#teml4‘
                    }
                },
                beforeCreat() {},
                created(){},
                beforeMount(){},
                mounted(){},
                beforeUpdate(){},
                updated(){},
                beforeDestory(){},
                destoryed(){},
                afterDestory(){}
            });
            var vm2 = new Vue({
                el:"#app2"
            })
        </script>
<div id="app">
            <mycom1>
            </mycom1>
            <hr>
            <mycom1>
            </mycom1>
            <hr>
            <mycom1>
            </mycom1>
            <hr>
        </div>
        <template id="templ">
            <div>
                <input @click="increament" name="" value="increament" type="button">
                    <h3>
                        {{count}}
                    </h3>
                </input>
            </div>
        </template>
        <script>
            var obj = {count:0};
            // 如果data不是一个methods的话(而是一个对象obj),
            // 那么每次创建一个新的组件,都会像使用全局变量一样,这样导致
            // 的结果就是所有的组件共用变量。
            Vue.component(‘mycom1‘,{
                template:"#templ",
                data:function(){
                    // return obj;
                    // 这样写是为每个组件都开辟一块内存区域
                    return {count:0};
                },
                methods:{
                    increament() {
                        this.count++;
                    }
                }
            })
            var vm = new Vue({
                el: "#app",
                data: {
                    
                },
                methods: {
                    
                }
            });
        </script>
<style type="text/css"> .v-enter,.v-leave-to { opacity: 0; transform: translateX(100px); } .v-enter-active,.v-leave-active { transition: all .8s ease; } </style> </head> <body> <div id="app"> <a href="" @click.prevent="templ = ‘login‘">登陆</a> <a href="" @click.prevent="templ = ‘register‘">注册</a> <!-- 对组件使用动画,只需要使用transition包裹起来即可 --> <!-- 使用mode指定动画执行的顺序模式:先出后进 --> <transition mode="out-in"> <component :is="templ"></component> </transition> </div> <script> var vm = new Vue({ el: "#app", data: { templ:‘login‘ }, methods: { }, components:{ login:{ template:"<h3>登陆模块</h3>" }, register:{ template:"<h3>注册模块</h3>" } } }); </script>
首先,子组件是不能直接获取父组件里的值的,要想获取值需要在组件标签中使用指令绑定一个变量,传递给子组件中,如下:
<div id="app">
    <shop v-bind:parentmsg="msg"></shop>
</div>
子组件shop要获得父组件里的msg,需要使用属性绑定指令绑定一个变量,将父组件里的某个变量传递给这个变量,然后:
components:{ shop:{ template:‘#list‘, props:[‘parentmsg‘] } }
在子组件里,通过props指定的变量引入父组件里绑定的值,注意:props是一个数组,它里面的内容即为要引入的变量名称(通过名称引入)
<body>
        <div id="app">
            <shop v-bind:parentmsg="msg">
            </shop>
        </div>
        <template id="list">
            <div>
                <p>
                    从父组件里传来的数据---{{parentmsg.mm}}
                </p>
            </div>
        </template>
        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    msg:{mm:‘我是父组件里的信息‘}
                },
                methods: {
                    
                },
                components:{
                    // 结论:经过演示发现,子组件中,默认无法访问到父组件中的 data 上的数据 和 methods中的方法
                    shop:{
                        template:‘#list‘,
                        data:()=>{ // 注意:子组件中的data数据,并不是通过 父组件传递过来的,而是子组件自身私有的,比如:子组件通过Ajax,请求回来的数据,都可以放到data身上;
                            // data上的数据都是可写的
                            return {
                                title:‘abc‘,
                                name:‘123‘
                            }
                        },
                        methods:{
                        },
                        // 注意:组件中的所有props中的数据,都是通过父组件传递给子组件的
                        // props上的数据都是只读的
                        props:[‘parentmsg‘] // 把父组件传递过来的 parentmsg属性,先在props数组中,定义一下,这样,才能使用这个数据
                    }
                }
            });
        </script>
不管你是传递值还是传递引用,注意:在子组件中都不允许修改父组件传递过来的值,也就是说子组件只能使用,而不能修改。
注意:子组件想要获取父组件内的数据,必须通过组件传值的方式去获取。但是对于DOM操作,子组件直接可以使用document对象去操作父组件内部的元素【挂载完毕后】,例如子组件的某元素通过click方法,获取父组件内部某个元素,此时dom已经渲染完毕,针对dom操作以及跨越了组件,和组件并无关系了。
<div id="app">
            <!-- 传递子组件方法,使用v-on绑定事件的形式将父组件中的方法绑定到子组件身上 -->
            <!-- func为getMsg在子组件中的别名,getMsg为父组件的methods -->
            <shop @func="getMsg">
            </shop>
        </div>
        
        <template id="list">
            <div>
                <!-- 调用子组件的info方法 -->
                <button @click="info">点击调用父组件中的方法</button>
            </div>
        </template>
        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    
                },
                methods: {
                    getMsg(data1,data2){
                        console.log(‘我是父组件的methods‘ + data1 + data2);
                    }
                },
                components:{
                    shop:{
                        template:‘#list‘,
                        data:()=>{
                            return {
                                title:‘abc‘,
                                name:‘123‘
                            }
                        },
                        methods:{
                            info(){
                                // 子组件可以通过通过$emit触发执行绑定到自己身上的func方法
                                // 如果有参数,参数直接写在方法名后
                                this.$emit(‘getMsg‘,123,222);
                            }
                        }
                    }
                }
            });
        </script>
子组件给父组件传递值,只能是被动方式传递,即某个事件触发,才能传递。子组件向父组件传递值采用了父组件给子组件传递方法的方式。
<div id="app">
            <!-- 传递子组件方法,使用v-on绑定事件的形式将父组件中的方法绑定到子组件身上 -->
            <shop @func="getMsg">
            </shop>
        </div>
        <template id="list">
            <div>
                <button @click="info">点击调用父组件中的方法</button>
            </div>
        </template>
        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    childdata:null
                },
                methods: {
                    getMsg(data){
                        this.childdata = data;
                    }
                },
                components:{
                    shop:{
                        template:‘#list‘,
                        data:()=>{
                            return {
                                title:‘abc‘,
                                name:‘123‘
                            }
                        },
                        methods:{
                            info(){
                                // 当子组件中的方法被调用时,会执行父组件中的方法,此时,将要传递给父组件的值通过函数的参数传递过去,在父组件中接收。
                                // 子组件向父组件传值只能被动的传递(有事件触发)
                                this.$emit(‘func‘,this.title);
                            }
                        }
                    }
                }
            });
        </script>
<div id="app">
        <!-- <p ref="ppp">我能通过ref引用到p元素</p> -->
        <!-- 如果ref指定的名称被多个元素占用,则只使用最后一个 -->
        <p ref="ppp">我能通过ref引用到p元素</p>
        <!-- 使用ref还可以引用组件 -->
        <login ref="logref"></login>
    </div>
    <template id="mytempl">
        <div></div>
    </template>
    <script>
        var vm = new Vue({
            el: ‘#app‘,
            data: {
            },
            methods: {
            },
            components:{
                login:{
                    template:"#mytempl",
                    data:()=>{
                        return {
                            title:‘哈哈哈‘
                        }
                    }
                }
            }
        });
        console.log(vm.$refs.ppp);
        console.log(vm.$refs.logref);
        console.log(vm.$refs.logref.title);
    </script>
我们的组件除了使用特殊占位符替换以外,还可以使用render渲染我们的组件,不同的是这两者就类似于v-text和插值表达式,render渲染的组件会直接覆盖容器里的所有内容,而使用占位符的形式组件只会替换占位符位置的内容。
<script src="../lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
</div>
<script>
    var login = {
        template:"<h1>登陆模块</h1>"
    }
    var vm = new Vue({
      el: ‘#app‘,
      render:function(createElements) { 
          // createElements是一个方法,调用它,能够把指定的组件模板,渲染为 html 结构
            return createElements(login)
            // 注意:这里 return的结果,会替换页面中的el指定的那个容器
      }
    })
  </script>
原文:https://www.cnblogs.com/liudaihuablogs/p/13468948.html