1 ! DOCTYPE html 2 html 3 head 4 meta charset ="utf-8" 5 title vue 3 / title 6 style 7 .message-container { 8 margin : 5px 0 ; 9 border : 1px dashed lightcoral ; 10 text-align : left ; 11 } 12 13 .message-container div { 14 padding-left : 1
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>vue 3</title> 6 <style> 7 .message-container { 8 margin: 5px 0; 9 border: 1px dashed lightcoral; 10 text-align: left; 11 } 12 13 .message-container div { 14 padding-left: 10px; 15 } 16 </style> 17 </head> 18 <body> 19 <div id="app"> 20 <message name="gua"></message> 21 <message name="xiao gua"></message> 22 <!-- <button v-on:click="handleToggleTimer">开关 timer</button> --> 23 <!-- v-on:click 可以缩写成 @click, 在 vue 里面这样的缩写很常见, 多写写就会记下来 --> 24 <button @click="handleToggleTimer">开关 timer</button> 25 <!-- v-if 表示如果 showTimer 的值为 true, 那么就会渲染 timer 组件 --> 26 <!-- 组件会在后面描述 --> 27 <div v-if="showTimer"> 28 <timer></timer> 29 </div> 30 <markdown-editor></markdown-editor> 31 </div> 32 33 <!-- 引入 vue --> 34 <!-- 注意, 工作中并不是这样引入 vue 的, 我们先用最简单的方式引入, 之后会有复杂例子 --> 35 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> 36 <script src="https://unpkg.com/[email protected]"></script> 37 <script> 38 const log = console.log.bind(console) 39 40 // 使用 Vue.component 可以定义一个组件, 第一个参数是组件的名称 41 // 定义组件之后可以直接在 html 里面使用 42 Vue.component(‘message‘, { 43 // props 用来指定组件可以接收哪些属性 44 // 在 html 中使用组件的时候可以直接通过 name="xxx" 传递值 45 // 传递的值可以在组件内部使用 46 // props 类似 react 组件的 props 47 props: [‘name‘], 48 // template 的值是一个 html 格式的字符串 49 // 这个字符串会替换掉组件, 也就是 <message></message> 组件的内容会换成 template 的值 50 // 注意 template 里面的变量可以从 props 中获取 51 template: ` 52 <div class="message-container"> 53 <div>Hello {{ name }}</div> 54 <div>大写 {{ name.toUpperCase() }}</div> 55 </div> 56 `, 57 }) 58 59 Vue.component(‘timer‘, { 60 // 组件中依然可以使用 data 这个属性, 但是 data 的值不能是一个对象 61 // 必须是一个函数, 然后在函数内部返回一个对象, 用来表示组件内部的数据 62 // 依然类似 react 组件的 state 63 data: function() { 64 return { 65 secondsElapsed: 0, 66 } 67 }, 68 template: ` 69 <div> 70 启动时间: {{ secondsElapsed }} 71 </div> 72 `, 73 methods: { 74 tick: function() { 75 // 每次调用 tick 方法都会让 secondsElapsed 增加 1 76 this.secondsElapsed += 1 77 } 78 }, 79 // created 是实例创建完成后会被调用的方法 80 // 类似 react 中的 componentDidMount 81 created: function() { 82 console.log(‘定时器组件 did mount‘) 83 this.interval = setInterval(() => this.tick(), 1000) 84 }, 85 // destroyed 表示实例销毁后会被调用的方法 86 // 类似 react 中的 componentWillUnmount 87 destroyed: function() { 88 console.log(‘定时器组件 will unmount‘) 89 clearInterval(this.interval) 90 }, 91 }) 92 93 Vue.component(‘markdown-editor‘, { 94 data: function() { 95 return { 96 mdString: ‘输入 *markdown 语法* 就能看到效果‘, 97 } 98 }, 99 // template 中使用了 v-html 这个指令, 是用来设置元素的 innerHTML 属性的 100 // 每次都会将 getRawMarkup 函数的返回值设置为 innerHTML 的值 101 template: ` 102 <div className="MarkdownEditor"> 103 <h1>markdown 编辑器</h1> 104 <h3>原始 md 文本</h3> 105 <textarea v-model="mdString"></textarea> 106 <h3>结果预览</h3> 107 <div class="content" v-html="getRawMarkup()"></div> 108 </div> 109 `, 110 methods: { 111 getRawMarkup: function() { 112 // 因为 textarea 使用了 v-model 指令 113 // 所以当 mdString 发生变化的时候, getRawMarkup 方法中可以获取用户输入的 mdString 值 114 // marked 方法用来把一个 markdown 字符串转成 html 格式的字符串入 115 return marked(this.mdString) 116 }, 117 }, 118 }) 119 120 let app = new Vue({ 121 el: ‘#app‘, 122 data: { 123 showTimer: true, 124 }, 125 methods: { 126 // 切换 showTimer 属性的值 127 handleToggleTimer: function() { 128 this.showTimer = !this.showTimer 129 } 130 } 131 }) 132 </script> 133 </body> 134 </html>